参考网址 参考1 参考2 参考3

一、纪要

1、基本常识

IO,即in和out,也就是输入和输出

1.1、数据大小表

  1. 8bit(位)=1Byte(字节)
  2. 1024Byte(字节)=1KB
  3. 1024KB=1MB
  4. 1024MB=1GB
  5. 1024GB=1TB

1.2、字符和字节区别

字节是存储容量的基本单位,1字节=8个二进制位。
字符是指字母、数字、汉字和各种符号。

1.3、字节流的由来

  1. 字节流读取文字字节数据后,不直接操作而是先查指定的编码表。获取对应的文字。 在对这个文字进行操作。简单说:字节流+编码表。<br />字节流处理中文,如果一次读写一个字符对应的字节数就不会有问题,一旦将一个字符对应的字节分裂开来,就会出现乱码了。

1.4、字节流和字符流区别

字节流本身没有缓冲区,效率提升非常高。即使不关闭资源(close方法),文件也能输出。
字符流本身就带有缓冲区,但是如果字符流不使用close方法的话,则不会输出任何内容,说明字符流用的是缓冲区,并且可以使用flush方法强制进行、新缓冲区,这时才能在不close的情况下输出内容

二、IO流分类

image.png

按数据流方向:输出流 、输入流
按处理数据单位:字节流、字符流
按功能: 节点流、处理流

image.png
缓冲流
image.png
我们搬砖的时候,一块一块地往车上装肯定是很低效的。我们可以使用一个小推车,先把砖装到小推车上,再把这小推车推到车前,把砖装到车上。这个例子中,小推车可以视为缓冲区,小推车的存在,减少了我们装车次数,从而提高了效率。

1、字节流方法

字节流:InputStream,OutputStream 都是抽象类。所以不能直接new

1.1、FileOutputStream 字节流

  1. FileOutputStream(File file, boolean append);
  2. 构造方法:
  3. 本地没有文件,会创建一个空文件
  4. append 参数为true时,数据从文件尾部写入;为false时,数据覆盖文件

字节流输出数据实例:写入文件

  1. //字节流输出数据
  2. public static void main(String[] args) throws Exception{
  3. //获取文件地址
  4. File file = new File("d:/test.txt");
  5. //本地无此文件 自动创建 true 数据从文本尾部添加
  6. OutputStream outputStream = new FileOutputStream(file,true);
  7. //字符转字节
  8. String str = "hello world";
  9. byte[] b = str.getBytes();
  10. //输出数据至文件
  11. outputStream.write(b);
  12. //关闭字节流
  13. outputStream.close();
  14. }

换行符(\r\n): String str = “\r\nhello world”;

1.2、FileInputStream 字节流

字节流输入数据 :读取文件

  1. //字节流 读取数据
  2. public static void main(String[] args) throws Exception{
  3. //获取文件地址
  4. File file = new File("d:" + File.separator + "test.txt");
  5. //实例化输入流
  6. InputStream inputStream = new FileInputStream(file);
  7. //创建字节数组存储
  8. byte[] b = new byte[1024];
  9. int len = inputStream.read(b);
  10. //关闭流
  11. inputStream.close();
  12. System.out.println(new String(b,0,len));
  13. }

以上方法有问题,开辟这么大字节数组,明显是浪费嘛,可以根据文件大小来定义字节数组大小
File的public long length()方法

  1. //字节流 读取数据
  2. public static void main(String[] args) throws Exception{
  3. //获取文件地址
  4. File file = new File("d:" + File.separator + "test.txt");
  5. //实例化输入流
  6. InputStream inputStream = new FileInputStream(file);
  7. //创建字节数组存储
  8. byte[] b = new byte[(int)file.length()];
  9. inputStream.read(b);
  10. //关闭流
  11. inputStream.close();
  12. System.out.println(new String(b));
  13. }

以上情况只适合输入文件的大小,不知道的情况下

  1. //字节流 读取数据
  2. public static void main(String[] args) throws Exception{
  3. //获取文件地址
  4. File file = new File("d:" + File.separator + "test.txt");
  5. //实例化输入流
  6. InputStream inputStream = new FileInputStream(file);
  7. //创建字节数组存储
  8. byte[] b = new byte[1024];
  9. int temp = 0;
  10. int len = 0;
  11. //-1为文件读完的标志
  12. while ((temp = inputStream.read())!=-1){
  13. b[len] = (byte) temp;
  14. len++;
  15. }
  16. //关闭流
  17. inputStream.close();
  18. System.out.println(new String(b,0,len));
  19. }

1.3、BufferedInputStream 缓存字节流

缓冲字节流是为高效率而设计的,真正的读写操作还是靠FileInputStream,所以其构造方法入参是这两个类的对象也就不奇怪了。

  1. //缓冲字节输出流
  2. public static void main(String[] args) throws Exception {
  3. //获取文件地址
  4. File file = new File("d:/test.txt");
  5. BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
  6. //写入文件
  7. String str = "百度一下,您就知道";
  8. bos.write(str.getBytes());
  9. //关闭流
  10. bos.close();
  11. }

1.4、BufferedOutputStream 缓存字节流

缓冲字节流是为高效率而设计的,真正的读写操作还是靠FileOutputStream,所以其构造方法入参是这两个类的对象也就不奇怪了。

  1. //缓冲字节输入流
  2. public static void main(String[] args) throws Exception {
  3. //获取文件地址
  4. File file = new File("d:" + File.separator + "test.txt");
  5. BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
  6. //一次性获取多少字节
  7. byte[] b = new byte[1024];
  8. //文件数据的长度
  9. int len = bis.read(b);
  10. //关闭流
  11. bis.close();
  12. System.out.println(new String(b,0,len));
  13. }

2、字节流方法

字符流:Reader,writer 都是抽象类。所以不能直接new

2.1、FileWriter

字符流输出流:写文件

  1. //字符流输出数据
  2. public static void main(String[] args) throws Exception {
  3. //获取文件地址
  4. File file = new File("d:" + File.separator + "test.txt");
  5. Writer writer = new FileWriter(file);
  6. String str = "机会是留给有准备的人";
  7. //写入数据至文件
  8. writer.write(str);
  9. //不关闭字符流,数据还在缓存区 输出不出来
  10. writer.close();
  11. }

2.2、FileReader

字符流输入流:读文件

  1. //字符流读取数据
  2. public static void main(String[] args) throws Exception {
  3. //获取文件地址
  4. File file = new File("d:/test.txt");
  5. Reader reader = new FileReader(file);
  6. //字符数组方式读出数据
  7. char[] c = new char[1024];
  8. //获取数据最后的长度
  9. int len = reader.read(c);
  10. //关闭流
  11. reader.close();
  12. System.out.println(new String(c,0,len));
  13. }

2.3、OutputStreamWriter 字符流

字符流适用于文本文件的读写,OutputStreamWriter类其实也是借助FileOutputStream类实现的,故其构造方法是FileOutputStream的对象

  1. public static void main(String[] args) throws Exception{
  2. //获取文件地址
  3. File file = new File("d:/test.txt");
  4. // 需要FileOutputStream 实现
  5. OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(file));
  6. String str = "hahahahaha";
  7. osw.write(str);
  8. //关闭流
  9. osw.close();
  10. }

2.4、InputStreamReader 字符流

  1. public static void main(String[] args) throws Exception {
  2. //获取文件地址
  3. File file = new File("D:/test.txt");
  4. //依赖FileInputStream 实现输入数据
  5. InputStreamReader isr = new InputStreamReader(new FileInputStream(file));
  6. //字符数组
  7. char[] c = new char[1024];
  8. int len = isr.read(c);
  9. System.out.println(new String(c,0,len));
  10. }

2.5、BufferedReader 字符缓冲流


  1. public static void main(String[] args) throws Exception{
  2. //获取文件地址
  3. File file = new File("d:/test.txt");
  4. BufferedWriter bw = new BufferedWriter(new FileWriter(file));
  5. String str = "神话";
  6. bw.write(str);
  7. //关闭流
  8. bw.close();
  9. }

2.6、BufferedWriter 字符缓冲流


  1. public static void main(String[] args) throws Exception {
  2. //获取文件地址
  3. File file = new File("D:/test.txt");
  4. BufferedReader br = new BufferedReader(new FileReader(file));
  5. //字符数组
  6. char[] c = new char[1024];
  7. int len = br.read(c);
  8. System.out.println(new String(c,0,len));
  9. }


3、IO流方法

3.1、字节流方法

字节输入流InputStream主要方法:

  • read() : 从此输入流中读取一个数据字节。
  • read(byte[] b) : 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。
  • read(byte[] b, int off, int len) : 从此输入流中将最多 len 个字节的数据读入一个 byte 数组中。
  • close(): 关闭此输入流并释放与该流关联的所有系统资源。

字节输出流OutputStream主要方法:

  • write(byte[] b) : 将 b.length 个字节从指定 byte 数组写入此文件输出流中。
  • write(byte[] b, int off, int len) : 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。
  • write(int b) : 将指定字节写入此文件输出流。
  • close() : 关闭此输入流并释放与该流关联的所有系统资源。

3.2、字符流方法

字符输入流Reader主要方法:

  • read():读取单个字符。
  • read(char[] cbuf) :将字符读入数组。
  • read(char[] cbuf, int off, int len) : 将字符读入数组的某一部分。
  • read(CharBuffer target) :试图将字符读入指定的字符缓冲区。
  • flush() :刷新该流的缓冲。
  • close() :关闭此流,但要先刷新它。

字符输出流Writer主要方法:

  • write(char[] cbuf) :写入字符数组。
  • write(char[] cbuf, int off, int len) :写入字符数组的某一部分。
  • write(int c) :写入单个字符。
  • write(String str) :写入字符串。
  • write(String str, int off, int len) :写入字符串的某一部分。
  • flush() :刷新该流的缓冲。
  • close() :关闭此流,但要先刷新它。

另外,字符缓冲流还有两个独特的方法:

  • BufferedWriter类newLine() :写入一个行分隔符。这个方法会自动适配所在系统的行分隔符。
  • BufferedReader类readLine() :读取一个文本行。