十四IO

Posted 啄木鸟伍迪

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了十四IO相关的知识,希望对你有一定的参考价值。

一、概述:

1.流的分类:

  按照流向的不同分为:输入流 输出流
  按照处理数据单位的不通分为:字节流 字符流(处理的文本文件)
  按照角色的不通分为 节点流(直接作用于文件的)处理流

关于处理流的说明:(处理流作用在节点流上)

 2.IO的体系:

  抽象基类 节点流(文件流) 缓冲流
InputStream(字节流) FileInputStream BufferedInputStream
OutputStream(字节流) FileOutputStream BufferedOutputStream
  Reader(字符流) FileReader BufferedReader
  Writer(字符流) FileWriter BufferedWriter

 

 

 

 

 

 

 3.如何使用

  •   对于文本文件(.txt,.java,.c,.cpp)使用字符流处理
  •   对于非文本文件,使用字节流处理

二、节点流

1、FileReaderd

1.1步骤:

  • 创建File类对象,指明要操作的文件;
  • 提供具体的流
  • 数据的处理
  • 关闭应用的流

demo1:从硬盘存在的一个文件中,读取其内容到程序中,使用FileInputStream,显示在控制台上

 1 @Test
 2 
 3     public void testStream1() {
 4 
 5         // 2.提供具体的流
 6         FileReader fileReader = null;
 7         try {
 8 
 9             // 1.创建一个File类的对象,指明要操作的文件
10 
11             File file1 = new File("hello.txt");// 文件位置为当前工程下面,不是当前类下
12             fileReader = new FileReader(file1);
13             // 3.数据的读入
14             // read() 返回读入的一个字符,文件达到末尾,则返回-1
15             int data = fileReader.read();
16             while (data != -1) {
17                 System.out.print((char) data);
18                 data = fileReader.read();
19             }
20         } catch (FileNotFoundException e) {
21             // TODO Auto-generated catch block
22             e.printStackTrace();
23         } catch (IOException e) {
24             // TODO Auto-generated catch block
25             e.printStackTrace();
26         } finally {
27             // 4.关闭相应的流
28             if (fileReader != null) {
29                 try {
30                     fileReader.close();
31                 } catch (IOException e) {
32                     e.printStackTrace();
33                 }
34             }
35 
36         }
37 
38     }

注意:要读取的文件一定要存在,否则空指针异常

说明:

  • read()的理解:返回读入的一直字符,如果到底文件末尾则返回-1;
  • 关于异常的处理,为了保证保证流资源的关闭,这里使用了try catch finally 来处理,这里看到了顺序没有从上到下来,是因为最后做了异常处理导致的;

1.2.关于read方法的详细说明

1.2.1read()方法错误版(只为说明用)

 1 /
 2       reader 方法升级版(错误版)
 3  4       @Description
 5 @author lixiuming
 6       @date 2021年5月5日上午11:22:37
 7 @throws IOException
 8  9      /
10     @Test
11     public void testReaderUpgrade2() throws IOException {
12         // 1.File 类的实例化
13         File file1 = new File("hello.txt");// 文件位置为当前工程下面,不是当前类下
14         // 2.流的实例化
15         FileReader fileReader = new FileReader(file1);
16         // 3.流的写出
17         char[] charArr = new char[5];// 一次读入多个数据来提高效率
18         int len = fileReader.read(charArr);// 一次读入多个数据,返回每次读入的charArr数组中字符的个数,如果达到文件末尾,返回-1
19         while (len != -1) {
20             for (int i = 0; i < charArr.length; i++) {
21                 System.out.print((char) charArr[i]);
22             }
23             len = fileReader.read(charArr);
24         }
25         // 4.流的操作
26         fileReader.close();
27 
28     }

这里的charArr.length;有问题,在文件中,如果hello.txt中的内容是:hello word!! hello lixiuming!!123,那么此时的输出结果就是 hello word!! hello lixiuming!!123!!,多了两个“!!”;

若最后取的数组长度不足5,那么前一个的数组是:

i n g

 

 

最后一组数组则是:

1 3 2

 

 

没有覆盖掉原来的数据;

1.2.2read()的升级版本正确写法:

 1 /
 2       reader 方法的升级版(正确版)
 3  4       @Description
 5 @author lixiuming
 6 @throws IOException
 7       @date 2021年5月5日上午10:55:53
 8  9      /
10     @Test
11     public void testReaderUpgrade() throws IOException {
12         // 1.File 类的实例化
13         File file1 = new File("hello.txt");// 文件位置为当前工程下面,不是当前类下
14         // 2.流的实例化
15         FileReader fileReader = new FileReader(file1);
16         // 3.流的写出
17         char[] charArr = new char[5];// 一次读入多个数据来提高效率
18         int len = fileReader.read(charArr);// 一次读入多个数据,返回每次读入的charArr数组中字符的个数,如果达到文件末尾,返回-1
19         while (len != -1) {
20             for (int i = 0; i < len; i++) {
21                 System.out.print((char) charArr[i]);
22 
23             }
24             len = fileReader.read(charArr);
25         }
26         // 4.流的操作
27         fileReader.close();
28 
29     }

2.FileWrite

步骤:

  • 创建File类对象,指明要操作的文件;
  • 提供具体的流
  • 数据的处理
  • 关闭应用的流

demo:从内存中写出数据到硬盘的文件里的简单说明

View Code

说明:

输出操作,对应File可以不存在,并不会报异常;

如不存在,在输出过程中自动穿件文件

如果存在, a.如果流构造器使用的是FileWriter(file,false)/FileWriter(file),对象会对原有的文件进行覆盖;

      b.如果流构造器使用的是FileWriter(file,true) 不会对原有的文件覆盖,而是在原有的文件内追加;

 

3.文件的复制(FileReader和FileWriter同时使用)

3.1JUNIT测试版:

 1 /
 2       文件的复制
 3  4       @Description
 5 @author lixiuming
 6 @throws IOException
 7       @date 2021年5月5日上午10:19:44
 8  9      /
10     @Test
11     public void testFileCopy() {
12         // 2.创建输入和出入流的对象
13         FileReader fr = null;
14         FileWriter fw = null;
15         try {
16             // 1.创建File 类的对象,指明读入和写出的文件
17             File copy = new File("hello.txt");
18             File copyTo = new File("hello2.txt");
19             fr = new FileReader(copy);
20             fw = new FileWriter(copyTo);
21             // 3.数据的读入和写出
22             char[] charArr = new char[5];
23             int len = fr.read(charArr);
24             while (len != -1) {
25                 for (int i = 0; i < len; i++) {
26                     char data = (char) charArr[i];
27                     fw.write(data);
28                 }
29                 len = fr.read(charArr);
30             }
31         } catch (Exception e) {
32         } finally {
33             // 4.关闭流资源
34             try {
35                 if (fw != null) {
36                     fw.close();
37                 }
38 
39             } catch (IOException e) {
40                 e.printStackTrace();
41             } finally {
42                 if (fr != null) {
43                     try {
44                         fr.close();
45                     } catch (IOException e) {
46                         e.printStackTrace();
47                     }
48                 }
49             }
50 
51         }
52 
53     }

4、FileInputStream/FileOutputStream

*4.1步骤:

  • 创建File类对象,指明要操作的文件;
  • 提供具体的流
  • 数据的处理
  • 关闭应用的流

说明:用字节流 读取文本文件(中文 数字 英文):控制台中文会有乱码,如果单纯的复制文件没有问题;

使用demo:用字节流读取文本文件

 1 @Test
 2     public void testFileInputString() {
 3         // 2.造流
 4         FileInputStream fo = null;
 5         try {
 6             // 1.造文件
 7             File file = new File("hello.txt");
 8             fo = new FileInputStream(file);
 9             // 3.文件读出
10             byte[] arr = new byte[5];
11             int len = fo.read(arr);
12             while (len != -1) {
13                 System.out.print(new String(arr, 0, len));
14                 len = fo.read(arr);
15             }
16         } catch (Exception e) {
17             // TODO: handle exception
18         } finally {
19             // 4、流关闭
20             try {
21                 if (fo != null)
22                     fo.close();
23             } catch (IOException e) {
24                 // TODO Auto-generated catch block
25                 e.printStackTrace();
26             }
27         }
28 
29     }

4.2实现图片的复制

View Code

 

*4.3对文件复制的通用方法:

说明:不能使用字符流复制照片,但是 字节流可以复制文本文件,但是,如果在复制的过程中,想在控制台查看文件,可能会有中文乱码;

 1 /
 2       复制文件通用方法
 3  4       @Description
 5 @author lixiuming
 6       @date 2021年5月5日下午2:34:36
 7 @param srcStr  复制文件地址(文件名)
 8 @param destStr 复制到文件的地址(文件名)
 9 10      /
11     public void testCopFile(String srcStr, String destStr) {
12         // 2.造流
13         FileInputStream fi = null;
14         FileOutputStream fo = null;
15         try {
16             // 1.造文件
17             File copyFile = new File(srcStr);
18             File copytoFile = new File(destStr);
19             fi = new FileInputStream(copyFile);
20             fo = new FileOutputStream(copytoFile);
21             // 3.文件读出
22             byte[] arr = new byte[1024];// 一般使用1024
23             int len = fi.read(arr);
24             while (len != -1) {
25                 for (int i = 0; i < len; i++) {
26                     fo.write(arr[i]);
27                 }
28                 len = fi.read(arr);
29 
30             }
31         } catch (Exception e) {
32             // TODO: handle exception
33         } finally {
34             // 4、流关闭
35             try {
36                 if (fo != null)
37                     fo.close();
38             } catch (IOException e) {
39                 // TODO Auto-generated catch block
40                 e.printStackTrace();
41             }
42             try {
43                 if (fi != null)
44                     fi.close();
45             } catch (IOException e) {
46                 // TODO Auto-generated catch block
47                 e.printStackTrace();
48             }
49         }
50 
51     }

*三、缓冲流

1.1缓冲流的作用:可以提供效率

*1.2使用和步骤

  • 创建File类对象,指明要操作的文件;
  • 提供具体的流:节点流和缓冲流;
  • 数据的处理
  • 关闭应用的流

demo:使用缓冲流实现文件的复制:(BufferedInputStream/BufferedOutputStream)

 1 /
 2       缓冲流实现的文件复制
 3  4       @Description
 5 @author lixiuming
 6       @date 2021年5月5日下午2:58:38
 7  8      /
 9     @Test
10     public void testCopyFileByBuffer() {
11         BufferedInputStream bi = null;
12         BufferedOutputStream bo = null;
13         // 3.复制
14         byte[] arr;
15         int len;
16         try {
17             // 1.造文件
18             File copy = new File("hello.txt");
19             File copyTo = new File("hello3.txt");
20             // 2.造流
21             FileInputStream fi = new FileInputStream(copy);
22             FileOutputStream fo = new FileOutputStream(copyTo);
23             bi = new BufferedInputStream(fi);
24             bo = new BufferedOutputStream(fo);
25             arr = new byte[1024];
26             len = bi.read(arr);
27             while (len != -1) {
28                 for (int i = 0; i < len; i++) {
29                     bo.write(arr[i]);
30                 }
31                 len = bi.read(arr);
32             }
33         } catch (Exception e) {
34         } finally {
35             // 4.关闭资源
36             try {
37                 if (bo != null) {
38                     bo.close();
39                 }
40             } catch (IOException e) {
41                 e.printStackTrace();
42             }
43             try {
44                 if (bi != null) {
45                     bi.close();
46                 }
47             } catch (IOException e) {
48                 e.printStackTrace();
49             }
50         }
51 
52     }

说明,这里的造流除了 节点流还有缓冲流,因为缓冲流作用在节点流之上;

*1.3 缓冲流复制文件的通用方法

 1 public void testCopyFileByBuffer(String srcStr, String destStr) {
 2         BufferedInputStream bi = null;
 3         BufferedOutputStream bo = null;
 4         // 3.复制
 5         byte[] arr;
 6         int len;
 7         try {
 8             // 1.造文件
 9             File copy = new File(srcStr);
10             File copyTo = new File(destStr);
11             // 2.造流
12             // 2.1造节点流
13             FileInputStream fi = new FileInputStream(copy);
14             FileOutputStream fo = new FileOutputStream(copyTo);
15             // 2.2造缓冲流
16             bi = new BufferedInputStream(fi);
17             bo = new BufferedOutputStream(fo);
18             arr = new byte[1024];
19             len = bi.read(arr);
20             while (len != -1) {
21                 for (int i = 0; i < len; i++) {
22                     bo.write(arr[i]);
23                 }
24                 len = bi.read(arr);
25             }
26         } catch (Exception e) {
27         } finally {
28             // 4.关闭资源
29             // 说明,关闭外层流,内层流自动关闭;所以 file的节点流在此处自动关闭
30             try {
31                 if (bo != null) {
32                     bo.close();
33                 }
34             } catch (IOException e) {
35                 e.printStackTrace();
36             }
37             try {
38                 if (bi != null) {
39                     bi.close();
40                 }
41             } catch (IOException e) {
42                 e.printStackTrace();
43             }
44         }
45 
46     }

1.4BufferReader BufferedWriter 实现文本文件的复制

junit测试版

View Code

封装版:

View Code

四、其他流

1.转换流(属于字符流 ):

  •  InputStreamReader:将字节的输入流 转 字符的输入流;
  • OutputStreamWriter; 将字符的输出流,转字节的输出流

作用:提供字节流和字符流的转换;

通途:可以编码 和 解码;

demo:使用utf-8读取文件,使用gbk写文件;

 1 @Test
 2     public void testReaderWriter() {
 3         InputStreamReader isr = null;
 4         OutputStreamWriter osw = null;
 5         try {
 6             //1.造文件
 7             File strFile = new File("hello.txt");
 8             File destFile = new File("hello_gbk.txt");
 9             //2.造流
10             FileInputStream fi = new FileInputStream(strFile);
11             FileOutputStream fo = new FileOutputStream(destFile);
12             isr = new InputStreamReader(fi, "utf-8");
13             osw = new OutputStreamWriter(fo, "gbk");
14             //3.处理
15             char[] arr = new char[1024];
16             int len = isr.read(arr);
17             while (len != -1) {
18                 for (int i = 0; i < len; i++) {
19                     osw.write(arr[i]);
20                 }
21                 len = isr.read(arr);
22             } 
23         } catch (Exception e) {
24             // TODO: handle exception
25         }finally {
26             //4.关闭流
27             try {
28                 if(isr!=null) {
29                     isr.close();
30                 }
31             } catch (IOException e) {
32                 // TODO Auto-generated catch block
33                 e.printStackTrace();
34             }
35             try {
36                 if(osw!=null) {
37                     osw.close();
38                 }
39             } catch (IOException e) {
40                 // TODO Auto-generated catch block
41                 e.printStackTrace();
42

以上是关于十四IO的主要内容,如果未能解决你的问题,请参考以下文章

java缓冲字符字节输入输出流:java.io.BufferedReaderjava.io.BufferedWriterjava.io.BufferedInputStreamjava.io.(代码片段

六十四 asyncio

十四IO

python3的学习之路十四IO编程

csharp C#代码片段 - 使类成为Singleton模式。 (C#4.0+)https://heiswayi.github.io/2016/simple-singleton-pattern-us

C++ 介绍(十四)——IO流