Как определить количество байтов, записанных в настоящее время методом DataHandler.writeTo()?
Я должен загрузить файл из веб-сервиса, используя MTOM. Подробности реализации ниже мне не известны. Я делаю это таким образом, который работает (ответом является объект, возвращаемый веб-сервисами, а данные javax.activation.DataHandler
тип, filePath
это файл, в который я хочу сохранить загруженный контент):
DataHandler dataHandler = response.getData();
File file = new File(filePath);
FileOutputStream fileOutputStream = new FileOutputStream(file);
dataHandler.writeTo(fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
Но мне нужно выяснить, сколько байтов было записано во время загрузки. Это может занять много времени, этот способ просто ожидает завершения загрузки, а затем закрывает выходной поток и продолжает работу.
Я знаю, что мне, вероятно, понадобится другой поток для чтения количества записанных байтов и что-то с ним делать (он нужен для обновления progressBar в приложении SWT).
Моя идея заключалась в том, чтобы как-то расширить DataHandler, а потом периодически спрашивать, сколько байт написано). Но я ява нуб и не знаю, как это реализовать.
2 ответа
Если вы прочитали все на byte[]
Вам понадобится достаточно памяти для хранения всего файла. Это не может быть проблемой для вас сейчас, но хорошо не создавать эту вредную привычку (которая может легко отключить сервер).
Apache Commons и Google Guava имеют CountingOutputStream
класс, который делает именно то, что вы хотите, просто посчитайте, сколько байтов, где написано. Если вы не можете использовать эти библиотеки, вы можете написать аналогичный класс, просто реализовать OutputStream
, получить другой OutputStream
в конструкторе, и каждый метод просто увеличивает byteCount
и делегаты.
Я провел некоторое исследование и раньше не обращал внимания на метод DataHandler с именем getInputStream(). Используя этот метод, я могу делать то, что мне нужно:
DataHandler dataHandler = response.getData();
File file = new File(filePath);
FileOutputStream fileOutputStream = new FileOutputStream(file);
// got Input Stream from DataHandler
InputStream is = dataHandler.getInputStream();
// then I can manage writing file my way
byte data[] = new byte[BUFFER_SIZE];
int br;
Long bytesWritten = 0L;
while ((br = is.read(data)) > 0) {
fileOutputStream.write(data, 0, br);
bytesWritten = bytesWritten + br;
// call some method to update UI progressBar
}
// this is now useless:
// dataHandler.writeTo(fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();