字节数组流ByteArrayInputStream和ByteArrayOutputStreamjava
常常用在须要流和数组之间转化数组
FileInputStream是把文件当作数据源。ByteArrayInputStream则是把内存中的”某个字节数组对象”当作数据源。app
import java.io.ByteArrayInputStream; import java.io.IOException; public class TestByteArray { public static void main(String[] args) { //将字符串转变成字节数组 byte[] b = "abcdefg".getBytes(); test(b); } public static void test(byte[] b) { ByteArrayInputStream bais = null; StringBuilder sb = new StringBuilder(); int temp = 0; //用于保存读取的字节数 int num = 0; try { //该构造方法的参数是一个字节数组,这个字节数组就是数据源 bais = new ByteArrayInputStream(b); while ((temp = bais.read()) != -1) { sb.append((char) temp); num++; } System.out.println(sb); System.out.println("读取的字节数:" + num); } finally { try { if (bais != null) { bais.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
数据流DataInputStream和DataOutputStreamdom
数据流将“基本数据类型与字符串类型”做为数据源,从而容许程序以与机器无关的方式从底层输入输出流中操做Java基本数据类型与字符串类型。ide
public class TestDataStream { public static void main(String[] args) { DataOutputStream dos = null; DataInputStream dis = null; FileOutputStream fos = null; FileInputStream fis = null; try { fos = new FileOutputStream("D:/data.txt"); fis = new FileInputStream("D:/data.txt"); //使用数据流对缓冲流进行包装,新增缓冲功能 dos = new DataOutputStream(new BufferedOutputStream(fos)); dis = new DataInputStream(new BufferedInputStream(fis)); //将以下数据写入到文件中 dos.writeChar('a'); dos.writeInt(10); dos.writeDouble(Math.random()); dos.writeBoolean(true); dos.writeUTF("北京尚学堂"); //手动刷新缓冲区:将流中数据写入到文件中 dos.flush(); //直接读取数据:读取的顺序要与写入的顺序一致,不然不能正确读取数据。 System.out.println("char: " + dis.readChar()); System.out.println("int: " + dis.readInt()); System.out.println("double: " + dis.readDouble()); System.out.println("boolean: " + dis.readBoolean()); System.out.println("String: " + dis.readUTF()); } catch (IOException e) { e.printStackTrace(); } finally { try { if(dos!=null){ dos.close(); } } catch (IOException e) { e.printStackTrace(); } try { if(dis!=null){ dis.close(); } } catch (IOException e) { e.printStackTrace(); } try { if(fos!=null){ fos.close(); } } catch (IOException e) { e.printStackTrace(); } try { if(fis!=null){ fis.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
对象流学习
若是要对某个对象进行读写操做,咱们须要学习一对新的处理流:ObjectInputStream/ObjectOutputStream。ui
ObjectInputStream/ObjectOutputStream是以“对象”为数据源,可是必须将传输的对象进行序列化与反序列化操做。spa
注:序列化实体类实现序列化接口时orm
serialVersionUID适用于Java的序列化机制。简单来讲,Java的序列化机制是经过判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,若是相同就认为是一致的,能够进行反序列化,不然就会出现序列化版本不一致的异常,便是InvalidCastException。public class TestObjectStream { public static void main(String[] args) throws IOException, ClassNotFoundException { write(); read(); } /**使用对象输出流将数据写入文件*/ public static void write(){ // 建立Object输出流,并包装缓冲流,增长缓冲功能 OutputStream os = null; BufferedOutputStream bos = null; ObjectOutputStream oos = null; try { os = new FileOutputStream(new File("d:/bjsxt.txt")); bos = new BufferedOutputStream(os); oos = new ObjectOutputStream(bos); // 使用Object输出流 //对象流也能够对基本数据类型进行读写操做 oos.writeInt(12); oos.writeDouble(3.14); oos.writeChar('A'); oos.writeBoolean(true); //对象流可以对对象数据类型进行读写操做 //Date是系统提供的类,已经实现了序列化接口 //若是是自定义类,则须要本身实现序列化接口 oos.writeObject(new Date()); } catch (IOException e) { e.printStackTrace(); } finally { //关闭输出流 if(oos != null){ try { oos.close(); } catch (IOException e) { e.printStackTrace(); } } if(bos != null){ try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } if(os != null){ try { os.close(); } catch (IOException e) { e.printStackTrace(); } } } } /**使用对象输入流将数据读入程序*/ public static void read() { // 建立Object输入流 InputStream is = null; BufferedInputStream bis = null; ObjectInputStream ois = null; try { is = new FileInputStream(new File("d:/bjsxt.txt")); bis = new BufferedInputStream(is); ois = new ObjectInputStream(bis); // 使用Object输入流按照写入顺序读取 System.out.println(ois.readInt()); System.out.println(ois.readDouble()); System.out.println(ois.readChar()); System.out.println(ois.readBoolean()); System.out.println(ois.readObject().toString()); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 关闭Object输入流 if(ois != null){ try { ois.close(); } catch (IOException e) { e.printStackTrace(); } } if(bis != null){ try { bis.close(); } catch (IOException e) { e.printStackTrace(); } } if(is != null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
转换流对象
InputStreamReader/OutputStreamWriter用来实现将字节流转化成字符流。
System.in是字节流对象,表明键盘的输入,若是咱们想按行接收用户的输入时,就必须用到缓冲字符流BufferedReader特有的方法readLine(),可是通过观察会发如今建立BufferedReader的构造方法的参数必须是一个Reader对象,这时候咱们的转换流。
而System.out也是字节流对象,表明输出到显示器,按行读取用户的输入后,而且要将读取的一行字符串直接显示到控制台,就须要用到字符流的write(String str)方法,因此咱们要使用OutputStreamWriter将字节流转化为字符流。
使用InputStreamReader接收用户的输入,并输出到控制台
public class TestConvertStream { public static void main(String[] args) { // 建立字符输入和输出流:使用转换流将字节流转换成字符流 BufferedReader br = null; BufferedWriter bw = null; try { br = new BufferedReader(new InputStreamReader(System.in)); bw = new BufferedWriter(new OutputStreamWriter(System.out)); // 使用字符输入和输出流 String str = br.readLine(); // 一直读取,直到用户输入了exit为止 while (!"exit".equals(str)) { // 写到控制台 bw.write(str); bw.newLine();// 写一行后换行 bw.flush();// 手动刷新 // 再读一行 str = br.readLine(); } } catch (IOException e) { e.printStackTrace(); } finally { // 关闭字符输入和输出流 if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (bw != null) { try { bw.close(); } catch (IOException e) { e.printStackTrace(); } } } } }