我正在尝试在java上编写客户端和服务器端。服务器端正常(在多个客户端上检查)。
所以,问题出在客户端。我为bytearray
分配内存,从BufferedInputStream
读取并写入bytearray
。然后从bytearray
写入FileOutputStream。一切正常,但bytearray
的可用空间填充为NULL,因此接收的文件不正确(例如图像)。
我找到了2个问题的决定:
bytearray
直到文件结尾(但我不知道文件末尾的位置)BufferedInputStream
阅读FileInputStream
,但不起作用:我实际上需要接收标头和文件。输出标题到控制台并将文件写入光盘。
完整来源
public class SClient {
private static int bufferSize = 8192;
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
System.out.println("Enter the address:");
BufferedReader bufferRead = new BufferedReader
(new InputStreamReader(System.in));
try {
String address = bufferRead.readLine();
System.out.println("Enter the extention of receiving file:");
String fileExt = bufferRead.readLine();
// TODO code application logic here
Socket socket = new Socket(address,4040);
BufferedInputStream bis = new BufferedInputStream
(socket.getInputStream());
BufferedOutputStream bout = new BufferedOutputStream
(socket.getOutputStream());
System.out.println("Enter the request:");
String message = bufferRead.readLine();// GET /index.html HTTP/1.0
System.out.println("Header read");
if(message!=null){
bout.write(message.getBytes());
}
FileOutputStream fout = new FileOutputStream("out"+fileExt);
String s1 = "\r\n\r\n";
bout.write(s1.getBytes());
bout.flush();
System.out.println("Header sent");
byte[] res = new byte[bufferSize];
int got;
while((got = bis.read(res))!=-1){
fout.write(res,0,got);
}
fout.close();
bout.flush();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
服务器端来源:
String endLine = "\r\n";
File f = new File(fileName);
FileInputStream fstream;
fstream = new FileInputStream(f);
response = "HTTP/1.0 200 OK" + endLine;
header = "Content-type: "+ contentType + endLine + "Content-length: " + f.length() + endLine + endLine;
bout.write(response.getBytes());
bout.write(header.getBytes());
while(fstream.read(buffer) != -1) {
bout.write(buffer);
}
System.out.println("Message sent");
bout.flush();
socket.close();
答案 0 :(得分:4)
您必须记住读入缓冲区的字节数,并且必须只返回这些字节。像这样:
int got;
while ((got = bis.read(res)) != -1) {
fout.write(res, 0, got);
}
答案 1 :(得分:3)
不是答案,而是建议......
这看起来不对。基本上,您正在读取一个最大为bufferSize
的字节数组,但只是将一个byte
写入输出流。您还冒着索引越界错误的风险,因为您在每个循环中递增i
未绑定...
while (bis.read(res) != -1) {
fout.write(res[i]);
i++;
}
相反,你应该使用更像......
的东西int bytesRead = -1;
while ((bytesRead = bis.read(res)) != -1) {
fout.write(res, 0, bytesRead);
}
将字节数组写入读取的字节数...
接下来的问题是,你需要一些方法知道你何时到达文件的末尾。
现在,您可以输入某种终结符,但这可能会损坏输出文件。
现在,因为我是一名UI开发人员,我想知道我正在下载多少。那么,第一个然后你可以向下发送流是预期的字节数,然后你可以简单地保持读取的字节数,并在达到你的限制时停止......
这需要对您的服务器稍作更改,它需要能够发送long
值,指示要读取的图像大小(以字节为单位)和\n
< / p>
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String header = br.readLine();
long expectedBytes = Long.parseLong(header);
然后你只需循环直到你有所需的字节数......
int bytesRead = 0;
int totalBytes = 0;
while (totalBytes < expectedBytes) {
bytesRead = bis.read(res);
fout.write(res, 0, bytesRead);
totalBytes += expectedBytes;
}
// Flush and close your steams as required.
做了类似的事情
答案 2 :(得分:1)
记住用Java复制流的规范方法:
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
使用大于零的任何缓冲区大小,通常为4k或8k。