【发布时间】:2016-12-22 19:10:27
【问题描述】:
我在两个设备之间发送文件,所以我建立了一个套接字通信。现在,我只是想发送一个文件,但将来我想发送多个文件(由用户从网格视图中选择)。
问题是当我发送一个文件时,在服务器端(接收文件)socket.getInputStream().read(buffer) 没有检测到文件的结尾。它只是等待发送“更多”数据。
在对这个问题进行了一些搜索之后,我找到了一些主题,这些主题给了我一些选项,但我仍然不满意,因为我不知道这些选项是否能有效地发送多个文件。这是一个例子:How to identify end of InputStream in java
我可以在发送文件后关闭套接字或流对象,但是如果我想发送大量文件,总是关闭和打开套接字会效率不高。
接收器上的代码:
File apkReceived = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/testeReceiveServerComm.apk");
byte[] buffer = new byte [8192];
FileOutputStream fos=new FileOutputStream(apkReceived);
int count=0;
int total=0;//so apra ir vendo quanto recebi.
while((count = in.read(buffer)) != -1){
fos.write(buffer,0,count);
total+=count;
System.out.println("Server Comm receive thread - already received this ammount : "+total);
}
客户端(发送者)上的代码:
File apkToSend=new File(filePath);
byte[] buffer = new byte [8192];
BufferedInputStream bis=new BufferedInputStream(new FileInputStream(apkToSend));
int count;
int total=0;
while((count=bis.read(buffer))!=-1){
out.write(buffer,0,count);
total+=count;
out.reset();
System.out.println("send thread - already sent this ammount : "+total);
}
out.flush();
bis.close();
【问题讨论】:
-
不要依赖流的结尾。它简单得多。只需先发送文件的大小。您可以将大小放入一个整数变量中,然后发送整数的四个字节。接收器首先读取四个字节并知道大小。然后它将从流中准确读取 size 字节。完成后,它再次读取下一个文件大小的四个字节。当所有四个字节都为零时,就没有更多的文件了。
-
最简单的方法是使用例如protocol buffers 1) 写入文件“描述符”(路径、文件名、描述、文件大小等)并根据
filesize写入确切的字节数,然后转到 1),阅读器对其输入流执行相同的操作 -
感谢两位。 Greenapps 方法类似于 Riyaz Parasara 写的答案,所以我实现了类似的东西。 Psink 非常感谢您的回答,肯定会检查协议缓冲区,也许它会更有效(我只会读取 1 次以获得大小和文件?)。再次感谢你们的回答
标签: android sockets streaming file-transfer android-networking