带套接字的大文件传输
当我使用套接字编程传输大文件时,收到的文件不完整,即它是一个mp3文件,当我播放声音时很奇怪。 代码是:
服务器端:
File myFile = new File("abc.mp3"); { Socket sock = servsock.accept(); int packetsize=1024; double nosofpackets=Math.ceil(((int) myFile.length())/packetsize); BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myFile)); for(double i=0;i<nosofpackets+1;i++) { byte[] mybytearray = new byte[packetsize]; bis.read(mybytearray, 0, mybytearray.length); System.out.println("Packet:"+(i+1)); OutputStream os = sock.getOutputStream(); os.write(mybytearray, 0,mybytearray.length); os.flush(); } }
客户端:
int packetsize=1024; FileOutputStream fos = new FileOutputStream("zz.mp3"); BufferedOutputStream bos = new BufferedOutputStream(fos); double nosofpackets=Math.ceil(((int) (new File("abc.mp3")).length())/packetsize); for(double i=0;i<nosofpackets+1;i++) { InputStream is = sock.getInputStream(); byte[] mybytearray = new byte[packetsize]; int bytesRead = is.read(mybytearray, 0,mybytearray.length ); System.out.println("Packet:"+(i+1)); bos.write(mybytearray, 0,mybytearray.length); } sock.close(); bos.close();
在客户端,我使用了new File("abc.mp3")).length
只是为了简单(我可以从服务器端发送文件的长度)。
如果客户端和服务器是同一台机器,则此代码可以正常工作,但如果文件位于不同的计算机上,则该文件会失真。
在Java中复制流的规范方法:
int count; byte[] buffer = new byte[8192]; while ((count = in.read(buffer)) > 0) { out.write(buffer, 0, count); }
适用于任何大于零的缓冲区大小。 应该尽量避免将缓冲区大小与输入大小联系起来的诱惑。
我认为问题在于您忽略了各种read
调用返回的值,并假设它们完全填充缓冲区。 这是有问题的:
-
从文件读取时, 最后一次读取可能不会填充缓冲区。
-
从套接字读取时, 任何读取都可能在填充缓冲区之前返回。
最终结果是您的写入将垃圾放入流(在服务器端),并放入目标文件(在客户端)。
此外,根据文件的大小将文件分成多个块是毫无意义的。 只需阅读,直到你到达文件的末尾。
不要重新发明轮子,使用IOUtils.copy()
。
不要使用数据包。
尝试使用ByteArrayOutputStream而不是使用静态字节数组。
继续阅读输入流,直到你达到EOF。 n将每个写入ByteArrayOutputStream。
InputStream is = sock.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); int byteToBeRead = -1; while((byteToBeRead = is.read())!=-1){ baos.write(byteToBeRead); } byte[] mybytearray = baos.toByteArray(); bos.write(mybytearray, 0,mybytearray.length);
希望这可以帮助。
- Apache Commons Email with attach with base64
- Java用于读取200万行文本文件的最快方式
- Avatar.js和Project Avatar
- 将List转换为JSON
- 如何从Java中的xml Document对象中删除encoding =“UTF-8”standalone =“no”
- 在JScrollPane中获取显示的组件
- 如何使用apache POI和java将一个工作簿工作表复制到另一个工作簿表
- 任何人都可以在mac os 10.5.8上运行eclipse galileo
- 如何让RESTful java客户端在Openstack上发送GET / POST请求?