我编写了以下用于从服务器下载某些文件的代码,但问题是这段代码没有读取完整的响应(inputStream)。文件大小为7.5 MB,而我每次获得5.5 MB,当然adobe reader抱怨文件已损坏。这是代码
import java.net.URLConnection;
public class Downloader {
URL url;
public Downloader(){
try {
url = new URL("https://d396qusza40orc.cloudfront.net/algs4partI/slides%2F13StacksAndQueues.pdf");
FileOutputStream outStream;
ObjectOutputStream oStream;
try {
URLConnection con = url.openConnection();
InputStream inStream = con.getInputStream();
outStream = new FileOutputStream("data.pdf");
oStream = new ObjectOutputStream(outStream);
int bytesRead;
int totalBytesRead = 0;
byte[] buffer = new byte[100000];
while((bytesRead = inStream.read(buffer)) > 0){
//outStream.write(buffer, 0 , bytesRead);
oStream.write(buffer, 0, bytesRead);
buffer = new byte[100000];
totalBytesRead += bytesRead;
}
System.out.println("Total Bytes read are = " + totalBytesRead);
oStream.close();
outStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args){
Downloader d = new Downloader();
}
}
我在这里做错了什么想法?提前谢谢。
答案 0 :(得分:1)
InputStream
不保证所有字节一次到达。它们通过网络传输,因此您的阅读速度可能高于您的网络。方法read()
返回当前执行方法时已读取的字节数。如果它返回0,则此信息可能暂时不可用,但稍后可用。
方法read()
返回-1表示流的结束。结论:将> 0
语句中的if
更改为>= 0
。
答案 1 :(得分:1)
当您没有序列化java对象时,您不希望使用ObjectOutputStream
。
取消对该行的评论
//outStream.write(buffer, 0 , bytesRead);
并删除
oStream.write(buffer, 0, bytesRead);
所以:
while((bytesRead = inStream.read(buffer)) > 0){
outStream.write(buffer, 0 , bytesRead);
buffer = new byte[100000]; // this line is useless
totalBytesRead += bytesRead;
}
完全摆脱ObjectOutputStream
。您的文件长度为5.25 MB(5,511,685字节),而不是7.5 MB。
答案 2 :(得分:0)
问题是您正在使用ObjectOutputStream。这将以Java对象序列化格式对输出进行编码,这不是PDF阅读器所期望/需要的。
使用普通FileOutputStream
,它应该有用。