一般 IO
- InputStream 所有字节输入流的超类
- FileInputStream 用于操作文件的读取
- ByteArrayInputStream
- FilterInputStream
- BufferedInputStream
- DataInputStream
- OutputStream
- FilterOutputStream
- DataOutputStream
- PrintStream
- BufferedOutputStream
- FilterOutputStream
Java 1.1 对基本 I/O 流类库进行了重大改写。Reader 和 Writer 属于其中的新产物,不过它们的出现并不是取代 InputStream 和 OutputStream,因为 InputStream 和 OutputStream 在面向字节的 I/O 仍然具有价值,Reader 和 Writer 则提供了兼容 Unicode 与面向字符的 I/O。
- Reader
- InputStreamReader
- FileReader
- InputStreamReader
- Writer
- OutputStreamWriter
- FileWriter
- PrintWriter
- OutputStreamWriter
案例 1
public static String getFileContent(String path) {
StringBuilder result = new StringBuilder();
try (FileInputStream fileInputStream = new FileInputStream(path);
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, StandardCharsets.UTF_8);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);) {
String readLine = null;
while ((readLine = bufferedReader.readLine()) != null) {
result.append(readLine);
}
} catch (IOException e) {
e.printStackTrace();
return null;
}
return result.toString();
}
案例 2
public static void putFileContent(String content, String path) {
try (PrintWriter printWriter = new PrintWriter(new File(path), "GBK");
BufferedWriter bufferedWriter = new BufferedWriter(printWriter);) {
bufferedWriter.write(content);
} catch (IOException e) {
e.printStackTrace();
}
}
BIO
Blocking IO 的缩写,意思是阻塞型 IO
ServerSocket.accept() 方法会一直阻塞到一个连接建立,返回一个新的 Socket 用于客户端和服务器之间的通信。
如果为每个客户端创建一个新的 Thread,有以下问题:
-
任何时候都可能有大量的线程处于休眠状态,只是等待输入或输出数据,造成资源浪费
-
需要为每个线程的调用栈都分配内存,内存消耗问题
-
即使忽略内存消耗问题,上下文的切换开销也很大
NIO
Channel
FileChannel、DatagramChannel、ServerSocketChannel、SocketChannel
Buffer
关于以下属性的解释可以参考:https://docs.oracle.com/javase/7/docs/api/java/nio/Buffer.html
mark: 缓冲区的 mark 是在调用 reset 方法时将其位置重置到的索引。
position: 缓冲区的 position 是下一个要读或写的元素的索引。缓冲区的位置永远不会为负,也永远不会大于其 limit。
limit: 缓冲区的 limit 是不应该读取或写入的第一个元素的索引。缓冲区的 limit 永远不会是负的,也永远不会超过它的 capacity 。
capacity: 缓冲区的 capacity 就是它包含的元素的数量。缓冲区的容量永远不会是负的,也永远不会改变。
具有 0 <= mark <= position <= limit <= capacity
clear(): 使 buffer 为新的读取或者相对 put 操作做好准备,它将设置 limit 为 capacity,并且 position 设置为 0
flip(): 使 buffer 为新的序列写入或者相对 get 操作做好准备,他将设置 limit 为当前的位置,并且设置 position 为 0
rewind(): 使 buffer 为重新读取已经包含的数据做好准备,它将保持 limit 不变,设置 position 为 0
只读 Buffer
byteBuffer.asReadOnlyBuffer();
MappedByteBuffer
文件的修改在堆外内存进行
https://docs.oracle.com/javase/8/docs/api/java/nio/MappedByteBuffer.html
Selector
select() 方法是阻塞操作。但可以设置超时时间。
SelectionKey
包含以下 int 类型常量 OP_READ、OP_WRITE、OP_CONNECT、OP_ACCEPT