简体   繁体   English

为什么 InputStream read 方法会阻塞资源?

[英]Why does InputStream read method block the resource?

Why does InputStream's read method block the resource when there's nothing to read?为什么 InputStream 的 read 方法在没有什么可读取的情况下会阻塞资源?

Let's say I've a RandomAccessFile opened in RW mode, and I create InputStream / OutputStream using File Descriptor.假设我在 RW 模式下打开了一个 RandomAccessFile,并且我使用文件描述符创建了 InputStream/OutputStream。

Thread 1 is trying to read from the file, while nothing is available.线程 1 正在尝试从文件中读取,而没有可用的内容。 At this time, if thread 2 tries to write to the file, it's blocked.此时,如果线程 2 尝试写入文件,则会被阻塞。

Why is that so?为什么呢?

The FileDescriptor is the object carrying the OS file handle, which means it's the object carrying the file pointer. FileDescriptor是携带操作系统文件句柄的对象,这意味着它是携带文件指针的对象。

Only one thread can use the file handle / file pointer at a time, because a FileDescriptor does not support multi-threading.一次只有一个线程可以使用文件句柄/文件指针,因为FileDescriptor不支持多线程。 Access has been synchronized.访问已同步。

If you want two threads to have independent access to the file, then you need two FileDescriptors.如果你想让两个线程独立访问文件,那么你需要两个 FileDescriptor。

To prove my point of shared file pointer, what do you think would happen if you alternately read from FileInputStream and write to FileOutputStream ?为了证明我的共享文件指针的观点,如果您交替读取FileInputStream和写入FileOutputStream ,您认为会发生什么?

Here is code to show what happens:这是显示发生了什么的代码:

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);

Output输出

abcd
ijkl
qrst
abcd1234ijkl1234qrst1234yz

As you can see, reading 4 bytes returns bytes 0-3 and moves the file pointer, so writing of 4 bytes replaces bytes 4-7, then reading 4 bytes returns bytes 8-11, and writing of 4 bytes replaces bytes 12-15, and so forth.如您所见,读取4个字节返回字节0-3并移动文件指针,因此写入4个字节替换字节4-7,然后读取4个字节返回字节8-11,写入4个字节替换字节12-15 ,等等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM