我写下载文件的方法总是会产生损坏的文件.
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(); }
日志:
file.length : 2485394 | contentLength : 1399242
问题是我OkHttpClient
从我的API单例中得到了它,它被改造使用并且有多个拦截器.那些拦截器污染了这种反应.
所以我OkHttpClient client = Api.getInstance().getOkHttpClient();
成了OkHttpClient client = new OkHttpClient.Builder().build();
,一切都好了!
非常感谢.我现在把方法分成小块.