最近简单学习了下Java中IO流的知识,为了方便以后的复习以及巩固学习到的知识,在这里记录一下。
学习IO流首先要了解输入输出的定义,输入流和输出流都是相对于内存设备而言
输入:将外部设备中的数据读取到内存中 输出:将内存中的数据写入到外部设备中
原理图:
IO流按操作的数据类型分为字节流和字符流,按数据流向分为输入流和输出流。
字符流和字节流的关系:字符流相当于字节流读取文字数据后,不直接操作而是先查指定的编码表。获取对应的文字,再对这个文字进行操作。
简单说:字符流=字节流+编码表
IO继承体系图(比较粗略)体系的子类都以父类名为后缀,而且子类名的前缀就是该对象的功能
简单了解了下JavaIO流,我们开始编码简单实现下文件的读写操作
需求1:将一些文字储存到硬盘的一个文件中,思路如下
1、创建一个可以往文件中写入字符数据的字符输出流对象。
既然是往一个文件中写入文字数据,那么在创建对象时,就必需明确该文件的位置(也就是储存到硬盘哪个位置)
FileWriter构造函数的作用:如果文件不存在,则会自动创建,如果文件存在的话就会覆盖该文件,如果构造函数中,加入true就可以对该文件进行续写,而不会覆盖该文件
2、调用Writer对象中的writer(String)方法,写入数据。其实数据是写入到临时储存缓冲区中
3、进行刷新操作,将数据写入到目的地中
4、关闭流,释放资源,这点自己有时会忘。
FileWriter fw = null; try { fw = new FileWriter("G:\\CloudNoteTry\\demo.txt", true); fw.write("排名" + LINE_SEPARATOR + "第二位"); fw.flush(); } catch (IOException e) { System.out.println(e.toString()); } finally { if (fw != null) { try { fw.close(); } catch (IOException e) { throw new RuntimeException("关闭失败"); } } }
需求2:读取硬盘文件中的内容并在控制台输出,思路同需求1基本一样
public static void fileReaderTest() throws IOException { /* * 需求2:读取硬盘中的一个文件并将其输出到控制台中 * 1、创建读取字符流数据的流对象,注意:在创建读取字符流对象时,必需明确被读取的文件的信息,一定要确定该文件是存在的 */ FileReader fr = new FileReader("G:\\CloudNoteTry\\demo.txt"); int ch = 0; while ((ch = fr.read()) != -1) { System.out.println((char) ch); } fr.close(); }
读取时也可以先将读取到的内容存在数组中,如果数组满了则把数组中内容输出到控制台,再进行数据的读取并储存到数组中,直至读取结束。
这样会提高读取的效率,类似于缓冲区,缓冲区可以理解为超市购物所用的购物车,提高了购物的效率。
public static void fileReaderWithArrayTest() throws IOException { FileReader fr = new FileReader("G:\\CloudNoteTry\\demo.txt"); char[] buf = new char[1024]; int len = 0; while ((len = fr.read(buf)) != -1) { System.out.println(new String(buf, 0, len)); } fr.close(); }
需求3:利用FileReader和FileWriter进行文件的复制,这个思路比较简单就是将硬盘文件的内容读取出来并将读取的内容写到具体的文件中,即频繁的读写操作,为了提高效率可以采用数组的形式。
public static void copyFileTest() throws IOException { FileReader fr = new FileReader("G:\\CloudNoteTry\\demo.txt"); FileWriter fw = new FileWriter("C:\\test\\demo1.txt"); int ch = 0; while ((ch = fr.read()) != -1) { fw.write(ch); fw.flush(); } fr.close(); fw.close(); }
这里写入数据时可以一边写一边调用flush()方法将数据从缓冲区中刷新到目的文件中,同时缓冲区清空,也可以不写,因为close()方法在释放资源前会调用flush()方法,将缓冲区的数据进行刷新。
注意:缓冲区一旦充满数据就会自动地进行刷新操作,将数据写到目的文件中,而如果缓冲区没有充满,我们则需要手动将缓冲区的数据写到目的文件中,这个手动的方法就是flush()
所以close()方法只调用一次flush()就可以了。
边写边刷新:读取到数据后立刻进行储存,避免了数据完全丢失,效率不太高。
读完最后再刷新:效率较高,读取小文件时,缓冲区没有充满,没有进行刷新操作,这时可能因为停电等操作导致数据一点也没有写入到文件中。
需求4:采用缓冲流进行文件高效率的读写操作,通过调用缓冲流的方法提高读取的效率。
public static void bufferedReaderTest() throws IOException { FileReader fr = new FileReader("G:\\CloudNoteTry\\demo.txt"); BufferedReader bufr = new BufferedReader(fr); String line = null; while ((line = bufr.readLine()) != null) { System.out.println(line); } bufr.close(); } public static void bufferedWriterTest() throws IOException { FileWriter fw = new FileWriter("C:\\test\\demo.txt"); BufferedWriter bufw = new BufferedWriter(fw); for (int i = 0; i < 4; i++) { bufw.write("张小凡" + i); bufw.newLine(); bufw.flush(); } bufw.close(); }
需求5:利用缓冲流进行文件的复制操作。这里只需要关闭缓冲流即可,不用再关闭文件读取、写入流,因为关闭缓冲流的同时会释放与其相关的一切资源
public static void copyFileByBufferTest() throws IOException { FileReader fr = new FileReader("G:\\CloudNoteTry\\demo.txt"); BufferedReader bufr = new BufferedReader(fr); BufferedWriter bufw = new BufferedWriter(new FileWriter("C:\\test\\demo.txt")); String line = null; while ((line = bufr.readLine()) != null) { bufw.write(line); bufw.newLine(); bufw.flush(); } bufr.close(); bufw.close(); }
readLine()方法原理:
学习JavaIO流只要理解相关流的方法用途及如何使用就可以进行编程练习和适当发挥
需求6:采用字节输入、输出流进行歌曲的复制。对于歌曲、视频、图片等非文本文件只能采用字节流进行操作。
FileInputStream fis=new FileInputStream("G:\\CloudNoteTry\\周深 - 大鱼.mp3"); FileOutputStream fos=new FileOutputStream("G:\\CloudNoteTry\\music.mp3"); int len=0; byte[] buf=new byte[1024]; while((len=fis.read(buf))!=-1) { fos.write(buf,0,len); } fis.close(); fos.close();
附上学习过程参考的博客链接:
https://blog.csdn.net/qq_28233015/article/details/78748628
https://blog.csdn.net/code_change/article/details/28875771