目录
处理流
缓冲流(Buffering)
缓冲流测试:BufferedInputStream
缓冲流测试:BufferedReader
转换流
转换流测试代码
数据流
数据流测试代码
打印流(Print)
对象流(Object)
缓冲流要”套接“在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法
常用构造方法如下:
BufferedReader(Reader in) BufferedReader(Reader in,int sz) //sz 为自定义缓冲区的大小 BufferedWriter(Writer out) BufferedWriter(Writer out,int sz) BufferedInputStream(InputStream in) BufferedInputStream(InputStream in,int size) BufferedOutputStream(InputStream in) BufferedOutputStream(InputStream in,int size)
package com.kou.chapter; import java.io.*; public class TestBufferStream { public static void main(String args[]) { FileInputStream fis = null; try { fis = new FileInputStream("D:\\IDEA\\CODE\\JAVASE\\src\\com\\kou\\chapter\\student.java"); // 在FileInputStream节点流的外面套接一层处理流BufferedInputStream BufferedInputStream bis = new BufferedInputStream(fis); int c = 0; System.out.println((char) bis.read()); System.out.println((char) bis.read()); bis.mark(100);// 在第100个字符处做一个标记 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 (FileNotFoundException e) { e.printStackTrace(); } catch (Exception e1) { e1.printStackTrace(); } } }
package com.kou.chapter; import java.io.*; public class TestBufferStream{ public static void main(String args[]){ try{ BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\IDEA\\CODE\\JAVASE\\src\\com\\kou\\chapter\\student.txt")); //在节点流FileWriter的外面再套一层处理流BufferedWriter String s = null; for(int i=0;i<100;i++){ s = String.valueOf(Math.random());//“Math.random()”将会生成一 系列介于0~1之间的随机数。 // static String valueOf(double d)这个valueOf()方法的作用就是把 一个double类型的数转换成字符串 //valueOf()是一个静态方法,所以可以使用“类型.静态方法名”的形式来调用 bw.write(s);//把随机数字符串写入到指定文件中 bw.newLine();//调用newLine()方法使得每写入一个随机数就换行显示 } bw.flush();//调用flush()方法清空缓冲区 BufferedReader br = new BufferedReader(new FileReader("D:\\IDEA\\CODE\\JAVASE\\src\\com\\kou\\chapter\\student.txt")); //在节点流FileReader的外面再套一层处理流BufferedReader while((s = br.readLine())!=null){ //使用BufferedReader处理流里面提供String readLine()方法读取文件中 的数据时是一行一行读取的 //循环结束的条件就是使用readLine()方法读取数据返回的字符串为空值后则表 示已经读取到文件的末尾了。 System.out.println(s); } bw.close(); br.close(); }catch(Exception e){ e.printStackTrace(); } } }
程序的输入指的是把从文件读取到的内容存储到为程序分配的内存区域里面去。流,什么是流,流无非就是两根管道,一根向里,一根向外,向里向外都是对于我们自己写的程序来说,流分为各种各样的类型,不同的分类方式又可以分为不同的类型,根据方向来分,分为输入流和输出流,根据读取数据的单位的不同,又可以分为字符流和字节流,除此之外,还可以分为节点流和处理流,节点流就是直接和数据源连接的流,处理流就是包在其它流上面的流,处理流不是直接和数据源连接,而是从数据源读取到数据以后再通过处理流处理一遍。缓冲流也包含了四个类:
BufferedInputStream、BufferedOutputStream、BufferedReader和BufferedWriter。
流都是成对的,没有流是是不成对的,肯定是一个in,一个out。
InputStream isr = new InputStreamReader(System.in,"ISO8859-1")
转换流非常的有用,它可以把一个字节流转换成一个字符流
转换流有两种,一种叫InputStreamReader,另一种叫OutputStreamWriter。InputStream是字节流,Reader是字符流,InputStreamReader就是把InputStream转换成Reader。
OutputStream是字节流,Writer是字符流,OutputStreamWriter就是把OutputStream转换成Writer。把OutputStream转换成Writer之后就可以一个字符一个字符地通过管道写入数据了
import java.io.*; public class TestTransform1 { public static void main(String args[]) { try { OutputStreamWriter osw = new OutputStreamWriter( new FileOutputStream("D://kou.txt")); osw.write("MircosoftsunIBMOracleApplet");// 把字符串写入到指定的文件 中去 System.out.println(osw.getEncoding());// 使用getEncoding()方法取得 当前系统的默认字符编码 osw.close(); osw = new OutputStreamWriter(new FileOutputStream( "D://kou.txt", true), "ISO8859_1"); // 如果在调用FileOutputStream的构造方法时没有加入true,那么新加入的字符 串就会替换掉原来写入的字符串,在调用构造方法时指定了字符的编码 osw.write("MircosoftsunIBMOracleApplet");// 再次向指定的文件写入字符 串,新写入的字符串加入到原来字符串的后面 System.out.println(osw.getEncoding()); osw.close(); } catch (Exception e) { e.printStackTrace(); } } }
DataInputStream (InputStream in) DataOutputStream (OutputStream out)
package com.kou.chapter; import java.io.*; public class TestDataStream{ public static void main(String args[]){ ByteArrayOutputStream baos = new ByteArrayOutputStream(); //在调用构造方法时,首先会在内存里面创建一个ByteArray字节数组 DataOutputStream dos = new DataOutputStream(baos); //在输出流的外面套上一层数据流,用来处理int,double类型的数 try{ dos.writeDouble(Math.random());//把产生的随机数直接写入到字节数组 ByteArray中 dos.writeBoolean(true);//布尔类型的数据在内存中就只占一个字节 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); System.out.println(bais.available()); DataInputStream dis = new DataInputStream(bais); System.out.println(dis.readDouble());//先写进去的就先读出来,调用 readDouble()方法读取出写入的随机数 System.out.println(dis.readBoolean());//后写进去的就后读出来,这里面 的读取顺序不能更改位置,否则会打印出不正确的结果 dos.close(); bais.close(); }catch(Exception e){ e.printStackTrace(); } } }
通过bais这个流往外读取数据的时候,是一个字节一个字节地往外读取的,因此读出来的数据无法判断是字符串还是bool类型的值,因此要在它的外面再套一个流,通过dataInputStream把读出来的数据转换就可以判断了。读取数据的时候是先写进去的就先读出来,因此读ByteArray字节数组数据的顺序应该是先把占8个字节的double类型的数读出来,然后再读那个只占一个字节的boolean类型的数,因为double类型的数是先写进数组里面的,读的时候也要先读它。这就是先写的要先读。如果先读Boolean类型的那个数,那么读出来的情况可能就是把double类型数的8个字节里面的一个字节读了出来。
PrintWriter(Writer out) PrintWriter(Writer out,boolean autoFlush) PrintWriter(OutputStream out) PrintWriter(OutputStream out,boolean autoFlush) PrintStream(OutputStream out) PrintStream(OutputStream out,boolean autoFlush)
测试代码
/*这个小程序是重新设置打印输出的窗口, * 把默认在命令行窗口输出打印内容设置成其他指定的打印显示窗口 */ import java.io.*; public class TestPrintStream{ public static void main(String args[]){ PrintStream ps = null; try{ FileOutputStream fos = new FileOutputStream("D:\\IDEA\\CODE\\JAVASE\\src\\com\\kou\\chapter\\log.txt"); ps = new PrintStream(fos);//在输出流的外面套接一层打印流,用来控制打印 输出 if(ps != null){ System.setOut(ps);//这里调用setOut()方法改变了输出窗口,以前写 System.out.print()默认的输出窗口就是命令行窗口 //但现在使用System.setOut(ps)将打印输出窗口改成了由ps指定的文件里 面,通过这样设置以后,打印输出时都会在指定的文件内打印输出 //在这里将打印输出窗口设置到了log.txt这个文件里面,所以打印出来的内容会 在log.txt这个文件里面看到 } for(char c=0;c<=1000;c++){ System.out.print(c+"\t");//把世界各国的文字打印到log.txt这个文件中去 } }catch(Exception e){ e.printStackTrace(); } } }
直接将Object 写入或读出
package com.kou.chapter; import java.io.*; public class TestObjectIo { public static void main(String args[]) { T t = new T(); t.k = 8;// 把k的值修改为8 try { FileOutputStream fos = new FileOutputStream( "D:\\IDEA\\CODE\\JAVASE\\src\\com\\kou\\chapter\\TestObjectIo.txt"); ObjectOutputStream oos = new ObjectOutputStream(fos); // ObjectOutputStream流专门用来处理Object的,在fos流的外面套接 ObjectOutputStream流就可以直接把一个Object写进去 oos.writeObject(t);// 直接把一个t对象写入到指定的文件里面 oos.flush(); oos.close(); FileInputStream fis = new FileInputStream( "D:\\IDEA\\CODE\\JAVASE\\src\\com\\kou\\chapter\\TestObjectIo.txt"); ObjectInputStream ois = new ObjectInputStream(fis); // ObjectInputStream专门用来读一个Object的 T tRead = (T) ois.readObject(); // 直接把文件里面的内容全部读取出来然后分解成一个Object对象,并使用强制转换 成指定类型T System.out.print(tRead.i + "\t" + tRead.j + "\t" + tRead.d + "\t" + tRead.k); ois.close(); } catch (Exception e) { e.printStackTrace(); } } } /* * 凡是要将一个类的对象序列化成一个字节流就必须实现Serializable接口 * Serializable接口中没有定义方法,Serializable接口是一个标记性接口,用来给类作标记, 只是起到一个标记作用。 * 这个标记是给编译器看的,编译器看到这个标记之后就可以知道这个类可以被序列化 如果想把某个 类的对象序列化,就必须得实现Serializable接口 */ class T implements Serializable { // Serializable的意思是可以被序列化的 int i = 10; int j = 9; double d = 2.3; int k = 15; // transient int k = 15; // 在声明变量时如果加上transient关键字,那么这个变量就会被当作是透明的,即不存在。 }
直接实现Serializable接口的类是JDK自动把这个类的对象序列化,而如果实现public interfaceExternalizable extends Serializable的类则可以自己控制对象的序列化,
能让JDK自己控制序列化的就不要让自己去控制
部分图片来源:百度图片