今天来继续总结一下文件io流,这块儿内容是研一的时候学的,大概时间是2016年1月13日到2016年1月14日学的,现在有些忘记,还好之前的笔记还在,重新梳理一下吧。希望能快速上手。此部分内容,重新整理于2021年1月23日。
IO的意思就是输入输出嘛,主要包括内存,文件等地的输入输出。Java.io 包几乎包含了所有操作输入、输出需要的类。所有这些流类代表了输入源和输出目标。Java.io 包中的流支持很多种格式,比如:基本类型、对象、本地化字符集等等。
- 一个流可以理解为一个数据的序列。输入流表示从一个源读取数据,输出流表示向一个目标写数据。
Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中,Java的io包的整体结构如下:
IO流分类
从不同的维度出发,IO流有很多种分类方式,接下来分别介绍:
- 依据功能不同,可以划分为节点流/处理流 , 节点流:直接从特定数据源(文件,内存)读写数据;处理流:套在其它已存在流之上的,为程序提供更强大的读写功能
- 依据数据单位,可以划分为字节流/字符流 , 字节流:按照8位二进制读;字符流:按照2个8位二进制读,是2个字节
- 依据IO流的方向,可以划分为输入流/输出流 ,对此的理解应该站在程序(控制台)的角度上,从文件到程序叫做输入流,从程序到文件叫输出流,读(输入)是读到为程序分配的内存空间中去啦,写(输出)是写到指定的文件中去了。
接下来我们按照这几种符合维度分别讨论下这几种IO流
字节流
字节流分为字节输入流和字节输出流,以及带有buffer缓冲处理的流。
文件字节输入流
文件字节输入流,其类为:FileInputStream ,使用示例如下:
public static void main(String[] args) { int b = 0; FileInputStream in = null; //输入字节流 try { in = new FileInputStream("g:\\TML\\TML.txt"); //创建一个管道,新建一个输入流(对接到指定文件) } catch (FileNotFoundException e) { System.out.println("找不到指定文件"); System.exit(-1); } try { long num=0; while((b=in.read())!=-1){ //表示文件还没有读到结尾,读到结尾返回-1 //强制转化成字符读取出来,如果不加强转,输出的是一系列对应每个字节的ASCII码数字 System.out.println((char) b); num++; } in.close(); //一定要记住,读完要关闭读 System.out.println("共读取了"+num+"个字节"); } catch (IOException e) { System.out.println("文件读取错误"); System.exit(-1); } } //打印出来全是???,因为是一个字节一个字节往出读的,
运行结果,中文汉字发生乱码,因为字节是一个一个读出来的,即使转字符打印,单字节也是半个字符。
A DSFDFDF DFDF DFDFDFA ä¸ å›½
文件输出字节流
文件字节输入流,其类为:FileOutputStream ,使用示例如下:
public static void main(String[] args) { int b = 0; FileOutputStream out = null; FileInputStream in = null; try { in = new FileInputStream("g:\\TML\\TML.txt"); // 从文件里读数据 out = new FileOutputStream("g:\\TML\\ZYJ.txt"); // 往文件里写数据 int num = 0; while ((b = in.read()) != -1) { out.write(b); //写到指定文件中去 num++; } in.close(); out.close(); System.out.println("共复制了" + num + "个字节"); } catch (FileNotFoundException e) { System.out.println("找不到指定文件"); System.exit(-1); } catch (IOException e) { System.out.println("文件复制错误"); System.exit(-1); } System.out.println("复制成功"); }
操作完成后,会产生一个文件内容和复制来源一模一样的文件。
字节缓冲处理流
缓冲输入字节流,其类为:BufferedInputStream ,使用示例如下:
public static void main(String[] args) { FileInputStream fis = null; BufferedInputStream bis = null; int c = 0; try { fis = new FileInputStream("g:\\TML\\TML.txt"); bis = new BufferedInputStream(fis); //把字节流包装到buffer缓冲读入,减少对硬盘的损伤。 System.out.println((char)fis.read()); //读取第一个字符 System.out.println((char)bis.read()); //读取第二个字符 bis.mark(10); //要求在10个字符之内,这个mark应该保持有效,系统会保证buffer至少可以存储10个字符 for (int i = 0; i <= 10 && (c = bis.read()) != -1; i++) { System.out.print((char)c + " "); } System.out.println(); bis.reset(); //回到标记的地方重新读入 for (int i = 0; i <= 10 && (c = bis.read()) != -1; i++) { System.out.print((char)c + " "); } bis.close(); } catch (IOException e) { e.printStackTrace(); }
返回结果如下,可以按行输出:
t m l l o v e g u o c l l o v e g u o c
字符流
字符流分为字符输入流和字符输出流,以及带有buffer缓冲处理的流。
文件输入字符流
文件输入字符流,其类为:FileReader ,使用示例如下:
public static void main(String[] args) { FileReader fr = null; //注意,这里是fileReader int c = 0; try { fr = new FileReader("g:\\TML\\TML.txt"); while ((c = fr.read()) != -1) { System.out.print((char) c); //注意不要换行,打印输出时还是需要char强转,否则读出的是一串数字 } fr.close(); } catch (FileNotFoundException e) { System.out.println("找不到指定文件"); System.exit(-1); } catch (IOException e) { System.out.println("文件读取错误"); System.exit(-1); } }
此时结果中
A DSFDFDF DFDF DFDFDFA 中 国
文件输出字符流
文件输出字符流,其类为:FileWriter ,使用示例如下:
public static void main(String[] args) { FileWriter fw = null; int c = 0; try { fw = new FileWriter("g:\\TML\\MHW.txt"); for (c = 0; c < 200; c++) { fw.write("支持茂神的点赞" + c+" "); //只有字符流才能输出字符串,字节流只能输出字符 } fw.close(); //切记,写完一定要关了,不关资源不释放,无法写入 } catch (IOException e) { System.out.println("文件读取错误"); System.exit(-1); } System.out.println("写入成功"); }
此时会按照字符的模式写入这些内容。