2014-11-05 18 views
6

Tôi muốn tải xuống tệp văn bản từ url web và lưu tệp cục bộ trên thiết bị và sử dụng nó trong ứng dụng của tôi.Tải xuống tệp văn bản từ web

Code:

try { 
    File file = new File(getFilesDir(), "file.txt"); 
    if (file.length() > 0) { 
     //File already exists and it is not empty 
     return; 
    } 
    URL url = new URL("https://www.abc.com/file.txt"); 
    FileOutputStream fos = new FileOutputStream(file); 
    InputStream in = url.openStream(); 
    byte[] buffer = new byte[1024]; 
    int length = 0; 
    while ((length = in.read(buffer)) > 0) { 
     fos.write(buffer, 0, length); 
    } 
    fos.flush(); 
    fos.close(); 
} catch (Exception e) { 
    // TODO: 
} 

Như bạn thấy, mã đi với getFilesDir() giả định rằng luôn luôn tồn tại. Tuy nhiên, có một vài câu hỏi, với kết nối mạng và quyền phù hợp:

  1. Giả định của tôi là getFilesDir() không thành công?
  2. Có trường hợp nào của một trong hai tệp không được tải xuống/sai nội dung, v.v., với mã này không?
  3. Khi tôi gặp sự cố trong đó tệp được tải xuống nhưng có tất cả các ký tự được mã hóa, cho dù tôi có tải xuống được bao nhiêu lần, nó vẫn có cùng văn bản được mã hóa. Chỉ khi tôi cài đặt lại ứng dụng của mình thì văn bản thích hợp đã được tải xuống. Và không bao giờ có vấn đề đó kể từ đó. Bất kỳ lý do nào cho hành vi kỳ lạ đó?

EDIT: Đây là những gì tôi nhận được như nội dung khi tôi cố gắng đọc các tập tin mà tôi đã tải xuống (đôi khi xảy ra 1 trong 10) được hiển thị trong logcat:

enter image description here

Mã để đọc các file:

BufferedReader inputReader= = new BufferedReader(
     new InputStreamReader(new FileInputStream(file))); 
String inputString; 
StringBuffer stringBuffer = new StringBuffer(); 
while ((inputString = inputReader.readLine()) != null) { 
    Log.e("inputString: ", inputString); 
} 
inputReader.close(); 

cảm ơn

+0

getFilesDir() sẽ luôn cung cấp thư mục tệp. Nhưng nó có thể chưa tồn tại tôi nghĩ. Vậy mã có tải xuống không? – greenapps

+0

Cho đến nay thiết bị/trình giả lập nào tôi đã thử nghiệm, nó tải xuống tệp đúng cách. Nhưng tôi thấy ít người dùng báo cáo một số vấn đề. – Housefly

+0

Xem câu hỏi SO này: [Android: Cách tải xuống Tệp từ máy chủ và lưu tệp đó vào thư mục cụ thể trong sdcard] (http://stackoverflow.com/questions/16117067/androidhow-to-download-the-file- thư mục từ máy chủ-và-lưu-thư-cụ-cụ-riêng) –

Trả lời

2

Có giả định của tôi về getFilesDir() thất bại trong mọi trường hợp?

Theo số documentation, nó luôn hoạt động mà không cần quyền truy cập.

Có trường hợp nào tệp không tải xuống/sai nội dung, v.v., bằng mã này không?

Chắc chắn, tôi có nghĩa là chỉ một giọt kết nối đơn giản sẽ làm cho tải về thất bại và rất nhiều những thứ khác có thể đi sai như thiếu sự cho phép yêu cầu (android.permission.INTERNET), mã hóa sai, đĩa đầy đủ, ...

Khi tôi phải đối mặt với một vấn đề mà tập tin được tải về nhưng có tất cả mã hóa ký tự, bất kể như thế nào có thể lần tôi tải về nó, nó vẫn có cùng văn bản được mã hóa. Chỉ khi tôi cài đặt lại ứng dụng của mình thì văn bản thích hợp đã được tải xuống. Và không bao giờ có vấn đề đó kể từ đó. Bất kỳ lý do nào cho hành vi kỳ lạ đó?

Có thể đó là sự cố mã hóa, hãy bọc FileOutputStream của bạn theo số OutputStreamWriter, cho phép bạn chuyển tham số mã hóa trong hàm tạo.

Writer writer = new OutputStreamWriter(fos); 
. 
. 
. 
writer.write(buffer, 0, length); 
0

Đó không thực sự là câu trả lời mà là lời khuyên, sử dụng ion thư viện mạng cho Android.

Từ ví dụ:

Ion.with(context) 
.load("http://example.com/really-big-file.zip") 
// have a ProgressBar get updated automatically with the percent 
.progressBar(progressBar) 
// and a ProgressDialog 
.progressDialog(progressDialog) 
// can also use a custom callback 
.progress(new ProgressCallback() {@Override 
    public void onProgress(int downloaded, int total) { 
     System.out.println("" + downloaded + "/" + total); 
    } 
}) 
.write(new File("/sdcard/really-big-file.zip")) 
.setCallback(new FutureCallback<File>() { 
    @Override 
    public void onCompleted(Exception e, File file) { 
     // download done... 
     // do stuff with the File or error 
    } 
}); 

Tất cả các hoạt động được thực hiện không có trong thread UI, vì vậy người dùng luôn luôn nhìn thấy một ứng dụng đáp ứng.

1

Ví dụ sau có thể hữu ích:

try { 
    // Create a URL for the desired page 
    URL url = new URL("mysite.com/thefile.txt"); 

    // Read all the text returned by the server 
    BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); 
    String str; 
    while ((str = in.readLine()) != null) { 
     // str is one line of text; readLine() strips the newline character(s) 
    } 
    in.close(); 
    } catch (MalformedURLException e) { 
    } catch (IOException e) { 
} 
+0

để biết thêm chi tiết, bạn cũng có thể tham khảo [tải xuống tệp từ máy chủ] (http://wininterview.blogspot.in/2013/04/download-file -in-android-from-remote.html) –

+0

Và viết nó bằng cách sử dụng 'FileOutputStream f = new FileOutputStream (tệp); f.write (str.getBytes()); '?? – Housefly

0

tôi có thể không thực sự nhận xét về những gì diễn ra sai trong trường hợp của bạn, tôi sẽ đăng một đoạn mã tôi đang sử dụng để phát hiện loại tập tin tôi m nhắm mục tiêu và sau đó nhận được nó. Điều này luôn làm việc như tôi mong đợi. Tôi đã sửa đổi phương thức "onPostExecute" của tôi cho phù hợp với câu trả lời của tôi ở đây và tôi đã cố giữ tên của các biến tương tự như của bạn. Tôi đã bỏ qua thanh chỉ báo tiến trình tải xuống để đơn giản hóa đoạn mã. Việc tải xuống phải được thực hiện trong nền, do đó "AsyncTask" được sử dụng. Đối với đoạn trích, tôi sử dụng tệp văn bản ngẫu nhiên từ google.

final String file_url = "https://www.kernel.org/doc/Documentation/power/drivers-testing.txt"; 
String fileExtension = MimeTypeMap.getFileExtensionFromUrl(file_url); 
final String fileName = URLUtil.guessFileName(file_url, null, fileExtension); 
final String path = Environment.getExternalStorageDirectory().toString() + "/" + fileName; 

new AsyncTask<Void, Void, Void>() { 
     @Override 
     protected Void doInBackground(Void... params) { 
      try { 
       URL url = new URL(file_url); 
       URLConnection connection = url.openConnection(); 
       connection.connect(); 

       // download the file 
       InputStream in = new BufferedInputStream(url.openStream()); 
       OutputStream output = new FileOutputStream(path); 
       byte buffer[] = new byte[1024]; 
       int length; 
       while ((length = in.read(buffer)) != -1) { 
        output.write(buffer, 0, length); 
       } 
       output.flush(); 
       output.close(); 
       in.close(); 
      } catch (IOException e) { 
       Log.e("Downloading file", "Download Error", e); 
      } 
      return null; 
     } 

     @Override 
     public void onPostExecute(Void result) { 
      try { 
       File file = new File(path); 

       BufferedReader inputReader = new BufferedReader(new FileReader(file)); 
       String inputString; 

       while ((inputString = inputReader.readLine()) != null) { 
        Log.e("inputString: ", inputString); 
       } 
       inputReader.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    }.execute(); 
0

Hãy thử với mã bên dưới:

public void downloadFile(){ 
    String DownloadUrl = "Paste Url to download a text file here…"; 
    DownloadManager.Request request = new DownloadManager.Request(Uri.parse(DownloadUrl)); 
    request.setDescription("sample text file for testing"); //appears the same in Notification bar while downloading 
    request.setTitle("Sample.txt");     
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 
     request.allowScanningByMediaScanner(); 
     request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); 
    } 
    request.setDestinationInExternalFilesDir(getApplicationContext(),null, "sample.pdf"); 

    // get download service and enqueue file 
    DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); 
    manager.enqueue(request); 
} 

public static boolean isDownloadManagerAvailable(Context context) { 
    try { 
     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) { 
      return false; 
     } 
     Intent intent = new Intent(Intent.ACTION_MAIN); 
     intent.addCategory(Intent.CATEGORY_LAUNCHER); 
     intent.setClassName("com.android.providers.downloads.ui","com.android.providers.downloads.ui.DownloadList"); 
     List <resolveinfo> list = context.getPackageManager().queryIntentActivities(intent, 
       PackageManager.MATCH_DEFAULT_ONLY); 
     return list.size() > 0; 
    } catch (Exception e) { 
     return false; 
    } 
} 
Các vấn đề liên quan