[英]Socket InputStream glitches while reading bytes in chunks
我正在通过套接字连接编写简单的文件传输,在以字节为单位下载文件时遇到问题。 当我一次读取一个字节时,一切正常,但是当我尝试以512字节的块为单位进行读取时,在下载文件的所有字节后(由于头文件,我知道了长度)后,套接字开始接收一些随机字节最终导致崩溃,因为发现2x“%”,并且服务器开始尝试计算传入消息的长度时(没有开始时)。
@Override
public void run() {
while (client.isConnected() && !client.isClosed() && !client.isInputShutdown()){
try {
readResponse();
clientWriter.write("0%"); /// IF IT CATCHES EXCEPTION SOCKET CLOSED ON THE OTHER SIDE(DON'T KNOW HOW TO CHECK IT IN ANOTHER WAY)
}
catch (IOException e) {
System.out.println(e.toString());
return;
}
catch (InterruptedException e) {
System.out.println(e.toString());
return;
}
}
}
private void readResponse() throws IOException, InterruptedException {
int length = 0;
int ch;
FileOutputStream file = new FileOutputStream("holder");
boolean bWrite = false;
StringBuilder name = new StringBuilder();
int percentageCount = 0;
String filename="";
length = 0;
int l = 0;
int old = 0;
while ((ch=client.getInputStream().read())!=-1){
if (!bWrite) {
name.append(Character.toChars(ch));
}
if (ch==37 && !bWrite){
if (percentageCount<1){
percentageCount++;
} else {
filename = name.toString();
length = Integer.parseInt(filename.substring(0,filename.indexOf("%")));
l = length;
filename = filename.substring(filename.indexOf("%")+1);
filename = filename.substring(0,filename.indexOf("%"));
file = new FileOutputStream(filename);
bWrite = true;
break;
}
}
}
byte[] bytes = new byte[512];
while (length>=512){
client.getInputStream().read(bytes, 0, 512);
file.write(bytes, 0, 512);
length-=512;
}
if (length>0){
bytes = new byte[length];
client.getInputStream().read(bytes,0,length);
file.write(bytes,0,length);
length = 0;
}
file.flush();
file.close();
}
可以将代码的最后一部分更改为(未测试):
byte[] bytes = new byte[512];
InputStream is = client.getInputStream();
while (length>0) {
int read = is.read(bytes, 0, Math.min(bytes.length, length));
if (read > 0) {
file.write(bytes, 0, read);
length-=read;
}
if (read < 0)
throw new IOException("end reached before all data read";
}
这样可以正确检查返回的大小,避免两个循环并检查流的结尾。
BTW2: getInputStream()
是相当沉重的重量,它应该只进行一次(的is
从我的例子应该在方法开始进行检索,尤其是读循环之前)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.