简体   繁体   中英

data loss in file transfer - JAVA?

i have a FileServer and a FileClient, server sends a file, when client connects. it is a simple program, just to understand the concept behind.

I am able to send the file from Server to Client, with a buffer of 1024. The problem is that the recieved file is always around 0.01 MB less than the original file.Thus mp3 files lose some info, and video files just doesn't play.

I put some prinln statements in my while loops in both Server & Client. i found that my server is not sending the whole file.

  //Server
  byte [] mybytearray  = new byte [1024];    
  FileInputStream fis = new FileInputStream(myFile);
  BufferedInputStream bis = new BufferedInputStream(fis);
  bis.read(mybytearray,0,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,0,mybytearray.length)) != -1) { 

      os.write(mybytearray, 0, 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();
  } 

The 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

The file length:12767554 & Last readTotal: 12759362 shud be equal. i don't understand why the last read value is lower [322], while it can still have 1024.

Any kind of help wud be appreciated. Thanks.

[EDIT]

//Client
int read;
int totalRead = 0;

while ((read = is.read(mybytearray,0,mybytearray.length)) != -1) {
        bos.write(mybytearray, 0 , read);

        totalRead += read;
        System.out.println("\nread:"+read+"\ntotalread: "+totalRead);
}
System.out.println("Final File Read:"+read+" Final readtotal:"+totalRead);
bos.write(mybytearray, 0 , read);  //57 Line in FileClient.java
bos.flush();

i again tried to send a file. a txt this time. this is my server's output

Sending...
mybytearray length:1024file length:1232
File REad:1024readtotal:0
File REad:208readtotal:1024
Final File Read:-1 Final readtotal:1232

and this one on 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)

readtotal values are same, but sometimes i get this error, sometimes i don't.

[BIG EDIT--COMPLETE CLIENT 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,0,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, 0 , current);
bos.flush();
 */
int read;
int totalRead = 0;
//InputStream clientInputStream = clientSocket.getInputStream();
while ((read = is.read(mybytearray,0,mybytearray.length)) != -1) {
        bos.write(mybytearray, 0 , read);

        totalRead += read;
        System.out.println("\nread:"+read+"\ntotalread: "+totalRead);
}
System.out.println("Final File Read:"+read+" Final readtotal:"+totalRead);
 //   bos.write(mybytearray, 0 , 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;
}   

}

You're missing the beginning of the file (up to the first 1024 bytes), due to your 5th line (including the comment). You read from the input and advanced it, without sending it to the client. Remove this:

bis.read(mybytearray,0,mybytearray.length);

Additionally, you're not using the BufferedInputStream in your loop. Either use bis.read here instead of fis.read (if you still want buffered reads) - or remove the BufferedInputStream all together.

Your other problem is that you're reading the final bytes on the client, then entering the loop once more. is.read is again called. Instead of returning -1, it's throwing an IOException as the other side of the socket has been closed. As such, bos.flush() and bos.close() aren't getting called, and your final bytes are never written to disk. To assist with this, try calling sock.shutdownOutput before closing it. Regardless, you'll want to add some proper exception handling around this.

byte [] mybytearray  = new byte [1024];    
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
OutputStream os = sock.getOutputStream();
System.out.println("Sending...\n mybytearray length:"+mybytearray.length+"filelength:"+(int)myFile.length());
int read, readTotal=0;
while ((read = bis.read(mybytearray,0,mybytearray.length)) != -1) { 
    os.write(mybytearray, 0, 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();
} 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM