Как правильно установить позицию в NIO.2 AsynchronousFileChannel.write (ByteBuffer src, длинная позиция)? - PullRequest
0 голосов
/ 22 августа 2011

Моя Java-программа выполняет многопоточное XSLT-преобразование и записывает результаты в файл.Чтобы избежать узкого места ввода-вывода, я экспериментирую с новым AsynchronousFileChannel.Потоки XSLT должны передавать свои выходные данные в виде строк (что работает), а Writer - добавлять их в файл (который еще не работает).

Я написал собственный класс Writer для операций записи.Мои потоки вызывают метод Writer.write (String text).Там я хотел бы добавить строку как ByteBuffer к AsynchronousFileChannel.К сожалению, я не смог найти подсказки, что использовать в качестве значения позиции в asyncOutput.write (ByteBuffer, Long).Я пробовал разные значения для позиции без успеха (Выходные данные зашифрованы).Я почти уверен, что с синхронизацией проблем нет, так как код хорошо работает с FileChannels (которые не поддерживают простой неблокирующий режим io):

  • asyncOutput.size ()
  • asyncOutput.size () + future.get (). longValue ()
  • 0

Вот код, как я пытаюсь это сделать:

public class MyWriter {
private AsynchronousFileChannel asyncOutput;    

    MyWriter(String filename) throws IOException {
        asyncOutput = AsynchronousFileChannel.open(Paths.get(filename), StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
    }

    public void write(String output) throws IOException, ExecutionException, InterruptedException {
        System.err.println("Write was called");
        this.future = asyncOutput.write(string2ByteBuffer(output), asyncOutput.size());
    }

    public ByteBuffer string2ByteBuffer (String text){
    ...
    }
}

Метод вызывается из потоков XSLT (Runnable) следующим образом:

synchronized (this) {
        this.write2Writer(outputXmlWriter.toString());
        }
...
private void write2Writer(String output) throws IOException {
    try {
        myWriter.write(output);
    } catch (ExecutionException | InterruptedException ex) {
        ex.printStackTrace();
    }
}

Ответы [ 3 ]

1 голос
/ 25 августа 2011

AsynchronousFileChannel не имеет глобальной позиции, это намеренно. Вместо этого этот канал предоставляет асинхронный API-интерфейс для приложений, которым требуется одновременный доступ к различным частям файла.

1 голос
/ 29 августа 2011

Раствор извлечен из ссылки:

Future<Integer> future = asyncOutput.write(string2ByteBuffer(output), this.position);
this.position += future.get();

Источник: http://cr.openjdk.java.net/~alanb/6830721/webrev.00/test/java/nio/channels/AsynchronousFileChannel/Basic.java.html

1 голос
/ 23 августа 2011

Я не нашел подсказки, что использовать в качестве значения позиции в asyncOutput.write (ByteBuffer, Long)

Это позиция, которую вы хотите позиционировать. Я не понимаю, что в этом такого загадочного.

...