2013-03-05 72 views
2

我有以下代碼用於將文件從url下載到SD卡。此代碼適用於小文件,但是當文件大小很大時,我得到的下載文件大小爲0. 任何幫助,將不勝感激。下載顯示大小爲0的SD卡中的文件

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(); 
     } 

    } 

} 
+3

我認爲你應該把下載的AsyncTask或線程 – Gyonder 2013-03-05 08:57:34

+1

+1爲SCJP書 – Jacob 2013-03-05 09:03:09

+0

@Gyonder可以請你告訴我wathz這裏的問題爲什麼對於大文件顯示文件下載0? – sonia 2013-03-05 09:07:49

回答

1

嘗試使用此代碼。

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"/> 

我也在手機上測試過。它的工作。

+0

downloadFile.execute(「http://java.net/downloads/jfjug/SCJP%20Sun%20Certified%20Programmer%20for% 20Java%206-0071591060.pdf「); 哪裏定義了這個方法? – sonia 2013-03-05 10:16:42

+0

這不是一種方法。那是AsyncTask。與參數字​​符串(多數民衆贊成在您的PDF格式)。 .execute是調用AsyncTask – itsrajesh4uguys 2013-03-05 10:21:52

+0

是的方式現在它工作正常...謝謝你... – sonia 2013-03-05 10:26:58

0

具體根據Java文檔public int read (byte\[\] buffer, int offset, int length)方法返回

字節數實際讀取或-1,如果流的末尾, 已經達到。

因此,您應該檢查-1而不是0

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

       fileOutput.write(buffer, 0, len); 

      } 

更改while循環以下

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

       fileOutput.write(buffer, 0, len); 

      } 

而且在評論中指出,你應該在後臺線程或AsyncTask做到這一點...

EDIT1:

你可以把一些日誌看到錯誤點..喜歡如果輸入流被打開或不...打電話後連接檢查HTTP響應代碼通過調用getResponseCode()方法如果響應代碼是200那麼只創建文件..

+0

我改變了,但沒有working.Again獲得0尺寸 – sonia 2013-03-05 09:13:06

+0

請檢查我的編輯1 ... – 2013-03-05 09:39:11

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(); 
    } 
+0

TIMEOUT_CONNECTION和TIMEOUT_SOCKET應採用哪些常量值? – sonia 2013-03-05 09:16:52

+0

私人最終詮釋TIMEOUT_CONNECTION = 5000; // 5秒 私人最終詮釋TIMEOUT_SOCKET = 30000; // 30秒 – 2013-03-05 09:18:08