(Java) Файл все еще читается после блокировки - PullRequest
1 голос
/ 24 апреля 2020

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

File someFile = new File(somePath);

FileLock lock = null;
FileChannel fromFileChannel = null;
FileOutputStream fromFileStream = null;
try {
    someFile.createNewFile();
    writeStringToFile(randomString, someFile);

    fromFileStream = new FileOutputStream(someFile);
    fromFileChannel = fromFileStream.getChannel();

    lock = fromFileChannel.lock(0L, Long.MAX_VALUE, false);
} catch (IOException e) {
    fail();
}

System.out.println(someFile.canRead());
System.out.println(someFile.canWrite());

Но почему оба canRead и canWrite возвращают true? Блокировка имеет значение только для FileChannel?

Большое спасибо

1 Ответ

0 голосов
/ 24 апреля 2020

Я провел исследование:

  1. Это неправильное поведение для Windows, поскольку File.canWrite () проверяет только флаг MS-DOS только для чтения, не ACL для файла. Поэтому он даст ложные срабатывания для файлов, к которым у вас нет доступа для записи

  2. File file = new File("file.txt"); boolean fileIsNotLocked = file.renameTo(file); Это простой способ проверить, заблокирован ли файл на Windows.

  3. Ваша блокировка работает до тех пор, пока вы fromFileChannel.close() или lock.release();

  4. Я не экспериментировал с запуском 2 потоков. Первый открывает fileChannel, устанавливает блокировку и пишет. Во втором потоке, если вы попытаетесь снова заблокировать файл, вы получите OverlappingFileLockException или если вы попытаетесь записать в файл, вы получите IOException, что другой процесс заблокировал доступ. Если вы освободите поток формы блокировки 1, вы можете редактировать файл в разных потоках.

Так что это выглядит очень сложно, и все это должно быть супер разработано для блокировок, если вы будете sh использовать их.

Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    FileLock lock = null; FileChannel fromFileChannel = null; FileOutputStream fromFileStream = null;
                    fromFileStream = new FileOutputStream(fileToCreatePath.toFile());
                    fromFileChannel = fromFileStream.getChannel();

                    lock = fromFileChannel.lock(0L, Long.MAX_VALUE, false);
                    ByteBuffer buff = ByteBuffer.wrap("Hello from thread 1".getBytes(StandardCharsets.UTF_8));
                    fromFileChannel.write(buff);
                    //fromFileChannel.close();  - Close channel or release lock
                    // lock.release();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        });
        thread1.start();

Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(100);
                    FileChannel fromFileChannel = null; FileOutputStream fromFileStream = null; FileLock lock = null;
                    fromFileStream = new FileOutputStream(fileToCreatePath.toFile());
                    fromFileChannel = fromFileStream.getChannel();
                  //  lock = fromFileChannel.tryLock(); - FileLockException
                    ByteBuffer buff = ByteBuffer.wrap("Hello from thread 2 :(".getBytes(StandardCharsets.UTF_8));
                    fromFileChannel.write(buff); // IOException
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        thread2.start();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...