4

我必须使用 MTOM 从 Web 服务下载文件。我不知道下面的实施细节。我这样做是有效的(响应是从 web 服务返回的对象,数据是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();

但是,我需要弄清楚下载期间写入了多少字节。这可能需要很长时间,这种方式只是等待完成下载然后关闭输出流并继续。

我知道,我可能需要另一个线程来读取写入字节数并对其进行处理(需要它来更新 SWT 应用程序中的 progressBar)。

我的想法是以某种方式扩展 DataHandler,然后定期询问写入了多少字节)。但我是java noob,我不知道如何实现它。

4

2 回答 2

1

如果您将所有内容都读入 a byte[],您将需要足够的内存来保存整个文件。现在这对您来说可能不是问题,但最好不要养成这种坏习惯(这很容易让服务器停机)。

Apache CommonsGoogle Guava有一个CountingOutputStream类可以完全满足您的需求,只需计算写入的字节数。如果你不能使用这个库,你可以编写一个类似的类,只需实现OutputStream,在构造函数中接收另一个OutputStream,每个方法只是增加byteCount和委托。

于 2014-12-10T14:37:56.470 回答
0

我做了一些研究,之前忽略了名为 getInputStream() 的 DataHandler 方法。使用这种方法,我可以做我需要的事情:

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();
于 2013-01-10T11:58:31.177 回答