本文共 5310 字,大约阅读时间需要 17 分钟。
IO流主要用于硬板、内存、键盘等处理设备上得数据操作,根据处理数据的数据类型的不同可以分为:字节流(抽象基类为InPutStream和OutPutStream)和字符流(抽象基类为Reader和Writer)。根据流向不同,可以分为:输入流和输出流。 其中主要结构可以用下图来表示:
(转自:http://blog.csdn.net/zzp_403184692/article/details/8057693)
字符流和字节流的主要区别:
1.字节流读取的时候,读到一个字节就返回一个字节; 字符流使用了字节流读到一个或多个字节(中文对应的字节数是两个,在UTF-8码表中是3个字节)时。先去查指定的编码表,将查到的字符返回。
2.字节流可以处理所有类型数据,如:图片,MP3,AVI视频文件,而字符流只能处理字符数据。只要是处理纯文本数据,就要优先考虑使用字符流,除此之外都用字节流。
(转自:http://blog.csdn.net/zzp_403184692/article/details/8057693)其他总结:
1、http://blog.csdn.net/whuhan2013/article/details/51539591
2、http://blog.csdn.net/u013087513/article/details/51956801
()
3、http://blog.csdn.net/jinhongliang123/article/details/7931729 (通过“套接”图表示输入/输出原理)
(箭头貌似标反了)
一些代码:(根据 马士兵 视频整理)
import java.io.*;//流 需求包import java.util.*;//Date类需求包/*范例名称: * 原文件名称: * 要点: * 1. 输入流、输出流 (相对程序来说) * 2. (字节流 --1字节 InputStream/OutputStream vs 字符流 --2字节 Reader/Writer) * 3. (节点流 vs 处理流--缓冲流、转换流、数据流、Print流、Object流) */public class StreamTest { public static void main(String[] args) { // 创建文件 File dirCurrent = new File(""); String strCurrent = dirCurrent.getAbsolutePath();// 获取当前类的绝对路径 String pathStr = strCurrent + File.separator + "javaTest";// separator路径分隔符 String fileName = "test.txt"; File dirFile = new File(pathStr); if (!dirFile.exists()) { dirFile.mkdirs();// 创建目录 } File file = new File(pathStr, fileName); if (!file.exists()) { try { file.createNewFile();// 创建文件 } catch (IOException e) { // TODO: handle exception e.printStackTrace(); } } // FileOutputStream(节点流) String fileName2 = "test2.txt"; File file2 = new File(pathStr, fileName2);// 创建文件 if (!file2.exists()) { try { file2.createNewFile(); } catch (IOException e) { // TODO: handle exception e.printStackTrace(); } } FileInputStream in = null; FileOutputStream out = null; int b = 0; try { in = new FileInputStream(strCurrent + File.separator + "StreamTest.java"); out = new FileOutputStream(file2); while ((b = in.read()) != -1) { out.write((char) b);// 字节流 } in.close(); out.close(); } catch (FileNotFoundException e) { // TODO: handle exception System.out.println("找不到指定文件"); System.exit(-1); } catch (IOException e) { // TODO: handle exception System.out.println("文件复制错误"); System.exit(-1); } // Buffer缓冲流(处理流) try { BufferedWriter bw = new BufferedWriter(new FileWriter(file)); BufferedReader br = new BufferedReader(new FileReader(file)); String strTest = null; for (int i = 0; i <= 10; i++) { strTest = String.valueOf(Math.random()); bw.write(strTest); bw.newLine(); } bw.flush();// 使内存中的数据立刻写出 while ((strTest = br.readLine()) != null) { System.out.println(strTest); } bw.close();// 关闭写缓冲区 br.close();// 关闭读缓冲区 } catch (IOException e) { e.printStackTrace(); } // 转换流 try { // OutputStreamWriter字符流转字节流 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(file, true), "ISO8859_1");// true表示追加 osw.write("Microsoft win7");// 直接写字符串进去啦 System.out.println(osw.getEncoding()); osw.close(); } catch (IOException e) { // TODO: handle exception e.printStackTrace(); } /* // 使用了2根“管道”读取键盘输入,然后输出显示 // InputStreamReader字节流转字符流 InputStreamReader isr = new InputStreamReader(System.in); // BufferedReader的readLine好使 BufferedReader br = new BufferedReader(isr); String s = null; try { System.out.println("请键盘输入字符串:回车结束"); // System.in是阻塞式 s = br.readLine(); while (s != null) { if (s.equalsIgnoreCase("exit")) break; System.out.println(s.toUpperCase()); System.out.println("请键盘输入字符串:回车结束"); s = br.readLine(); } br.close(); } catch (IOException e) { // TODO: handle exception e.printStackTrace(); } */ // 数据流 (先进先出) ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos);// 加 “管道” try { dos.writeDouble(Math.random());// 8字节 dos.writeBoolean(true);// 1字节 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); System.out.println(bais.available());// 剩余字节数 DataInputStream dis = new DataInputStream(bais); System.out.println(dis.readDouble()); System.out.println(dis.readBoolean()); dos.close(); dis.close(); } catch (IOException e) { // TODO: handle exception e.printStackTrace(); } // Print 流 (跟上边 “InputStreamReader字节流转字符流” 注释的部分 一次运行一个) String strTemp = null; BufferedReader br2 = new BufferedReader(new InputStreamReader(System.in)); try { FileWriter fw = new FileWriter(file,true);// 追加 PrintWriter log = new PrintWriter(fw);//Print管道添加到file文件上 while ((strTemp = br2.readLine()) != null) { if (strTemp.equalsIgnoreCase("exit")) break; System.out.println(strTemp.toUpperCase()); log.println("-----"); log.println(strTemp.toUpperCase()); log.flush(); } log.println("===" + new Date() + "==="); log.flush(); log.close(); br2.close(); } catch (IOException e) { // TODO: handle exception e.printStackTrace(); } //Object流(必须序列化相应的object) T t=new T(); try{ FileOutputStream fos=new FileOutputStream(file,true); ObjectOutputStream oos=new ObjectOutputStream(fos); oos.writeObject(t);//写Object流 oos.flush(); oos.close(); }catch(IOException e){ e.printStackTrace(); } }}//Serializable--标记化接口class T implements Serializable{ int i=1; int j=2; double d=1.1; transient int k=33;//序列化时不予考虑}