为什么没有什么东西可以读取时,InputStream的read方法会阻塞资源?
假设我在RW模式下打开了RandomAccessFile,并使用File Descriptor创建了InputStream / OutputStream。
线程1试图从文件中读取,而没有任何可用的。此时,如果线程2尝试写入文件,则会被阻止。
为什么会这样?
FileDescriptor
是携带OS文件句柄的对象,这意味着它是携带文件指针的对象。
因为FileDescriptor
不支持多线程,所以一次只能有一个线程使用文件句柄/文件指针。访问已同步。
如果您希望两个线程可以独立访问该文件,那么您需要两个FileDescriptors。
为了证明我对共享文件指针的看法,如果你从FileInputStream
中交替阅读并写入FileOutputStream
,你会怎么想?
以下是显示发生情况的代码:
String fileName = "Test.txt";
Files.writeString(Paths.get(fileName), "abcdefghijklmnopqrstuvwxyz", StandardCharsets.US_ASCII);
try (RandomAccessFile raFile = new RandomAccessFile(fileName, "rw");
FileInputStream in = new FileInputStream(raFile.getFD());
FileOutputStream out = new FileOutputStream(raFile.getFD()) ) {
byte[] buf = new byte[4];
for (int i = 0; i < 3; i++) {
int len = in.read(buf);
System.out.println(new String(buf, 0, len, StandardCharsets.US_ASCII));
out.write("1234".getBytes(StandardCharsets.US_ASCII));
}
}
String s = Files.readString(Paths.get(fileName), StandardCharsets.US_ASCII);
System.out.println(s);
产量
abcd
ijkl
qrst
abcd1234ijkl1234qrst1234yz
如您所见,读取4个字节会返回字节0-3并移动文件指针,因此写入4个字节将替换字节4-7,然后读取4个字节将返回字节8-11,写入4个字节将替换字节12-15等等。