在日常的开发与面试过程中,IO是一个绕不过去的话题,今天跟大家一起分享下,Java的IO知识。
什么是IO
IO流用来处理设备之间的数据传输。这个设备是指任何能够创造出数据或者从外界接收数据的东西。可以是你的鼠标、硬盘、内存、文件、视频等等。
Java的常用IO
Java常用IO图
Java的IO流API分为两类:字符流与字节流。字符流用来处理文本类型的数据,字节流用来处理二进制字节类型数据(图片、视频等)。
字节流
FileInputStream && FileOutputStream
适合读写非文本数据,如图片、音频文件、视频文件等等其他二进制数据
BufferedInputStream && BufferedOutputStream
提供了更加高效的读写,比起上面多了一个缓冲区。
有了缓冲区为什么快?
如下图,我们磁盘是像下面的光碟的东西组成的,数据就存储在上面。在进行磁盘数据读取(IO),光碟就在那转,那个长的像牙刷头的就在那找数据存储位置。找到位置了才可以进行数据读写。有了缓存区后,我可以写入3000个字符到缓存区,然后一次性写入,减少了读写次数。不用读写一个字符,就得等那个破光盘转一圈,太费事了。
FileInputStream fileInputStream = new FileInputStream("input.bin");
FileOutputStream fileOutputStream = new FileOutputStream("output.bin");
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = bufferedInputStream.read(buffer)) != -1) {
bufferedOutputStream.write(buffer, 0, bytesRead);
}
bufferedInputStream.close();
bufferedOutputStream.close();
PipedInputStream and PipedOutputStream
用来两个线程之间进行数据共享
public static void main(String[] args) throw Exception{
final PipedInputStream pipedInputStream = new PipedInputStream();
final PipedOutputStream pipedOutputStream = new PipedOutputStream();
// 输入流与输出流连接
pipedInputStream.connect(pipedOutputStream);
// 写数据
Thread writerThread = new Thread(() -> {
try {
String data = "Hello,world!";
pipedOutputStream.write(data.getBytes());
pipedOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
});
// 读数据
Thread readerThread = new Thread(() -> {
try {
int bytesRead;
byte[] buffer = new byte[1024];
while ((bytesRead = pipedInputStream.read(buffer)) != -1) {
String receivedData = new String(buffer, 0, bytesRead);
System.out.println("Received: " + receivedData);
}
pipedInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
});
writerThread.start();
readerThread.start();
writerThread.join();
readerThread.join();
}
FilterInputStream && FilterOutputStream
我们都用过Java8的steam API进行数据流操作,用了它,你也可以。他们是用来对读取的数据流进行过滤用的,比如只读取文本数据
过滤器:
class TextFileFilter implements Filter {
@Override
public boolean accept(Object obj) {
if (obj instanceof String) {
return ((String) obj).endsWith(".txt");
} else {
return false;
}
}
数据过滤
public static void main(String[] args) throws IOException {
// 创建一个原始的输入流
InputStream inputStream = new FileInputStream("input.txt");
DataInputStream dataInputStream = new DataInputStream(new BufferedInputStream(inputStream));
// 创建一个过滤器,只允许读取文本文件
TextFileFilter filter = new TextFileFilter();
// 从过滤后的输入流中读取数据
FilterInputStream filteredInputStream = new FilterInputStream(dataInputStream, filter);
String line;
while ((line = filteredInputStream.readLine()) != null) {
System.out.println(line);
}
}
ObjectInputStream 与 ObjectOutputStream
可以从数据流中读写Java对象,在网络传输中,进行Java对象的序列化与反序列使用。
写入
public static void main(String[] args) throws IOException {
Person person = new Person("Alice", 25);
FileOutputStream fileOutput = new FileOutputStream("person.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOutput);
out.writeObject(person);
out.close();
}
读出
public static void main(String[] args) throws IOException, ClassNotFoundException {
FileInputStream fileIn = new FileInputStream("person.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
Person person = (Person) in.readObject();
in.close();
System.out.println(person);
}
有了上面的知识,你就能很容易理解Reader对应的类了,它们都是字符相关的处理类。Java还有其他非常多的IO操作类,有兴趣可以自己再研究研究。