文件传输中的数据丢失 – JAVA?
我有一个FileServer和一个FileClient,服务器在客户端连接时发送文件.这是一个简单的程序,只是为了理解背后的概念.
我能够将文件从Server发送到Client,缓冲区为1024. 我在服务器和放大器的while循环中放了一些prinln语句.客户.我发现我的服务器没有发送整个文件. //Server byte [] mybytearray = new byte [1024]; FileInputStream fis = new FileInputStream(myFile); BufferedInputStream bis = new BufferedInputStream(fis); bis.read(mybytearray,mybytearray.length); OutputStream os = sock.getOutputStream(); System.out.println("Sending...n mybytearray length:"+mybytearray.length+"file length:"+(int)myFile.length()); int read,readTotal=0; while ((read = fis.read(mybytearray,mybytearray.length)) != -1) { os.write(mybytearray,read); System.out.println("File REad:"+read+"readtotal:"+readTotal); //* readTotal += read; } System.out.println("Final File Read:"+read+" Final readtotal:"+readTotal); os.flush(); sock.close(); } Println语句输出为: Sending... mybytearray length:1024file length:12767554 File REad:1024readtotal:0 File REad:1024readtotal:1024 .............and a lot of it...and then File REad:1024readtotal:12756992 File REad:1024readtotal:12758016 File REad:322readtotal:12759040 Final File Read:-1 Final readtotal:12759362 文件长度:12767554&最后阅读总数:12759362 shud相等.我不明白为什么最后一个读数值较低[322],而它仍然可以有1024. 任何形式的帮助都值得赞赏. [编辑] //Client int read; int totalRead = 0; while ((read = is.read(mybytearray,mybytearray.length)) != -1) { bos.write(mybytearray,read); totalRead += read; System.out.println("nread:"+read+"ntotalread: "+totalRead); } System.out.println("Final File Read:"+read+" Final readtotal:"+totalRead); bos.write(mybytearray,read); //57 Line in FileClient.java bos.flush(); 我再次尝试发送文件.这次是一个txt. Sending... mybytearray length:1024file length:1232 File REad:1024readtotal:0 File REad:208readtotal:1024 Final File Read:-1 Final readtotal:1232 这个客户端 read:208 totalread: 1232 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException Final File Read:-1 Final readtotal:1232 at java.lang.System.arraycopy(Native Method) at java.io.BufferedOutputStream.write(Unknown Source) at FileClient.main(FileClient.java:57) readtotal值是相同的,但有时我得到这个错误,有时我没有. [大编辑 – 完整的客户代码] public class FileClient{ public static void main (String [] args ) throws IOException { long start = System.currentTimeMillis(); int bytesRead; int current = 0; final JFrame f = new JFrame("Sample"); f.getContentPane().setLayout(new FlowLayout()); f.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE); f.setSize(590,490); f.setVisible(true); // localhost for testing Socket sock = new Socket("localhost",13267); System.out.println("Connecting..."); File f1=new File(RecieveObject(sock)); // receive file byte [] mybytearray = new byte [1024]; InputStream is = sock.getInputStream(); FileOutputStream fos = new FileOutputStream(f1); ProgressMonitorInputStream nn= new ProgressMonitorInputStream(f,"reading",is); BufferedOutputStream bos = new BufferedOutputStream(fos); /* bytesRead = is.read(mybytearray,mybytearray.length); current = bytesRead; do { bytesRead = is.read(mybytearray,current,(mybytearray.length-current)); System.out.println("mybytesarray length: "+mybytearray.length+"ncurrent:"+current+"nbytesread: "+bytesRead); if(bytesRead >= 0) current += bytesRead; } while(bytesRead > -1); bos.write(mybytearray,current); bos.flush(); */ int read; int totalRead = 0; //InputStream clientInputStream = clientSocket.getInputStream(); while ((read = is.read(mybytearray,read); totalRead += read; System.out.println("nread:"+read+"ntotalread: "+totalRead); } System.out.println("Final File Read:"+read+" Final readtotal:"+totalRead); // bos.write(mybytearray,read); bos.flush(); long end = System.currentTimeMillis(); System.out.println(end-start); bos.close(); sock.close(); } public static String RecieveObject(Socket s) { String str = null; try{ ObjectInputStream is = new ObjectInputStream(s.getInputStream()); str =(String)is.readUTF(); } catch(IOException ex){} return str; } } 解决方法
由于你的第5行(包括评论),你错过了文件的开头(最多1024个字节).您从输入中读取并将其提前,而不将其发送到客户端.删除这个:
bis.read(mybytearray,mybytearray.length); 此外,您没有在循环中使用BufferedInputStream.在这里使用bis.read而不是fis.read(如果你仍然需要缓冲读取) – 或者一起删除BufferedInputStream. 你的另一个问题是你正在读取客户端上的最后一个字节,然后再次进入循环.再次调用is.read.而不是返回-1,它会抛出IOException,因为套接字的另一端已经关闭.因此,不会调用bos.flush()和bos.close(),并且您的最终字节永远不会写入磁盘.要解决此问题,请在关闭之前尝试调用sock.shutdownOutput.无论如何,你需要在此周围添加一些适当的异常处理. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |