我有一个 Android 应用程序,可以在运行时下载并使用文件。该文件是有效的,因为我可以通过浏览器下载它并打开它等。但是我的应用程序不断报告该文件已损坏。
经过调查,我发现服务器(我无法控制)返回了错误的“内容长度:”(~180 与~120000)。 header 是罪魁祸首,因为我通过使用 curl 下载文件来确认该问题 - 这也导致文件被截断。
经过一些研究,我得出的结论是,我使用 BufferedInputStream 附加到 ByteArrayBuffer 会自动将字节数组调整为 url 连接内容长度。为了避免这个问题,我尝试使用 ByteArrayOutputStream 来代替,但这没有解决任何问题。
如果内容长度设置不正确,有人知道如何下载文件吗?浏览器就可以。
这是我最新的尝试:
public static void downloadFileFromRemoteUrl(String urlString, String destination){
try {
URL url = new URL(urlString);
File file = new File(destination);
URLConnection urlConnection = url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
byte[] buffer = new byte[1024];
int curLength = 0;
int newLength = 0;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
while((newLength = inputStream.read(buffer))>0)
{
curLength += newLength;
byteArrayOutputStream.write(buffer, 0, newLength);
}
FileOutputStream fos = new FileOutputStream(file);
fos.write(byteArrayOutputStream.toByteArray());
fos.close();
android.util.Log.d("DB UPDATE", "Done downloading database. Size: " + byteArrayOutputStream.toByteArray().length);
}
catch (MalformedURLException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
最佳答案
After some research I concluded that my use of
BufferedInputStream
to append to aByteArrayBuffer
is autosizing the byte array to the url connections content length.
废话。你认为这些类(Class)具有超自然力量。输出流如何可能知道 Content-length header ? URLConnection
的输入流在内容长度处终止。正确。
To circumvent this, I tried to use ByteArrayOutputStream instead, however this solved nothing.
当然不是。
Anybody know of a way to download a file if the Content-Length is incorrectly set?
您可以使用 Socket
并自己参与 HTTP,这并不像听起来那么简单。但问题出在服务器上,这就是应该修复的地方。提示。或者 @Zong Yu 是正确的,并且该页面是包含 JavaScript 的 HTML。
注意您不需要将整个文件读入内存:
while((newLength = inputStream.read(buffer))>0)
{
curLength += newLength;
fos.write(buffer, 0, newLength);
}
关于java - 当Content-Length设置不正确时,在java中下载文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42033180/