数据流是指一组有顺序的,有起点和终点的字节集合。
最初的版本中,java.io 包中的流只有普通的字节流,即以 byte 为基本处理单位的流。字节流用来读写 8 位的数据,由于不会对数据做任何转换,因此可以用来处理二进制的数据。在后来的版本中,java.io 包中又加入了专门用于字符流处理的类,这个以 Reader 和 Writer 为基础派生的一系列的类。
另外,为了使对象的状态能够方便地永久保存下来,java.io 包中又提供了以字节流为基础的用于对象的永久化保存状态的机制,通过实现 ObjectInput 和 ObjectOutput 接口来完成。
InputStream 和 OutputStream 两个类都是抽象类,抽象类不能进行实例化。在实际应用中我们要用到一系列基本数据流类,都是他们的子类,在实现其父类方法的同时又都定义了其特有的功能。
输入数据流中提供的主要数据操作方法
输出数据流中提供的主要数据操作方法
文件数据流包括 FileInputStream 和 FileOutputStream,这两个类用来进行文件的I/O处理,其数据源或数据终点都应当是文件。通过所提供的方法可以对本机上的文件进行操作,但是不支持方法 mark() 和 reset()
示例(1)
FileInputStream fis = new FileInputStream("myFile.txt"); // 同样可以使用 FileOutputStream 向文件中输出字节 FIleOutputStream out = new FileOutputStream("myFile.txt");
示例(2)
FIleOutputStream out = new FileOutputStream("myFile.txt"); out.wirte(‘H‘); out.wirte(69); out.wirte(76); out.wirte(‘L‘); out.wirte(‘O‘); out.close();
FIleInputStream fis = new FileInputStream("myFile.txt"); while(fis.available() > 0){ System.out.print(fis.read() + " "); } fis.close();
一个过滤器数据流在创建时与一个已经存在的数据流相连,这样在从这样的数据流中读取数据时,它提供的是对一个原始输入数据流的内容进行了特定处理的数据。缓冲区数据流有BufferedInputStream 和 BufferedOutinputStream,它们是在数据流上增加了一个缓冲区,都属于过滤器数据流。当读写数据时,数据以块为单位先进入缓冲区(块大小可以进行设置),其后的读写操作则作用于缓冲区。采用这个办法可以降低不同硬件设备之间速度的差异,提高I/O操作的效率
示例(使用默认缓冲区大小)
FileInputStream fis = new FileInputStream("myFile.txt"); InputStream is = new BufferedInputStream(fis); FileOutputStream fos = new FileOutputStream("myFile.txt"); OutputStream is = new BufferedOutputStream(fos);
示例(自定义设置缓冲区大小)
FileInputStream fis = new FileInputStream("myFile.txt"); InputStream is = new BufferedInputStream(fis, 1024); FileOutputStream fos = new FileOutputStream("myFile.txt"); OutputStream is = new BufferedOutputStream(fos, 1024);
一般在关闭一个缓冲区输出流之前,应先使用 flush() 方法,强制输出剩余数据,以确保缓冲区内的所有数据全部写入输出流
前面提到的数据流中处理数据都是指字节或字节数组,这是进行数据传输时系统默认的数据类型。但实际上所处理的数据并非只有这两种类型,遇到这种情况时就要应用一种专门的数据流来处理。DataInputStream 和 DataOutputStream 就是这样的两个过滤器数据流,它们允许通过数据流来读写 Java 基本类型
示例
DataInputStream dis = new DataInputStream(is); DataOutputStream ous = new DataOutputStream(os);
常用方法
// DataInputStream 常用方法 byte readByte() long readLong() doublue readDouble() boolean readBoolean() String readUTF() int readInt() float readFloat() short readShort() char readChar() // DataOutputStream 常用方法 void writeByte(int aByte) void writeLong(long aLong) void writeDouble(double aBouble) void writeBoolean(boolean aBool) void writeUTF(String aString) void writeInt(int aInt) void writeFloat(float aFloat) void writeShort(short aShort) void rwriteChar(char aChar)
虽然这两个数据流定义了对字符串进行读写的方法,但是由于字符编码的原因,应该避免使用这些方法。Reader 和 Writer 重载了这两个方法,对字符进行操作时应当使用 Reader 和 Writer 两个系列类中的方法
能够输入/输出对象的流称为对象流。Java 通过 java.io 包中的 ObjectInputStream 和 ObjectOutputStream 两个类实现把对象写入文件数据流或从文件数据流中读出的功能
示例
// 写对象数据流 Date date = new Date(); FileOutputStream fos = new FileOutputStream("date.ser"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(date); oos.close(); // 读对象数据流 Date date = null; FileInputStream fis = new FileInputStream("date.ser"); ObjectInputStream ois = new ObjectInputStream(fis); date = (Date) ois.readObject(date); ois.close(); System.out.println("Date serialized at " + date);
序列化的概念
Serializable 接口中没有定义任何方法,只是作为一个标记来指示实现该接口的类可以进行序列化,只有实现 Serializable 接口的类才能被序列化。当一个类实现 Serializable 接口时,表明该类加入了对象序列化协议
序列化一个对象,必须与特定的对象输出/输入流联系起来,通过对象输出流/输入流将对象状态保存下来或者将对象状态恢复。通过 java.io 包中的 ObjectInputStream 和 ObjectOutputStream 两个类可以实现。writeObject() 和 readObject() 方法可以直接将对象保存到输出流中或者从输出流中读取一个对象
// 序列化 public class Student implements Serializable { int id; String name; int age; String department; public Student(int id, String name, int age, String department) { this.id = id; this.name = name; this.age = age; this.department = department; } } // 对象的存储 Student stu = new Student(927103, "Li Ming", 16, "CSD"); FileOutputStream fo = new FileOutputStream("data.ser"); ObjectOutputStream so = new ObjectOutputStream(fo); so.writeObject(stu); so.close(); // 对象的恢复 Student stu; FileInputStream fi = new FileInputStream("data.ser"); ObjectInputStream si = new ObjectInputStream(fi); stu = (Student)si.readObject(); si.close(); System.out.println("ID:" + stu.id + ";name:" + stu.name);
对象结构表
示例
public class Student implements Serializable { public transient Thread myThread; private transient String customerID; private int total; }
从 JDK1.1 开始,java.io 包中加入了专门用于字符流处理的类,它们是以 Reader 和 Writer 为基础派生的一系列类。
同其他语言使用 ASCII 字符集不同,Java 使用 Unicode 字符集来表示和字符。ASCII 字符集以一个字节(8bit)表示一个字符,可以认为一个字符就是一个字节(byte)。但是 Java 使用的 Unicode 是一种大字符集,用两个字节(16bit)来表示一个字符,这时字节与字符就不再相同。为实现与其他程序语言及不同平台的交互,Java 提供一种新的数据流处理方案称作 Reader 和 Writer。在 java.io 包中有许多不同类对其进行支持,其中最重要的是 InputStreamReader 和 OutputStreamWriter 类。这两个类是字节流和 Reader 和 Writer 的接口,用来在字节流和字符流之间作为中介。
在英语国家中,字节编码采用 ISO8859_1 协议。ISO8859_1 是 Latin-1 编码系统映射到 ASCII 标准,能够在不同平台之间正确转换字符。
// 构造映射到 ASCII 码的标准的 InputStreamReader 的方法 InputStreamReader ir = new InputStreamReader(System.in, "8859_1"); // Reader 提供的方法 void close(); void mark(int readAheadLimit); boolean markSupported(); int read(); int read(char[] cbuf); int read(char[] cbuf, int off, int len); boolean ready(); void reset(); long skip(long n); // Writer 提供的方法 void close(); void flush(); void write(char[] cbuf); void write(char[] cbuf, int off, int len); void write(int c); void write(String str); void write(String str, int off, int len);
java.io 中提供流缓冲流 BufferedReader 和 BufferedWriter。其构造方法与 BufferedInputStream 和 BufferedOutputStream 类似。另外,除了 read() 和 write() 方法外,还提供了整行字符的处理方法
方法如下
示例
FileInputStream fis = new FileInputStream("data.ser"); InputStreamReader dis = new InputStreamReader(fis); BufferedReader reader = new BufferedReader(dis); // BufferedReader reader = new BufferedReader(new FileReader("data.ser")); String s; while((s = reader.readLine()) != null) { System.out.println("read:" + s); }
dis.close();
当你写文件的时候,为了提高效率,写入的数据会先放入缓冲区,然后写入文件。因此有时候你需要主动调用 flush()方法
// FileWriter FileWriter fw = new FileWriter("D:/Test.txt"); String s = "hello world"; fw.write(s, 0, s.length()); fw.flush(); //flush将缓冲区内容写入到问题件 // OutputStreamWriter OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:/Test1.txt")); osw.write(s, 0, s.length()); osw.flush(); // PrintWriter PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("D:/Test2.txt")), true); // PrintWriter pw = new PrintWriter(new FileWriter("D:/Test2.txt")); pw.println(s); // close AllWriter fw.close(); osw.close(); pw.close();
File file = new File("D:/Test.txt"); File dest = new File("D:/new.txt"); try { BufferedReader reader = new BufferedReader(new FileReader(file)); BufferedWriter writer = new BufferedWriter(new FileWriter(dest)); String line = reader.readLine(); while(line!=null){ writer.write(line); line = reader.readLine(); } writer.flush(); reader.close(); writer.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
原文:https://www.cnblogs.com/qpliang/p/10994926.html