输入流和输出流的使用示例
规则
关于flush
对于输出流而言,如果其具有Buffer功能,则每次的write操作其实是将内容保存在内存中的数组中(称之为buffer),当buffer容量到达上限时,会自动将buffer的数据写入到目的地;假如buffer没有到达上限,通过手动调用flush()方法,也会将buffer的数据写入到目的地。
对于输入流,则没有这个概念,只有OutputStream/Writer/Console实现了Flushable接口。
FileWriter:内部通过StreamEncoder将字符流编码为字节流,StreamEncoder的默认的的缓冲区大小为8192byteFileOutputStream:没有缓冲区BufferedOutputStream:buffer为字节数组,默认的的缓冲区大小为8192byteBufferedWriter:buffer为字符数组,默认的的缓冲区大小为8192char,即2*8192byte(一个char占用2个byte)
什么时候需要手动调用flush()
使用输出流将内容(假设为字符串)写入到目的地(假设为文件),在write()之后(没有close这个输出流之前),假如使用了这个文件,那么极有可能这个文件中实际的字符与内容不相同(除非这个字符串的大小恰好为8*1024byte的整数倍)。所以,这种情况需要手动调用flush()方法。但是,如果只是在close这个输出流之后,才去使用输出流的输出目的的内容,则不必手动调用flush方法,因为close()方法中会自动调用flush()(API docs no guarantee,but most ),以确保关闭流之前将内容全部写入。
查了很多资料,没有找到确切的说法。
File
对于文本文件,我们可以通过FileReader或者FileWriter进行字符的读写,但是对于一些图片或者视频这类文件,显然字符是无意义的,需要使用FileInputStream与FileOutputStream等字节流进行操作。
示例1:在硬盘上,创建一个文件并写入一些文字数据
@Test
public void testFileWriter() {
try (FileWriter fw = new FileWriter("demo.txt");) {
fw.write("abcde");
fw.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void testFileReader() {
try (FileReader fileReader = new FileReader("demo.txt");) {
int ch = 0;
while ((ch = fileReader.read()) != -1) {
System.out.println("ch=" + (char) ch);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void testFileReader2() {
try (FileReader fileReader = new FileReader("demo.txt");) {
char[] buf = new char[1024];
int num = 0;
while ((num = fileReader.read(buf)) != -1) {
System.out.println(new String(buf, 0, num));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
示例2:复制图片:对于输入流,要去文件必须已经存在;对于输出流,文件如果不存在,则会自动创建
@Test
public void testFileStream() {
try (OutputStream outputStream = new FileOutputStream("/Users/yue/Desktop/copy.png");
InputStream inputStream = new FileInputStream("/Users/yue/Desktop/test.png");
) {
byte[] buffer = new byte[1024 * 1024];
while (inputStream.read(buffer) != -1) {
outputStream.write(buffer);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
示例3:复制视频:使用缓冲功能
@Test
public void testBufferedStream() {
long start = System.currentTimeMillis();
try (
InputStream inputStream = new FileInputStream("/Users/yue/Desktop/test.ev4");
InputStream bis = new BufferedInputStream(inputStream, 1024 * 1024);
OutputStream outputStream = new FileOutputStream("/Users/yue/Desktop/copy.ev4");
OutputStream bos = new BufferedOutputStream(outputStream, 1024 * 1024);
) {
byte[] buffer = new byte[1024 * 1024];
while ((bis.read(buffer)) != -1) {
bos.write(buffer);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("使用缓冲,耗时:" + (end - start));
}
Java对象/基本类型
基本类型
@Test
public void testDataStream() {
try (
DataOutputStream dos = new DataOutputStream(new FileOutputStream("test.txt"));
DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream("test.txt")));
) {
dos.writeChars("abc");
dos.writeBoolean(Boolean.TRUE);
dos.writeInt(123);
System.out.println(dis.readChar());
System.out.println(dis.readChar());
System.out.println(dis.readChar());
System.out.println(dis.readBoolean());
System.out.println(dis.readInt());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//输出如下a
b
c
true
123
对象:类必须实现Serializable接口
public class Person implements Serializable {
private String name;
private int age;
public Person(String name, int age){
this.name = name;
this.age = age;
}
//省略setter/getter
@Override
public String toString() {
return String.format("%s: %d", this.name, this.age);
}
}
@Test
public void testObjectStream() {
//写入
try (
ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("object.ar")));
) {
Person person1 = new Person("xiaohong", 12);
Person person2 = new Person("xiaoming", 12);
oos.writeObject(person1);
oos.writeObject(person2);
oos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//读取
try (
ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream("object.ar")));
) {
Person xiaohong = (Person) ois.readObject();
Person xiaoming = (Person) ois.readObject();
System.out.println(xiaohong);
System.out.println(xiaoming);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
参考
Last updated