使用 OkHTTP 客户端下载二进制文件损坏
Binary File Download using OkHTTP Client get corrupted
我正在尝试使用 OkHttp
下载二进制文件并取得进展。
当 BUFFER_SIZE
为 1
.
时,文件可以正确下载
但是,当我将 BUFFER_SIZE
设置为 1024
时,文件会损坏。
BUFFER_SIZE
设置为 1
文件需要很长时间才能下载
下面是代码片段:
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class DownloadTest {
public static String url = "https://cdn.pixabay.com/photo/2017/02/06/12/34/reptile-2042906_1280.jpg";
public static void main(String[] args) throws Exception {
OkHttpClient client = new OkHttpClient();
Call call = client.newCall(new Request.Builder().url(url).get().build());
Response response = call.execute();
System.out.println("" + response.headers().toString());
System.out.println("" + response.body().contentLength());
InputStream inputStream = response.body().byteStream();
float contentLength = (float) response.body().contentLength();
OutputStream fileOutputStream = new FileOutputStream(new File("myfile.jpg"));
System.out.println("writing file " + contentLength);
float downloaded = 0;
/**
* IF BUFFER_SIZE IS 1 file is downloaded properly
* if BUFFER_SIZE is 1024 file is corrupted
* open the downloaded image to test
*/
//byte[] BUFFER_SIZE = new byte[1]; //Proper Download
byte[] BUFFER_SIZE = new byte[1024]; //File Corrupt
while (true) {
int byteRead = inputStream.read(BUFFER_SIZE);
if (byteRead == -1) {
break;
}
downloaded += byteRead;
fileOutputStream.write(BUFFER_SIZE);
System.out.println(" " + downloaded + "/" + contentLength + " = " + ((downloaded / contentLength) * 100));
}
fileOutputStream.flush();
fileOutputStream.close();
System.out.println("file closed");
}
}
您的代码有点混乱,因为 BUFFER_SIZE 看起来像一个数字常量。除此之外,我认为你的问题是fileOutputStream.write(BUFFER_SIZE)。在最后一次写入时,当您的 byte[] 不是 "full," 时,您仍将写入数组的全部内容。使用指定偏移量 (0) 和要写入的字节 (byteRead.)
的重载
如果您的 BUFFER_SIZE 在上次读取时未满,那么您将在文件中写入错误数据:
你有
fileOutputStream.write(BUFFER_SIZE);
你应该有:
fileOutputStream.write(BUFFER_SIZE, 0, byteRead);
EDIT1:我还建议替换这部分代码:
while (true) {
int byteRead = inputStream.read(BUFFER_SIZE);
if (byteRead == -1) {
break;
}
采用更好的方法:
int byteRead;
while ( (byteRead = inputStream.read(BUFFER_SIZE)) > 0 ) {
我正在尝试使用 OkHttp
下载二进制文件并取得进展。
当 BUFFER_SIZE
为 1
.
时,文件可以正确下载
但是,当我将 BUFFER_SIZE
设置为 1024
时,文件会损坏。
BUFFER_SIZE
设置为 1
文件需要很长时间才能下载
下面是代码片段:
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class DownloadTest {
public static String url = "https://cdn.pixabay.com/photo/2017/02/06/12/34/reptile-2042906_1280.jpg";
public static void main(String[] args) throws Exception {
OkHttpClient client = new OkHttpClient();
Call call = client.newCall(new Request.Builder().url(url).get().build());
Response response = call.execute();
System.out.println("" + response.headers().toString());
System.out.println("" + response.body().contentLength());
InputStream inputStream = response.body().byteStream();
float contentLength = (float) response.body().contentLength();
OutputStream fileOutputStream = new FileOutputStream(new File("myfile.jpg"));
System.out.println("writing file " + contentLength);
float downloaded = 0;
/**
* IF BUFFER_SIZE IS 1 file is downloaded properly
* if BUFFER_SIZE is 1024 file is corrupted
* open the downloaded image to test
*/
//byte[] BUFFER_SIZE = new byte[1]; //Proper Download
byte[] BUFFER_SIZE = new byte[1024]; //File Corrupt
while (true) {
int byteRead = inputStream.read(BUFFER_SIZE);
if (byteRead == -1) {
break;
}
downloaded += byteRead;
fileOutputStream.write(BUFFER_SIZE);
System.out.println(" " + downloaded + "/" + contentLength + " = " + ((downloaded / contentLength) * 100));
}
fileOutputStream.flush();
fileOutputStream.close();
System.out.println("file closed");
}
}
您的代码有点混乱,因为 BUFFER_SIZE 看起来像一个数字常量。除此之外,我认为你的问题是fileOutputStream.write(BUFFER_SIZE)。在最后一次写入时,当您的 byte[] 不是 "full," 时,您仍将写入数组的全部内容。使用指定偏移量 (0) 和要写入的字节 (byteRead.)
的重载如果您的 BUFFER_SIZE 在上次读取时未满,那么您将在文件中写入错误数据:
你有
fileOutputStream.write(BUFFER_SIZE);
你应该有:
fileOutputStream.write(BUFFER_SIZE, 0, byteRead);
EDIT1:我还建议替换这部分代码:
while (true) {
int byteRead = inputStream.read(BUFFER_SIZE);
if (byteRead == -1) {
break;
}
采用更好的方法:
int byteRead;
while ( (byteRead = inputStream.read(BUFFER_SIZE)) > 0 ) {