getContentLengthLong() == -1 یعنی در فراداده موجود طول محتوای مشخصی وجود ندارد. خواندن جریان را ادامه دهید و بایت‌های دریافتی یا پیشرفت نامعین را نمایش دهید؛ آن را پاسخ خالی نگیرید و بافری با اندازه منفی تخصیص ندهید.

long expected = connection.getContentLengthLong();
long received = 0;
byte[] buffer = new byte[8192];
try (InputStream input = connection.getInputStream()) {
    int count;
    while ((count = input.read(buffer)) != -1) {
        output.write(buffer, 0, count);
        received += count;
    }
}

اتصال از قبل پیکربندی شده است و output متعلق به فراخواننده است. مهلت‌های اتصال و خواندن و هر محدودیت اندازه برنامه را پیرامون این حلقه نگه دارید. خطای ورودی/خروجی یک دانلود ناموفق است، نه تکمیل موفق با بایت‌های کمتر.

طول‌ها را در همان لایه مقایسه کنید. کدگذاری chunked در HTTP/1.1 می‌تواند جای Content-Length را بگیرد و توسط پیاده‌سازی HTTP رمزگشایی می‌شود. پروکسی ممکن است آن را دوباره قالب‌بندی کند. فشرده‌گشایی هم می‌تواند باعث شود شمار بایت رمزگشایی‌شده برنامه با Content-Length کدگذاری‌شده متفاوت باشد.

اگر هم Transfer-Encoding و هم Content-Length حاضر باشند، عدد راحتی انتخاب نکنید: قالب‌بندی HTTP به کدگذاری انتقال اولویت می‌دهد و ترکیب را خطای احتمالی می‌داند. آن تجزیه را به پیاده‌سازی سازگار بسپارید.

یک URL از نوع FTP از طریق درگاه HTTP نیازمند بررسی رفتار مشخص URLConnection است؛ تضمین نمی‌کند که هر دسترسی به سرآیند HTTP در هر JDK مانند یک URL معمولی HTTP رفتار کند. جایی که فراداده اهمیت دارد از API طول با مقدار بلند استفاده کنید، و ساختار نهایی را در برابر طول یا چک‌سام واقعاً لازم اعتبارسنجی کنید. خواندن بدنه باعث ظاهر شدن سرآیندی که قبلاً غایب بود نمی‌شود.

مقالات مرتبط