我通过TCP将文件从一个Android设备发送到另一个。当我试图发送一个MP3文件。 它收到成功。但文件已损坏。 (我在目标设备中获得了完全相同的文件大小) 我的收件人
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();
发件人
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;
}
答案 0 :(得分:1)
在你的接收器中你有:
byte[] rFile = new byte[ (int) temp ];
input.read( rFile );
无法保证您可以一次性获取所有这些字节。实际上,由于通过网络发送大量字节,因此不太可能。 Javadocs for read(byte[] b)州:
从包含的输入流中读取一些字节数并将它们存储到缓冲区数组b中。实际读取的字节数以整数形式返回。
您想要使用readFully()
方法。
byte[] rFile = new byte[ (int) temp ];
input.readFully(rFile);
这可以保证您的字节数组完全填满,或者如果套接字在收到那么多字节之前关闭,则会出现异常。
编辑完整性:但是,请注意,如果您的长度超过Integer.MAX_VALUE
,那么您确实已经开了。在这种情况下不太可能需要记住。 可以在没有readFully()
的情况下执行此操作,但您需要在循环中执行此操作,并使用返回的字节数作为后续调用的偏移量。这意味着在循环中使用int read(byte[] b, int off, int len)
read方法。例如,如果要监视从套接字读取数据的进度,这很有用。