Какая польза от CompletionHandler в AsynchronousFileChannel для чтения данных?

Я работаю с AsynchronousFileChannel для чтения данных. Для чтения данных я нашел два метода чтения:

//1.
Future<Integer> java.nio.channels.AsynchronousFileChannel.read(ByteBuffer dst, long position);

//2.
void java.nio.channels.AsynchronousFileChannel.read(ByteBuffer dst, long position, A attachment, CompletionHandler<Integer, ? super A> handler)

Как указано в документации java, как показано ниже, нет информации о том, что CompletionHandler используется в качестве третьего параметра функции:

Считывает последовательность байтов из этого канала в заданный буфер, начиная с заданной позиции в файле.

Этот метод инициирует чтение последовательности байтов из этого канала в заданный буфер, начиная с данной позиции файла. Результатом чтения является количество прочитанных байтов или -1, если данная позиция больше или равна размеру файла на момент попытки чтения.

Этот метод работает так же, как метод AsynchronousByteChannel.read(ByteBuffer, Object, CompletionHandler), за исключением того, что байты считываются, начиная с заданной позиции в файле. Если данная позиция в файле больше, чем размер файла во время попытки чтения, то байты не считываются.

Может ли кто-нибудь сообщить мне о третьем параметре и любом рабочем примере для CompletionHandler? Зачем нам нужен CompletionHandler и как его использовать?


person KayV    schedule 12.12.2016    source источник
comment
Как узнать, что асинхронная операция чтения завершена? В #1 вы получаете Future<Integer>, а в #2 вы передаете свой собственный CompletionHandler, который будет выполнен после завершения операции. См. также docs.oracle.com/javase/ 7/docs/api/java/nio/каналы/   -  person JimmyB    schedule 12.12.2016
comment
Из Javadoc: параметр handler — это обработчик завершения, который вызывается при завершении (или сбое) операции чтения. Результатом, передаваемым обработчику завершения, является количество прочитанных байтов или -1, если ни один байт не может быть прочитан из-за того, что канал достиг конца потока.   -  person Stefan Zobel    schedule 12.12.2016


Ответы (1)


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

try(AsynchronousFileChannel asyncfileChannel = AsynchronousFileChannel.open(Paths.get("/Users/***/Documents/server_pull/system_health_12_9_TestServer.json"), StandardOpenOption.READ)){
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        ByteBuffer attachment = ByteBuffer.allocate(1024);
        asyncfileChannel.read(buffer, 0, attachment, new CompletionHandler<Integer, ByteBuffer>() {
            @Override
            public void completed(Integer result, ByteBuffer attachment) {
                System.out.println("result = " + result);

                attachment.flip();
                byte[] data = new byte[attachment.limit()];
                attachment.get(data);
                System.out.println(new String(data));
                attachment.clear();
            }

            @Override
            public void failed(Throwable exc, ByteBuffer attachment) {

            }
        });
    }catch(Exception e){
        e.printStackTrace();
    }

И ниже детали обработки:

После завершения операции чтения будет вызван метод Completed() CompletionHandler. В качестве параметров методу complete() передается целое число, указывающее, сколько байтов было прочитано, и «вложение», которое было передано методу read(). «Вложение» — это третий параметр метода read(). В данном случае это был ByteBuffer, в который также считываются данные.

Если операция чтения не удалась, вместо этого будет вызван метод failed() CompletionHandler.

person KayV    schedule 12.12.2016