如何在从URL下载(使用http连接)期间检索文件的大小?

13K*_*3KZ 9 java android http download

我正在开发一个使用http连接下载文件的项目.我在下载过程中显示一个带有进度条状态的水平进度条.我的功能看起来像这样:

.......
try {           
        InputStream myInput = urlconnect.getInputStream();
        BufferedInputStream buffinput = new BufferedInputStream(myInput);

        ByteArrayBuffer baf = new ByteArrayBuffer(capacity);
        int current = 0;
        while((current = buffinput.read()) != -1) {
            baf.append((byte) current);
        }
File outputfile = new File(createRepertory(app, 0), Filename);
        FileOutputStream myOutPut = new FileOutputStream(outputfile);
        myOutPut.write(baf.toByteArray());
...
}
Run Code Online (Sandbox Code Playgroud)

我事先知道文件的大小,所以我需要在下载过程中检索大小(在我的while块中).因此,我将能够确定进度条的状态.

progressBarStatus = ((int) downloadFileHttp(url, app) * 100)/sizefile;
Run Code Online (Sandbox Code Playgroud)

long downloadFileHttp(..,..)是我的函数的名称.

我已经尝试使用outputfile.length检索它,但是他的值是"1",也许它是我试图下载的文件数.

有什么方法可以搞清楚吗?

更新1

我没有任何线索可以让我弄清楚这一点.目前我有一个水平进度条,只显示0和100%whitout中间值.我想另一种方法.如果我知道我的wifi速率和文件的大小,我可以确定下载的时间.

我知道我可以检索我的Wifi连接的信息和我要下载的文件的大小.

有人已经有工作或有线程吗?

小智 10

我假设您正在使用HttpURLConnection.在这种情况下,您需要调用该 getContentLength()方法urlconnect.

然而,在服务器要求发送一个有效的内容长度,所以你应该准备为它是-1.

  • 任何值得它的重量的服务器都会发送一个Content-Length标头.如果不存在,大量客户将会挂起. (5认同)
  • @Kylar"值得它的重量" - 这将坚持我很长一段时间.忍不住笑了. (2认同)

Ale*_*lex 6

AsyncTask可能是您的完美解决方案:

private class DownloadFileTask extends AsyncTask<URL, Integer, Long> {
 protected Long doInBackground(URL... urls) {
    Url url = urls[0];
    //connect to url here
    .......
    try {           
        InputStream myInput = urlconnect.getInputStream();
        BufferedInputStream buffinput = new BufferedInputStream(myInput);

        ByteArrayBuffer baf = new ByteArrayBuffer(capacity);
        int current = 0;
        while((current = buffinput.read()) != -1) {
            baf.append((byte) current);
            //here you can send data to onProgressUpdate
            publishProgress((int) (((float)baf.length()/ (float)sizefile) * 100));
        }
    File outputfile = new File(createRepertory(app, 0), Filename);
    FileOutputStream myOutPut = new FileOutputStream(outputfile);
    myOutPut.write(baf.toByteArray());
    ...
 }

 protected void onProgressUpdate(Integer... progress) {
     //here you can set progress bar in UI thread
     progressBarStatus = progress;
 }
Run Code Online (Sandbox Code Playgroud)

}

在你的方法中启动AsyncTask调用

new DownloadFileTask().execute(url);
Run Code Online (Sandbox Code Playgroud)

  • 我同意@Alex的回答.这是要走的路.您可以从响应的Content-Length标头获取'sizeFile'(URLConnection.getContentLength()).但是,不是一次读取一个字节(buffinput.read()),而是同时读取一堆(buffinput.read(byteArray)),除非你想冒险获得数十万个调用onProgressUpdate.如果内容长度未知,则无法获得进度条. (2认同)