Почему метод чтения InputStream блокирует ресурс? - PullRequest
0 голосов
/ 01 марта 2019

Почему метод чтения InputStream блокирует ресурс, когда нечего читать?

Допустим, у меня есть файл RandomAccessFile, открытый в режиме RW, и я создаю InputStream / OutputStream, используя дескриптор файла.

Тема 1 пытается прочитать из файла, пока ничего не доступно.В настоящее время, если поток 2 пытается выполнить запись в файл, он блокируется.

Почему это так?

1 Ответ

0 голосов
/ 01 марта 2019

FileDescriptor - это объект, содержащий дескриптор файла ОС, что означает, что это объект, содержащий указатель файла.

Только один поток может одновременно использовать указатель файла / указатель файла, поскольку 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 и т. д.

...