2013-03-05 2 views
2

У меня есть следующий код для скачивания файла с url на sdcard. Этот код отлично работает для небольшого файла, но когда размер файла большой, я получаю загруженный размер файла 0. Любая помощь будет оценена.Скачивание файла в sdcard с указанием размера 0

Java Code

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 или Thread – Gyonder

+1

+1 для SCJP Book – Jacob

+0

@Gyonder может у вас рассказать мне wathz о проблеме здесь почему для большого файла он показывает файл, загруженный 0? – sonia

ответ

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

+0

это не метод. это AsyncTask. с аргументом String (это ваш pdf-адрес). .execute - способ вызова AsyncTask – itsrajesh4uguys

+0

да, теперь он отлично работает ... спасибо ... – sonia

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 ((len = inputStream.read(buffer)) != -1) { 

       fileOutput.write(buffer, 0, len); 

      } 

И как указано в комментарии, вы должны сделать это в фоновом потоке или AsyncTask ...

EDIT1:

Можете ли вы поместить некоторые журналы, чтобы увидеть ошибку. Lik e, если входной поток становится открытым или нет ... Также после вызова для подключения проверить код ответа HTTP, вызвав метод getResponseCode(), если код ответа 200, тогда создайте файл.

+0

Я изменил, но не работал. получив 0 размер – sonia

+0

, пожалуйста, проверьте мои изменения 1 ... –

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

+0

закрытый финал int TIMEOUT_CONNECTION = 5000; // 5sec закрытый финал int TIMEOUT_SOCKET = 30000; // 30sec –

Смежные вопросы