2

我有以下代码用于将文件从 url 下载到 sdcard 。此代码适用于小文件,但当文件大小较大时,我下载的文件大小为 0。任何帮助将不胜感激。

Java 代码

setContentView(R.layout.activity_download_file);
        String exStorageDirectory = Environment.getExternalStorageDirectory()
                .toString();
        File folder = new File(exStorageDirectory, "Folder");
        folder.mkdir();
        File file = new File(folder, "scjp.pdf");
        try {
            if (!file.exists()) {
                file.createNewFile();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        downloadFile(
                "http://java.net/downloads/jfjug/SCJP%20Sun%20Certified%20Programmer%20for%20Java%206-0071591060.pdf",
                file);

    }

    private void downloadFile(String fileUrl, File directory) {
        try {
            FileOutputStream fileOutput = new FileOutputStream(directory);
            URL url = new URL(fileUrl);
            HttpURLConnection connection = (HttpURLConnection) url
                    .openConnection();
            connection.setRequestMethod("GET");
            connection.setDoOutput(true);
            connection.connect();
            InputStream inputStream = connection.getInputStream();
            byte buffer[] = new byte[1024];
            int len = 0;
            while ((len = inputStream.read(buffer)) > 0) {

                fileOutput.write(buffer, 0, len);

            }

            fileOutput.close();
            Thread.sleep(10000);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}
4

3 回答 3

2

试试这个代码。

package com.example.stack;


import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.RelativeLayout;

public class MainActivity extends Activity {



    ProgressDialog mProgressDialog;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         overridePendingTransition(R.anim.enter, R.anim.enter);
        setContentView(R.layout.activity_main);

        // declare the dialog as a member field of your activity


        // instantiate it within the onCreate method
        mProgressDialog = new ProgressDialog(MainActivity.this);
        mProgressDialog.setMessage("A message");
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.setMax(100);
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

        // execute this when the downloader must be fired
        DownloadFile downloadFile = new DownloadFile();
        downloadFile.execute("http://java.net/downloads/jfjug/SCJP%20Sun%20Certified%20Programmer%20for%20Java%206-0071591060.pdf");
    }



    //The AsyncTask will look like this:

    // usually, subclasses of AsyncTask are declared inside the activity class.
    // that way, you can easily modify the UI thread from here
    private class DownloadFile extends AsyncTask<String, Integer, String> {
        @Override
        protected String doInBackground(String... sUrl) {
            try {
                URL url = new URL(sUrl[0]);
                URLConnection connection = url.openConnection();
                connection.connect();
                // this will be useful so that you can show a typical 0-100% progress bar
                int fileLength = connection.getContentLength();

                // download the file
                InputStream input = new BufferedInputStream(url.openStream());
                OutputStream output = new FileOutputStream("/sdcard/output.pdf");

                byte data[] = new byte[1024];
                long total = 0;
                int count;
                while ((count = input.read(data)) != -1) {
                    total += count;
                    // publishing the progress....
                    publishProgress((int) (total * 100 / fileLength));
                    output.write(data, 0, count);
                }

                output.flush();
                output.close();
                input.close();
            } catch (Exception e) {
            }
            return null;
        }

    //The method above (doInBackground) runs always on a background thread. You shouldn't do any UI tasks there. On the other hand, the onProgressUpdate and onPreExecute run on the UI thread, so there you can change the progress bar:

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            mProgressDialog.show();
        }

        @Override
        protected void onProgressUpdate(Integer... progress) {
            super.onProgressUpdate(progress);
            mProgressDialog.setProgress(progress[0]);
        }
    }

}

在清单文件中添加以下权限。

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.INTERNET"/>

我也在手机上测试过。它的工作。

于 2013-03-05T09:14:31.907 回答
0

根据public int read (byte\[\] buffer, int offset, int length)它返回的方法的java doc

实际读取的字节数,如果已到达流的末尾,则为 -1。

所以你应该检查-1而不是0

改变你的while循环

 while ((len = inputStream.read(buffer)) > 0) {

                fileOutput.write(buffer, 0, len);

            }

跟随

while ((len = inputStream.read(buffer)) != -1) {

                fileOutput.write(buffer, 0, len);

            }

正如评论中指出的那样,您应该在后台线程中执行此操作或AsyncTask...

编辑1:

你能放一些日志来查看错误点吗?比如输入流是否被打开……在调用连接之后,如果响应代码是,则通过调用getResponseCode()方法检查 HTTP 响应代码200只创建文件..

于 2013-03-05T09:06:17.767 回答
0

尝试使用以下代码:

 URL url;

    long startTime = System.currentTimeMillis();

    // Open a connection to that URL.
    URLConnection ucon = null;
    try {
        url = new URL(
                "http://java.net/downloads/jfjug/SCJP%20Sun%20Certified%20Programmer%20for%20Java%206-0071591060.pdf");
        ucon = url.openConnection();
        Log.i("", "image download beginning: " + url);

        ucon.setReadTimeout(TIMEOUT_CONNECTION);
        ucon.setConnectTimeout(TIMEOUT_SOCKET);

        // Define InputStreams to read from the URLConnection.
        // uses 3KB download buffer
        InputStream is = ucon.getInputStream();
        BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5);
        FileOutputStream outStream = new FileOutputStream(
                "mnt/sdcard/example.pdf");
        byte[] buff = new byte[5 * 1024];


        int len;
        while ((len = inStream.read(buff)) != -1) {
            outStream.write(buff, 0, len);
        }

        outStream.flush();
        outStream.close();
        inStream.close();

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 
于 2013-03-05T09:09:24.443 回答