Data loss in file transfer – Java?
I have a fileserver and a fileclient. The server sends files when the client connects This is a simple program, just to understand the concept behind it
I can send files from the server to the client with a buffer of 1024 The problem is that the received file is always about 0.01 MB less than the original file Therefore, MP3 files lose some information, and video files cannot be played
I put some prinln statements in the while loop of the server and amplifier customer. I found that my server did not send the entire file
//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 statement output is:
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
File length: 12767554 & total number of last reads: 12759362 shud equal I don't understand why the last reading value is low [322], and it can still have 1024
Any form of help is commendable thank you.
[Edit]
//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();
I tried to send the file again This is a TXT This is the output of my server
Sending... mybytearray length:1024file length:1232 File REad:1024readtotal:0 File REad:208readtotal:1024 Final File Read:-1 Final readtotal:1232
This client
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)
The readtotal value is the same, but sometimes I get this error, sometimes I don't
[major editor – complete customer code]
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; }
}
Solution
Because of your line 5 (including comments), you missed the beginning of the file (up to 1024 bytes) You read from the input and advance it without sending it to the client Delete this:
bis.read(mybytearray,mybytearray.length);
In addition, you do not use bufferedinputstream. In the loop Use bis here Read instead of FIS Read (if you still need to buffer reads) – or delete bufferedinputstream together
Your other problem is that you are reading the last byte on the client and entering the loop again Call is again read. Instead of returning - 1, it throws an IOException because the other end of the socket is closed Therefore, bos.com will not be called Flush() and BOS Close() and your final bytes will never be written to disk To fix this problem, try calling sock. Before shutting down shutdownOutput. Anyway, you need to add some appropriate exception handling around here