2011-06-09 103 views
3

我需要上传文件到服务器并监视它的进度。 我需要得到一个通知每次发送多少个字节。如何监视文件上传进度?

例如,在下载的情况下,我有:

HttpURLConnection connection = (HttpURLConnection) m_url.openConnection(); 
connection.connect(); 
InputStream stream = connection.getInputStream(); 
while ((currentBytes = stream.read(byteBuffer)) > 0) {      
    totalBytes+=currentBytes; 
    //calculate something... 
} 

现在我需要上传这样做。但如果使用

OutputStreamWriter stream = new OutputStreamWriter(connection.getOutputStream()); 
stream.write(str); 
stream.flush(); 

比我无法获得任何progres通知,关于发送多少字节(它看起来像自动操作)。

有什么建议吗?

感谢

+0

这是一个耻辱,你没有得到这个问题的真实答案,我很好奇...... – MirroredFate 2011-06-13 15:37:48

+0

看来,HttpURLConnection不是任务的正确对象。它对输出没有阻塞,所以我无法用它来衡量性能。我正在尝试使用套接字。 – Sophie 2011-06-16 13:12:54

+0

是的,使用套接字,您可以使用getSendBufferSize来确定它们何时发送数据。 – MirroredFate 2011-06-16 14:51:45

回答

4

我已经使用了ChannelSocket对象。此对象允许在访问服务器时阻止读取和写入。所以我仿效HTTP使用这个套接字和每个写入请求被阻止,直到它完成。这样我可以按照写交易的实际进度。

+0

'套接字'也可以做到。 – EJP 2013-09-23 03:21:06

2

我在类似情况下所做的是创造的FilterOutputStream子类,覆盖写入(...)方法,然后可以通知的任何写入的字节代码。

+0

嗨。我看到了这样的例子,但也许我不明白。我的意思是当我写入流(使用写入方法一次),我知道我写了多少字节,但我没有看到它的进展。只有在刷新方法时才会将它们发送到服务器。 – Sophie 2011-06-09 14:52:17

+0

@Sophie我也有类似的问题。字节被缓存,并且只能在特定时间后写入。如果您知道它,可以通过预先设置内容长度来解决此问题 - 有关更多信息,请参阅HttpURLConnection.setFixedLengthStreamingMode。 – 2011-06-09 14:54:54

+0

好的谢谢,但如果我用一个大的文本文件调用write()1次,我将不会在每个正在发送的块上看到通知,对不对? – Sophie 2011-06-09 14:57:50

1

如果要计算要上传的字节数,请将对象作为字节数组写入输出流本身,就像您对输入流执行的操作一样。

+0

是的,但是如果我自己没有滑过它,那将会干扰文件被分块的方式。 – Sophie 2011-06-09 14:53:34

0

这与您下载的方式类似。

OutputStream stream = connection.getOutputStream(); 
for(byte b: str.getBytes()) {      
    totalBytes+=1; 
    stream.write(b); 
    if(totalBytes%50 == 0) 
     stream.flush(); //bytes will be sent in chunks of 50 
    //calculate something... 
} 
stream.flush(); 

就是这样的。

+0

调用写入不一定会将这些字节发送到服务器,我需要了解响应时间。 – Sophie 2011-06-09 14:54:54

+0

根据输出流,您正在写入。但是,我可以修改这一点... – MirroredFate 2011-06-09 14:59:18

+0

它可以工作,但我仍然想要在发送每个数据包时收到通知,而不明确配置发送的大小。 – Sophie 2011-06-09 15:08:56

0

另一种方法是轮询服务器,询问有多少数据上传。也许使用一个id或其他东西。

POST - >/uploadfile

  • ID
  • 文件

POST - >/queryuploadstate(返回部分的大小)

  • ID

当然,它需要连接的servlet,并且不允许集群...

5

只需设置分块传输模式并监视您自己写入输出流。

如果您不使用分块或固定长度传输模式,则在写入网络之前,所有写入操作都会写入ByteArrayOutputStream,以便Java可以正确设置Content-Length标头。这是什么让你认为它是非阻塞的。事实并非如此。

+1

确实'connection.setChunkedStreamingMode(2048);'做到了。 – 2013-10-25 11:12:29

+0

它用于流式传输,因此无法按预期工作。 – 2013-10-25 12:08:28

+0

@btoueg'这是为了流式传输,所以它不会按预期工作'为什么? – EJP 2013-12-03 09:26:54