我目前正在尝试用Java创建一个小的下载管理器,我在将一个加载的字节写入文件时遇到了问题。我正在使用DataOutputStream
来编写我从DataInputStream
读取的字节数组。这是我创建的类:
public class DownloadThread extends Thread{
private String url_s;
private File datei;
public DownloadThread(String url_s, File datei){
this.url_s = url_s;
this.datei = datei;
}
public void run(){
// Connect:
int size = 0;
URLConnection con = null;
try {
URL url = new URL(url_s);
con = url.openConnection();
size = con.getContentLength();
// Set Min and Max of the JProgressBar
prog.setMinimum(0);
prog.setMaximum(size);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// Download:
if (con != null || size != 0){
byte[] buffer = new byte[4096];
DataInputStream down_reader = null;
// Output:
DataOutputStream out = null;
try {
out = new DataOutputStream(new FileOutputStream(datei));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
// Load:
try {
down_reader = new DataInputStream(con.getInputStream());
int byte_counter = 0;
int tmp = 0;
int progress = 0;
// Read:
while (true){
tmp = down_reader.read(buffer);
// Check for EOF
if (tmp == -1){
break;
}
out.write(buffer);
out.flush();
// Set Progress:
byte_counter += tmp;
progress = (byte_counter * 100) / size;
prog.setValue( byte_counter );
prog.setString(progress+"% - "+byte_counter+"/"+size+" Bytes");
}
// Check Filesize:
prog.setString("Checking Integrity...");
if (size == out.size()){
prog.setString("Integrity Check passed!");
} else {
prog.setString("Integrity Check failed!");
System.out.println("Size: "+size+"\n"+
"Read: "+byte_counter+"\n"+
"Written: "+out.size() );
}
// ENDE
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
out.close();
down_reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// Clean Up...
load.setEnabled(true);
try {
this.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
这是一个内部类,prog
- 对象是来自它的母类的JProgressBar
,所以可以直接访问它。
我正在尝试下载TinyCC的Windows .exe版本,其大小应为281KB。我用下载管理器下载的文件大小为376KB。
脚本的输出如下所示:
Size: 287181
Read: 287181
Written: 385024
因此,读取字节似乎与文件大小匹配,但写入的字节数更多。我在这里缺少什么?
答案 0 :(得分:9)
这是错误的:
out.write(buffer);
应该是
out.write(buffer, 0, tmp);
您需要指定要写入的字节数,读取并不总是读取完整的缓冲区。
答案 1 :(得分:4)
记住这一点。这是用Java复制流的规范方法。
int count;
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}