IO部分学习了一段时间了,现在来做个初步的总结。我的侧重点主要在IO流部分,主要分为两块:节点流和处理流。节点流就是离数据最近的流,处理流则是用于提高性能增强功能,我们首先来看节点流。
节点流
节点流根据处理的数据类型又可分为两部分,字节流和字符流。字节流可以处理一切文件如纯文本、音频、视频等,而字符流只能处理纯文本文件。
字节流
不论是字节流还是字符流,根据数据流向不同,都可划分成输入流和输出流,输入字节流InputStream,输出字节流OutputStream。InputStream是所有的输入字节流的父类,OutputStream是所有的输出字节流的父类,我们通过字节流读取文件的例子来进行理解。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| public class ReadFileTest { public static void main(String[] args) { File src = new File("/Users/jinqi/Desktop/a.txt"); InputStream is = null; try { is = new BufferedInputStream(new FileInputStream(src)); byte[] car = new byte[10]; int len = 0; while(-1!=(len = is.read(car))) { String info = new String(car,0,len); System.out.println(info); } } catch (FileNotFoundException e) { e.printStackTrace(); System.out.println("文件不存在"); }catch (IOException e) { e.printStackTrace(); System.out.println("读取文件失败"); }finally { if (null!=is) { try { is.close(); } catch (IOException e) { e.printStackTrace(); System.out.println("关闭文件输入流失败"); } } } } }
|
字节流写出文件和读取文件步骤基本相同,要注意的是写出文件中需要加入flush()方法,强制刷新,这样较严谨。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public class WriteFileTest {
public static void main(String[] args) { File dest = new File("/Users/jinqi/Desktop/b.txt"); OutputStream os = null; try { os = new BufferedOutputStream(new FileOutputStream(dest,true)); String str = "coding to change the world \r\n"; byte[] data = str.getBytes(); os.write(data,0,data.length); os.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); System.out.println("文件未找到"); }catch (IOException e) { e.printStackTrace(); System.out.println("文件写出失败"); }finally { try { os.close(); } catch (IOException e) { e.printStackTrace(); System.out.println("文件写出流关闭失败"); } } } }
|
文件与文件夹的字符流拷贝前面已经写过,见上一篇《手写字节流文件拷贝类》,这里就不再重复列出。
字符流
字符流只能对纯文本进行操作,因此文件拷贝我们用字节流写过之后,就不再用字符流处理,同样,字符流也可分为输入和输出流,输入字符流Reader,输出字符流Writer,Reader是所有的输入字符流的父类,Writer是所有的输出字符流的父类,我们下面通过字符流读取纯文本的例子进行理解。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| public class ReaderTest { public static void main(String[] args) { File src = new File("/Users/jinqi/Desktop/test/a.txt"); Reader reader = null; try { reader = new BufferedReader(new FileReader(src)); char[] flush = new char[1024]; int len = 0; while(-1!=(len = (reader.read(flush)))) { String str = new String(flush, 0, len); System.out.println(str); } } catch (FileNotFoundException e) { e.printStackTrace(); System.out.println("文件不存在"); } catch (IOException e) { e.printStackTrace(); System.out.println("文件读取失败"); }finally { if (null!= reader) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
|
字符流文件写出同样和文件读取步骤相同,一样需要添加flush()方法,强制刷新。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public class Writer { public static void main(String[] args) { File dest = new File("/Users/jinqi/Desktop/test/d.txt"); BufferedWriter wr = null; try { wr = new BufferedWriter(new FileWriter(dest,true)); String msg = "南京\r\n香港\r\n澳门\r\n"; wr.write(msg); wr.append("我都想去"); wr.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); }finally { try { wr.close(); } catch (IOException e) { e.printStackTrace(); } } } }
|
处理流
看完了节点流,我们来看看处理流,处理流分为转换流、缓冲流、打印流等,我们这里主要研究转换流。
转换流
同样,转换流根据数据的流向也可分为输入和输出流,输入流InputStreamReader,输出流OutputStreamWriter,InputStreamReader用于解码,OutputStreamWriter用于编码,我们通过下面的例子进行理解。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class InputStreamReader {
public static void main(String[] args) throws IOException,UnsupportedEncodingException, FileNotFoundException { BufferedReader br = new BufferedReader( new java.io.InputStreamReader( new FileInputStream( new File("/Users/jinqi/Downloads/JavaDevelopStudy/ReStudy/codingTest/coding.java")), "utf-8") ); String info = null; while(null!=(info=br.readLine())) { System.out.println(info); } br.close(); } }
|
转换流使用注意点,编码字符集和解码字符集必须统一,解码字符集设置要看源文件的编码字符集,解决乱码的主要方法就在于此。
缓冲流
缓冲流的使用在于提高性能,在每次读取写出的时候都可在外层套上缓冲流,同样根据数据流向,也能分为输入流和输出流,这里不再做详细介绍。
注意问题
以下流的新增方法使用时不能发生多态:ByteArrayOutputStream、BufferedReader、BufferedWriter、DataInputStream、DataOutputStream、ObjectInputStream、ObjectOutputStream、PrintStream。