2

我尝试将 zip 文件下载到 android,然后提取 zip 文件。我调试了我的代码,有一个有趣的问题:下载的 zip 文件比原始文件大一点。而且下载的zip文件不能被winrar解压。据说下载的文件以错误结束。(我网站上的 zip 文件没问题。我尝试用 IE 下载。它工作正常。)以下是我的代码:

public void download(final String url, final String savePath, final String saveName) {
    new Thread(new Runnable() {
        public void run() {
            try {
                sendMessage(FILE_DOWNLOAD_CONNECT);
                URL sourceUrl = new URL(url);
                URLConnection conn = sourceUrl.openConnection();
                conn.connect();
                InputStream inputStream = conn.getInputStream();

                int fileSize = conn.getContentLength();

                File savefilepath = new File(savePath);
                if (!savefilepath.exists()) {
                    savefilepath.mkdirs();
                }
                File savefile = new File(savePath+saveName);
                if (savefile.exists()) {
                    savefile.delete();
                }
                savefile.createNewFile();

                FileOutputStream outputStream = new FileOutputStream(
                    savePath+saveName, true);

                byte[] buffer = new byte[1024];
                int readCount = 0;
                int readNum = 0;
                int prevPercent = 0;
                while (readCount < fileSize && readNum != -1) {
                    readNum = inputStream.read(buffer);
                    if (readNum > -1) {
                        outputStream.write(buffer);

                        readCount = readCount + readNum;

                        int percent = (int) (readCount * 100 / fileSize);
                        if (percent > prevPercent) {
                            sendMessage(FILE_DOWNLOAD_UPDATE, percent,
                                readCount);

                            prevPercent = percent;
                        }
                    }
                }
                outputStream.flush();
                outputStream.close();
                inputStream.close();
                //Thread.sleep(50);
                sendMessage(FILE_DOWNLOAD_COMPLETE, savePath);

            } catch (Exception e) {
                sendMessage(FILE_DOWNLOAD_ERROR, e);
            }
        }
    }).start();
}

有人知道这个问题吗?

4

2 回答 2

5

当您读入缓冲区时,您正在将整个缓冲区写入输出流:

outputStream.write(buffer);

您应该只写入已填充的缓冲区部分:

outputStream.write(buffer, 0, readNum);

特别是对于网络下载,不能保证调用inputStream.read(buffer)会填满缓冲区(即使文件中有超过 1024 个字节)。

于 2012-04-11T05:27:00.407 回答
2
public class Download extends Activity {
public static final int DIALOG_DOWNLOAD_PROGRESS = 0;

private ProgressDialog mProgressDialog;
    public String app_name ;
    public String urlpath ;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);



app_name="test.rar";        
    urlpath = "https://www.abc.com/download/"+ app_name;
    if (android.os.Environment.getExternalStorageState().equals
            (android.os.Environment.MEDIA_MOUNTED))
    {        
        startDownload();
    }

    else
    {
         Toast.makeText(getApplicationContext(), "SD Card not found,Insert SD card and try again", Toast.LENGTH_SHORT).show();
    }

}

private void startDownload() {

    new DownloadFileAsync().execute(urlpath);
}
@Override
protected Dialog onCreateDialog(int id) {
    switch (id) {
        case DIALOG_DOWNLOAD_PROGRESS:
            mProgressDialog = new ProgressDialog(this);
            mProgressDialog.setMessage("Downloading Updates..");
            mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            mProgressDialog.setCancelable(false);
            mProgressDialog.setIndeterminate(false);
            mProgressDialog.setMax(100);
            mProgressDialog.show();
            return mProgressDialog;
        default:
            return null;
    }
}
class DownloadFileAsync extends AsyncTask<String, String, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        showDialog(DIALOG_DOWNLOAD_PROGRESS);
    }

    @Override
    protected String doInBackground(String... aurl) {


        try {


            URL url = new URL(urlpath.toString()); // Your given URL.

            HttpURLConnection c = (HttpURLConnection) url.openConnection();
            c.setRequestMethod("GET");
            c.setDoOutput(true);
            c.connect(); // Connection Complete here.!


            int lenghtOfFile = c.getContentLength();


            Log.d("Downloading Updates", "Lenght of file: " + lenghtOfFile);

            String PATH = Environment.getExternalStorageDirectory() + "/download/";

            File file = new File(PATH); // PATH = /mnt/sdcard/download/

            if (!file.exists()) {
                file.mkdirs();
            }
            File outputFile = new File(file, app_name);           
            FileOutputStream fos = new FileOutputStream(outputFile);



            InputStream is = c.getInputStream(); /

            byte[] buffer = new byte[1024];
            int len1 = 0;
            long total = 0;
            while ((len1 = is.read(buffer)) != -1) {
                total += len1;
                publishProgress(""+(int)((total*100)/lenghtOfFile));

                fos.write(buffer, 0, len1); // Write In FileOutputStream.
            }
            fos.flush();
            fos.close();
            is.close();
        } catch (Exception e) {}
        return null;

    }
    protected void onProgressUpdate(String... progress) {
         Log.d("Downloading Updates",progress[0]);
         mProgressDialog.setProgress(Integer.parseInt(progress[0]));
    }

    @Override
    protected void onPostExecute(String unused) {
        dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
        finish();
    }
}
}
于 2012-04-11T12:27:40.707 回答