【Java】文件I/O-文件内容操作-输入输出流-Reader/Writer/InputStream/OutputStream四种流

导读

在文件I/O这一节的知识里,对文件的操作主要分为两大类:

☑️针对文件系统进行的操作

☑️针对文件内容进行的操作

上文已经讲了针对文件系统即File类的操作,这篇文章里博主就来带了解针对文件内容的操作,即输入输出流(Reader,Writer,InputStream,OutputStream)四种流相关知识

前置知识

1、流的分类

文件I/O中的流分为字节流和字符流

字符流:以字符为单位,每次读写的最小单位是字符;对应文本文件。包括Reader,Writer两个类

字节流:以字节为单位,每次读写的最小单位是字节;对应二进制文件。包括InputStream,OutputStream两个类

流的关系分类如下图 

【Java】文件I/O-文件内容操作-输入输出流-Reader/Writer/InputStream/OutputStream四种流_第1张图片

注意,字符和字节的关系如下

一个字符可能是对应多个字节
GBK,一个中文字符 ->两个字节
UTF8,一个中文字符 ->三个字节 

2、输入输出的定义 

 计算机中的输入输出发生在CPU和硬盘之间,而我们所说的输入输出是以CPU为视角,即

 · 把数据从CPU保存到硬盘上,是输出/写(Input/Read)
 · 把内容从硬盘取到CPU里,是输入/读(Output/Write)

下图可以形象地表示输入输出的定义 

【Java】文件I/O-文件内容操作-输入输出流-Reader/Writer/InputStream/OutputStream四种流_第2张图片

四种流的使用 

1、Reader

(1)Reader类

先创建一个Reader

Reader reader = new FileReader("/Users/liuwenwen/Desktop/test.txt");

(2)Reader类中的方法

Reader最常用的就是read方法,read方法分为下面几种

【Java】文件I/O-文件内容操作-输入输出流-Reader/Writer/InputStream/OutputStream四种流_第3张图片

方法名 说明
read(char[] cbuf) 传入数组参数,读取数组长度的字符存放在数组中
read () 读一个字符
read(CharBuffer target) 传入CharBuffer对象
read(char[] cbuf,int off, int length) 传入数组参数,从字符串off位置开始读,读取length长度的字符存放在数组中

(3)代码实例

其中最常用的是read(char[] cbuf)方法,返回参数是读取字符的个数

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

public class demo {
    public static void main(String[] args){
        char[] buf = new char[12];
        try(Reader reader = new FileReader("/Users/liuwenwen/Desktop/test.txt")) {
            while (true){
                int n = reader.read(buf);
                if(n == -1){
                    break;
                }
                System.out.println("n="+n);
                for (int i = 0; i < n; i++) {
                    System.out.print(buf[i]);
                }
                System.out.println();
            }
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
}

注意:代码中将Reader reader = new FileReader("/Users/liuwenwen/Desktop/test.txt放在try()代码块中是隐藏了reader.close()操作,相当于

try {
      Reader reader = new FileReader("/Users/liuwenwen/Desktop/test.txt")
      while (true){
                int n = reader.read(buf);
                if(n == -1){
                    break;
                }
                System.out.println("n="+n);
                for (int i = 0; i < n; i++) {
                    System.out.print(buf[i]);
                }
                System.out.println();
        }
} catch (FileNotFoundException e) {
            throw new RuntimeException(e);
} catch (IOException e) {
            throw new RuntimeException(e);
}finally{
       reader.close();
}

读取结果 

 【Java】文件I/O-文件内容操作-输入输出流-Reader/Writer/InputStream/OutputStream四种流_第4张图片

2、Writer类

 (1)Writer中的方法

Writer方法如下

【Java】文件I/O-文件内容操作-输入输出流-Reader/Writer/InputStream/OutputStream四种流_第5张图片

方法名 说明
write(String str) 一次写一个字符串
write(char[] cbuf) 一次写多个字符(字符数组)
write(int c) 一次写一个字符
write(String str, int off, int len) 带有 offset 和lenoffset指的是从字符串中的第几个字符开始写
write(char[] cbuf, int off, int len) 带有 offset 和lenoffset 指的是从数组中的第几个字符开始写

(2)代码实例

我们最常用的是第一个即write(String str)方法

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

public class demo3 {
    public static void main(String[] args) {
        try(Writer writer = new FileWriter("/Users/liuwenwen/Desktop/test.txt")) {
            writer.write("驻跸怀千古,开襟望九州。太平词藻盛,长愿纪鸿休。");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

 运行程序后,文本内容被修改了

【Java】文件I/O-文件内容操作-输入输出流-Reader/Writer/InputStream/OutputStream四种流_第6张图片

可见我们原来的内容同时也被覆盖。如果不想覆盖原本的内容,怎么办呢?

在创建Writer类时,加一个参数true,表示追加

try(Writer writer = new FileWriter("/Users/liuwenwen/Desktop/test.txt",true)) 

为了防止由于程序运行太快,内容在缓冲区中没有来得及写到硬盘里,我们加一个flush()方法

writer.flush();

 现在整体代码就变成

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

public class demo3 {
    public static void main(String[] args) {
        try(Writer writer = new FileWriter("/Users/liuwenwen/Desktop/test.txt",true)) {
            writer.write("驻跸怀千古,开襟望九州。太平词藻盛,长愿纪鸿休。");
            writer.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

用原来的文本再次运行程序 

​​​​​​​

可以看到,这次是追加,不再是覆盖 

3、InputStream类

 (1)方法

InputStream类和Reader类里的方法类似,不过将char[]数组变为了byte[]数组,返回值是读取字节的个数

【Java】文件I/O-文件内容操作-输入输出流-Reader/Writer/InputStream/OutputStream四种流_第7张图片

 (2)代码实例

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

public class demo5 {
    public static void main(String[] args) {
        try (InputStream inputStream = new FileInputStream("/Users/liuwenwen/Desktop/test.txt")){
            byte[] buf = new byte[1024];
            int n = inputStream.read(buf);
            for (int i = 0; i < n; i++) {
                System.out.printf("%x ",buf[i]);
                //采用十六进制打印,更加直观
            }
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

读取结果

【Java】文件I/O-文件内容操作-输入输出流-Reader/Writer/InputStream/OutputStream四种流_第8张图片

4、OutputStream类

(1)方法 

OutputStream类和Writer类里的方法类似,不过将char[]数组变为了byte[]数组

【Java】文件I/O-文件内容操作-输入输出流-Reader/Writer/InputStream/OutputStream四种流_第9张图片

 (2)代码实例

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class demo6 {
    public static void main(String[] args) {
        try(OutputStream outputStream = new FileOutputStream("/Users/liuwenwen/Desktop/test.txt",true)){
            String s = "驻跸怀千古,开襟望九州。太平词藻盛,长愿纪鸿休。";
            outputStream.write(s.getBytes());
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

由于OutputStream类write方法要传入的是byte[]参数,我们直接调用字符串的getBytes()方法,方便书写

最终追加结果

你可能感兴趣的:(Java,#,文件I/O,java,开发语言)