نتيجة غير متوقعة من HttpURLConnection - قراءة الملف الثنائي البعيد
-
03-07-2019 - |
سؤال
أحاول قراءة ملف ثنائي عن بعد (على سبيل المثال، صورة) من الإنترنت مثل هذا:
HttpURLConnection connection = (HttpURLConnection) myUrl.openConnection(); //myUrl - URL object pointing for some location
if(connection.getResponseCode() == 200){
File temp = File.createTempFile("blabla", fileName); //fileName - string name of file
FileOutputStream out = new FileOutputStream(temp);
int fileSize = Integer.parseInt(connection.getHeaderField("content-length"));
int counter = 0;
DataInputStream in = new DataInputStream(connection.getInputStream());
byte ch[] = new byte[1024];
System.out.println(counter);
while((counter += in.read(ch)) > 0){
out.write(ch);
if(counter == fileSize){
out.close();
break;
}
}
}
محليًا باستخدام خادم الويب المحلي (المضيف المحلي) يعمل بشكل مثالي.
لكن.ثم myUrl هو عنوان URL للملف الموجود على بعض خوادم الويب البعيدة - فهو يُرجع نتائج غير متوقعة.على سبيل المثال، من مصادر ملفات معينة يبدو أنها تكرر بعض الحزم (على ما أعتقد بسبب تلف الحزم السابقة أو شيء ما) ويكون الملف الناتج عادة أكبر بحوالي 10% من الملف الأصلي بسبب هذا التكرار.لذا فإن الملف تالف ولا يمكن فتحه بشكل صحيح باستخدام عارض الصور.
كيف يمكنني حل هذا؟
المحلول
read
لا يقرأ بالضرورة المخزن المؤقت بأكمله (خاصة إذا كان في نهاية الدفق).
لذلك قم بتغيير الحلقة الخاصة بك:
for (;;) {
int len = in.read(ch);
if (len == -1) {
break;
}
out.write(ch, 0, len);
}
ربما ضع هذا الرمز بطريقة ما في مكان ما.
لاحظ أيضًا:
- ليس هناك فائدة من الاستخدام
DataInputStream
هنا (على الرغم منreadFully
غالبا ما يكون مفيدا). قم دائمًا بإغلاق المورد (مثل التدفقات) بالمصطلح المعتاد:
final Resource resource = acquire(); try { use(resource); } finally { resource.close(); }
ربما لن يحدث فرقًا كبيرًا، لكن حجم المخزن المؤقت 1024 صغير بعض الشيء.أنا أميل إلى التخلف عن 8192 بشكل تعسفي.