gpt4 book ai didi

java - 使用 OkHttp 下载损坏的文件

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:10:47 27 4
gpt4 key购买 nike

我写的下载文件的方法总是产生损坏的文件。

public static String okDownloadToFileSync(final String link, final String fileName, final boolean temp, DownloadStatusManager statusManager, ErrorDisplayerInterface errorDisplayerInterface) {

Request request = new Request.Builder()
.url(link)
.build();


OkHttpClient client = Api.getInstance().getOkHttpClient();
OutputStream output = null;
InputStream input = null;

try {

Response response = client.newCall(request).execute();

//Add the file length to the statusManager
final int contentLength = Integer.parseInt(response.header("Content-Length"));
if (statusManager != null) {
statusManager.add(Hash.md5(link), contentLength);
}

//Get content type to know extension
final String contentType = response.header("Content-Type");
final String ext = contentTypeMap.get(contentType);

Log.i(TAG, link + "\n --> contentType = " + contentType + "\n --> ext = " + ext);

if (ext == null) {
Log.e(TAG, "-----------\next is null, seems like there is a problem with that url : \n " + link + "\n----------");
return null;
} else if (ext.equals("json")) {
Log.e(TAG, "-----------\ndownloadable file seems to be a json, seems like there is a problem with that url : \n " + link + "\n----------");
return null;
}

//Check if file already exists
if (!temp && fileName != null) {
File test = new File(M360Application.getContext().getFilesDir(), fileName + "." + ext);
if (test.exists()) {
Log.i(TAG, "File exists ! : " + test.getPath());
test.delete();
//return test.getAbsolutePath();
}
}

// expect HTTP 200 OK, so we don't mistakenly save error report instead of the file
if (!response.isSuccessful()) {
errorDisplayerInterface.popWarn(null, "Error while downloading " + link, "connection.getResponseCode() != HttpURLConnection.HTTP_OK");
return null;
}

input = response.body().byteStream();

File file;
if (temp) {
file = File.createTempFile(UUID.randomUUID().toString(), ext, M360Application.getContext().getCacheDir());
} else {
file = new File(M360Application.getContext().getFilesDir(), fileName + "." + ext);
}


output = new FileOutputStream(file);

output.write(response.body().bytes());

// byte data[] = new byte[4096];
// long total = 0;
// int count;
// while ((count = input.read(data)) != -1) {
// output.write(data, 0, count);
// total++;
//
// if (statusManager != null) {
// statusManager.update(Hash.md5(link), contentLength - total);
// }
// }

return file.getAbsolutePath();
} catch (IOException e) {
e.printStackTrace();
errorDisplayerInterface.popError(null, e);

} finally {
if (statusManager != null) {
statusManager.finish(Hash.md5(link));
}
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
ignored.printStackTrace();
}

}
return null;
}

我通过 adb 访问这些文件,将它们传输到我的 sccard,在那里我看到它们的大小似乎合适,但根据例如 Linux file 命令没有类型。

您知道缺少什么以及如何解决吗?

谢谢。


编辑

代码的更简单版本(但错误是相同的)

public static String okioDownloadToFileSync(final String link, final String fileName) throws IOException {

Request request = new Request.Builder()
.url(link)
.build();


OkHttpClient client = Api.getInstance().getOkHttpClient();
Response response = client.newCall(request).execute();

final int contentLength = Integer.parseInt(response.header("Content-Length"));

//Get content type to know extension
final String contentType = response.header("Content-Type");
final String ext = contentTypeMap.get(contentType);

// expect HTTP 200 OK, so we don't mistakenly save error report instead of the file
if (!response.isSuccessful()) {
return null;
}

File file = new File(M360Application.getContext().getFilesDir(), fileName + "." + ext);

BufferedSink sink = Okio.buffer(Okio.sink(file));
sink.writeAll(response.body().source());
sink.close();

Log.i(TAG, "file.length : " + file.length() + " | contentLength : " + contentLength);

return file.getAbsolutePath();

}

The log : file.length : 2485394 | contentLength : 1399242


解决方案

问题是我从我的 API 单例中获取了 OkHttpClient,它被改造使用并且有多个拦截器。那些拦截器污染了响应。

所以我 OkHttpClient client = Api.getInstance().getOkHttpClient(); 变成了 OkHttpClient client = new OkHttpClient.Builder().build(); 一切都是现在好了!

非常感谢。我现在将该方法分成更小的部分。

最佳答案

代替output.write(response.body().bytes());尝试这样的事情

byte[] buff = new byte[1024 * 4];

while (true) {
int byteCount = input.read(buff);
if (byteCount == -1) {
break;
}
output.write(buff, 0, byteCount);
}

关于java - 使用 OkHttp 下载损坏的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41610209/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com