java IO流的使用

一、IO流原理

二、IO流的分类

  1. 根据操作数据单位划分:字节流、字符流

  1. 根据数据的流向划分: 输入流、输出流

  1. 根据流的角色划分:节点流、处理流

三、IO流的体系结构

1.字符流的读写操作

1.1 读取文件

//读取文件操作
FileReader fr = null;
try {
    // 实例化File类的对象,指明要操作的文件
    File file = new File("1.txt");
    // 提供具体的流
    fr = new FileReader(file);
    // read():返回读入的一个字符,如果达到文件末尾,返回-1
    int read;
    do {
        read = fr.read();
        System.out.println((char) read);
    } while (read != -1);

} catch (IOException e) {
    throw new RuntimeException(e);
} finally {
    // 流的关闭
    if (fr != null) {
        try {
            fr.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
说明:
1.read()的理解: 返回读入的一个字符。如果达到文件末尾,返回-1
2.异常的处理:为了保证流资源一定可以执行关闭操作。需要使用try-catch-finally处理
3.读入的文件一定要存在,否则就会报FiLeNotFoundException。
char[] cbuf = new char[5];
//read(char[] cbuf): 返回每次读入cbuf数组中的字符个数。如果达到文件末尾,返回-1
int len;
while ((len = fr.read(cbuf)) != -1) {
    // 错误的写法:最后一次的长度不足字符数组的长度时,会有遗留数据
    /* for (int i = 0; i < cbuf.length; i++) {
        System.out.println(cbuf[i]);
    }*/
    for (int i = 0; i < len; i++) {
        System.out.println(cbuf[i]);
    }
    
    // 错误的写法二:和上面原理一样
    // String str = new String(cbuf);
    
    String str = new String(cbuf, 0, len);
    System.out.println(str);
}

1.2 写入文件

FileWriter fw = null;
try {
    // 1.提供File类的对象,指明写出到的文件
    File file = new File("hello.txt");

    // 2.提供FLeWriter的对象,用于数据的写出
    fw = new FileWriter(file, true);

    // 3.写出的操作
    fw.write("I have a dream!\n");
    fw.write("you need to have a dream!");

} catch (IOException e) {
    throw new RuntimeException();
} finally {
    // 4.流资源的关闭
    try {
        fw.close();
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

2. 字节流的读写操作

File srcFile = new File( pathname::"爱情与友情.jpg");
File destFile = new File( pathname:"爱情与友情2.jpg");

fis = new FileInputStream(srcFile);
fos = new FileOutputStream(destFile);
//复制的过程
byte[] buffer = new byte[5];
int len;
while((len = fis.read(buffer)) != -1){
    fos .write(buffer, 0, len);
}
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (fis != null) {
        fis.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    if (fos != null) {
        fos.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
结论:
1.对于文本文件(.txt,.java,.c,.cpp),使用字符流处理
2.对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt,...)使用字节流处理
3.文本文件的复制,不在控制台展示可以用字节流操作

3. 缓冲流的读写操作(处理流)

1.作用:提升流的读取、写入的速度

2.原因:内部提供了一个缓冲区,默认8192字节大小

3.处理流:包裹节点流的一种流

使用BufferedReader和BufferedWriter实现文本的复制

public void testBufferedReaderBufferedWriter(){
    BufferedReader br = null;
    BufferedWriter bw = null;
    try {
        //创建文件和相应的流
        br = new BufferedReader(new FileReader(new File( pathname: "dbcp.txt")));
        bw = new BufferedWriter(new FileWriter(new File( pathname: "dbcp1.txt")));
        //读写操作        
/*        //方式一:
        char[] cbuf = new char[1024];
        int len;
        while((len = br.read(cbuf)) != -1){
              bw.write(cbuf, off: 0,len);
              //bw.flush();  刷新缓存,write操作会自动刷新
        } */   
        //方式二:使用String
        String data;
        while((data = br.readLine()) != null) {
             bw.writeLine(data); //data不包含换行符
             bw.newLine(); // 提供换行的操作   
        }
    } catch (IOException e) {
        e.printStackTrace();
    }finally {
        //关闭资源
        if(bw != null){
            try {
                  bw.close();          
            } catch(IOException e) {
                  e.printStackTrace();           
            }                
        }
        if(br != null){
            try {
                  br.close();          
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

说明: 关闭外层流的同时,内层流也会自动的进行关闭。关于内层流的关闭,我们可以省略。

4. 转换流(处理流)

1.转换流:属于字符流

InputstreamReader: 一个字节的输入流转换为字符的输入流

OutputstreamWriter: 一个字符的输出流转换为字节的输出流

2.作用

提供字节流到字符流之间的转换

3.编码与解码

解码:字节、字节数组 --->字符数组、字符串

编码:字符数组、字符串 ---> 字节、字节数组

4.字符集

转换流实现utf-8格式文件转gbk格式

//1.造文件、造流
File file1 = new File( pathname: "dbcp.txt");
File file2 = new File( pathname: "dbcp_gbk.txt");

FileInputStream fis = new FileInputStream(file1);
FileOutputStream fos = new FileOutputStream(file2);

InputStreamReader isr = new InputStreamReader(fis, charsetName: "utf-8");
OutputStreamWriter osw = new Outputstreamwriter(fos , charsetName: "gbk");

//2.读写过程
char[] cbuf = new char[20];
int len;
while((len = isr.read(cbuf)) != -1){
   osw.write(cbuf, off: 0,len); 
}
//3.关闭资源
isr.close();
osw.close();

5. 标准输入、输出流(处理流)

6. 打印流(处理流)

重新指定打印位置:打印字符到文件

7. 数据流(处理流)

8. 对象流

1.对象的序列化

Person需要满足如下的要求,方可序列化
1.需要实现接口: Serializable
2.当前类提供一个全局常量: serialVersionUID
3.除了当前Person类需要实现Serializable接口之外,还必须保证其内部所有属性也必须是可序列化的。

public class Person implements Serializable {
    public static final long serialVersionUID = 475463534532L;
    private String name;
    private int age;
    private int id; 
}

对象的序列化操作

public void testObjectOutputStream() {
    ObjectOutputStream oos = null;
    try {
    //1.
    oos = new ObjectOutputStream(new FileOutputStream( name: "object.dat"))
    //2.
    oos.writeObject(new string( original:"我爱北京天安门"));
    oos.flush();//刷新操作
    
    oos.writeObject(new Persion(name: "张三",age: "23")));
    oos.flush();//刷新操作
    
    } catch (IOException e) {
        e.printStackTrace();      
    }finally {
        if(oos != null){
            // 3.
              try {
                  foos.close();                  
              }  catch(IOException e) {
                   e.printStackTrace();                 
              }    
        }        
    }
}

2.对象的反序列化:

将磁盘文件中的对象还原为内存中的一个java对象使用objectInputStream来实现

public void testobjecinputStream(){
    ObjectInputStream ois = null;
    try {
        ois = new ObjectInputStream(new FileInputStream( name: "object.dat"));
        
        Object obj = ois.readobject();
        String str = (String) obj;
        
        Person p = (Person) ois.readobject();
        
        System.out.println(str);
        System.out.println(p);    
    }

) catch (IOException e) {
    e.printStackTrace();
}catch (ClassNotFoundException e) {
    e.printStackTrace();
}
注意:
ObjectOutputStream和ObjectlnputStream不能序列化static和transient修饰的成员变量

9. 随机存取文件流

RandomAccessFile的使用
1.RandomAccessFile直接继承于java.lang.Object类,实现了DataInputDataoutput接口
2.RandomAccessFile既可以作为一个输入流,又可以作为一个输出流
3.如果RandomAccessFile作为输出流时,写出到的文件如果不存在,则在执行过程中自动创建。如果写出到的文件存在,则会对原有文件内容进行覆盖。(默认情况下,从头覆盖)

四、NIO使用

猜你喜欢

转载自blog.csdn.net/weixin_44863237/article/details/129702062