سؤال

أواجه مشاكل في تنزيل ملف ثنائي (فيديو) في تطبيقي من الإنترنت. في QuickTime، إذا قمت بتنزيله مباشرة، فهي تعمل بشكل جيد ولكن من خلال تطبيقي بطريقة أو بأخرى افسدت (على الرغم من أنها تبدو نفسها بالضبط في محرر نصوص). هنا مثال:

    URL u = new URL("http://www.path.to/a.mp4?video");
    HttpURLConnection c = (HttpURLConnection) u.openConnection();
    c.setRequestMethod("GET");
    c.setDoOutput(true);
    c.connect();
    FileOutputStream f = new FileOutputStream(new File(root,"Video.mp4"));


    InputStream in = c.getInputStream();

    byte[] buffer = new byte[1024];
    int len1 = 0;
    while ( (len1 = in.read(buffer)) > 0 ) {
         f.write(buffer);
    }
    f.close();
هل كانت مفيدة؟

المحلول

لا أعرف إذا كانت المشكلة الوحيدة، ولكن لديك خلل جافا الكلاسيكي هناك: أنت لا تعول على حقيقة أن القراءة () دائما يسمح بإعادة بايت أقل مما تطلبه. وبالتالي، فإن قراءتك يمكن أن تحصل على أقل من 1024 بايت ولكن الكتابة الخاصة بك يكتب دائما 1024 بايت ربما بما في ذلك البايتات من التكرار الحلقة السابقة.

صحيح مع:

 while ( (len1 = in.read(buffer)) > 0 ) {
         f.write(buffer,0, len1);
 }

ربما تكون أحجام شبكة الكمون العالية أو أحجام الحزمة الأصغر من 3G على نظام Android تؤدي إلى تفاقم التأثير؟

نصائح أخرى

new DefaultHttpClient().execute(new HttpGet("http://www.path.to/a.mp4?video"))
        .getEntity().writeTo(
                new FileOutputStream(new File(root,"Video.mp4")));

مشكلة واحدة هي قراءتك في المخزن المؤقت. إذا لم تكن كل قراءة دفق الإدخال مضاعفة دقيقة من 1024، فستقوم بنسخ البيانات السيئة. يستخدم:

byte[] buffer = new byte[1024];
int len1 = 0;
while ( (len1 = in.read(buffer)) != -1 ) {
  f.write(buffer,0, len1);
}
 public class download extends Activity {

     private static String fileName = "file.3gp";
     private static final String MY_URL = "Your download url goes here";

     @Override
     public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        try {
            URL url = new URL(MY_URL);
            HttpURLConnection c = (HttpURLConnection) url.openConnection();
            c.setRequestMethod("GET");
            c.setDoOutput(true);
            c.connect();

            String PATH = Environment.getExternalStorageDirectory()
                + "/download/";
            Log.d("Abhan", "PATH: " + PATH);
            File file = new File(PATH);
            if(!file.exists()) {
               file.mkdirs();
            }
            File outputFile = new File(file, fileName);
            FileOutputStream fos = new FileOutputStream(outputFile);
            InputStream is = c.getInputStream();
            byte[] buffer = new byte[1024];
            int len1 = 0;
            while ((len1 = is.read(buffer)) != -1) {
                fos.write(buffer, 0, len1);
            }
            fos.flush();
            fos.close();
            is.close();
        } catch (IOException e) {
            Log.e("Abhan", "Error: " + e);
        }
        Log.i("Abhan", "Check Your File.");
    } 
}

قمت بإصلاح الرمز بناء على التقيمات السابقة على هذا الموضوع. لقد قمت باختبار استخدام الكسوف والملفات الكبيرة المتعددة. انها تعمل بشكل جيد. فقط يجب عليك نسخ ولصق هذا على بيئتك وتغيير مسار HTTP والموقع الذي تريد تنزيل الملف إليه.

try {
    //this is the file you want to download from the remote server
    String path ="http://localhost:8080/somefile.zip";
    //this is the name of the local file you will create
    String targetFileName
        boolean eof = false;
    URL u = new URL(path);
    HttpURLConnection c = (HttpURLConnection) u.openConnection();
    c.setRequestMethod("GET");
    c.setDoOutput(true);
    c.connect();
    FileOutputStream f = new FileOutputStream(new File("c:\\junk\\"+targetFileName));
        InputStream in = c.getInputStream();
        byte[] buffer = new byte[1024];
        int len1 = 0;
        while ( (len1 = in.read(buffer)) > 0 ) {
        f.write(buffer,0, len1);
                 }
    f.close();
    } catch (MalformedURLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (ProtocolException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

حظا سعيدا Alireza Aghamohammadi

ما عليك سوى استخدام طريقة نسخ Apache (اباتشي المشاع IO.) - ميزة استخدام جافا!

IOUtils.copy(is, os);

لا تنس إغلاق التدفقات في كتلة أخيرا:

try{
      ...
} finally {
  IOUtils.closeQuietly(is);
  IOUtils.closeQuietly(os);
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top