Reputation: 2934
I am sending file over TCP from one android device to other. when I tried to send a mp3 file.
It received successfully. but the file got corrupted. (I've got the exactly the same size of file in target device).
My receiver is
input = new DataInputStream( clientSocket.getInputStream());
output =new DataOutputStream( clientSocket.getOutputStream());
int fileLength = input.readInt();
System.out.println("test integer recived"+fileLength);
String actualFileName = "";
for(int i=0;i<fileLength;i++){
actualFileName =actualFileName+input.readChar();
}
Log.d(loggerTag,"file is going to be recieved"+actualFileName );
File file =new File("/*my file location*/"+actualFileName);
Log.d(loggerTag,"file is going to be saved at"+file.getAbsolutePath() );
long temp = input.readLong();
byte[] rFile = new byte[ (int) temp ];
input.read( rFile );
FileProcess.makeFile(, rFile);
FileOutputStream outStream = new FileOutputStream(file.getAbsolutePath());
outStream.write( rFile);
Log.d(loggerTag, "file success fully recived");
outStream.close();
Sender Is
s = new Socket(IP, serverPort);
DataInputStream input = new DataInputStream( s.getInputStream());
DataOutputStream output = new DataOutputStream( s.getOutputStream());
String actualFileName = StringUtil.getFileName(fileName);
output.writeInt(actualFileName.length());
Log.d(loggerTag, "sending file name");
for(int i =0;i<actualFileName.length();i++){
output.writeChar(actualFileName.charAt(i));
}
File file = new File(fileName);
Log.d(loggerTag, "file going to send"+fileName);
output.writeLong(file.length() );
output.write( FileProcess.getBytes( file ) );
Log.d(loggerTag, "file sending finshed");
public static byte[] getBytes( File path ) throws IOException {
InputStream inStream = new FileInputStream( path );
long length = path.length();
byte[] file = new byte[ (int) length ];
int offset = 0, numRead = 0;
while ( offset < file.length && ( numRead = inStream.read( file, offset, file.length - offset ) ) > -1 ) {
offset += numRead;
}
if (offset < file.length) {
throw new IOException( "Error: A problem occurs while fetching the file!" );
}
inStream.close();
return file;
}
Upvotes: 0
Views: 1333
Reputation: 76888
In your receiver you have:
byte[] rFile = new byte[ (int) temp ];
input.read( rFile );
There is no guarantee you're going to get all those bytes in one go. In fact, it's very unlikely given a large number of bytes sent over a network. The Javadocs for read(byte[] b) state:
Reads some number of bytes from the contained input stream and stores them into the buffer array b. The number of bytes actually read is returned as an integer.
You want to use the readFully()
method instead.
byte[] rFile = new byte[ (int) temp ];
input.readFully(rFile);
This guarantees your byte array is completely filled, or you get an exception if the socket closes before you receive that many bytes.
Edit for completeness: Note, however, that if your length exceeds Integer.MAX_VALUE
you're really hosed. Unlikely in this case but something to remember. You can do this without readFully()
but you need to do so in a loop and use the returned number of bytes as the offset for subsequent calls. This means using the int read(byte[] b, int off, int len)
read method in the loop. This is useful, for example, if you wanted to monitor progress of reading the data from the socket.
Upvotes: 1