0

我通过 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;
}
4

1 回答 1

1

在您的接收器中,您有:

byte[] rFile = new byte[ (int) temp ];
input.read( rFile );

不能保证您会一口气获得所有这些字节。事实上,考虑到通过网络发送的大量字节,这不太可能。用于 read(byte[] b)状态的Javadocs :

从包含的输入流中读取一些字节并将它们存储到缓冲区数组中 b。实际读取的字节数以整数形式返回。

您想改用该readFully()方法。

byte[] rFile = new byte[ (int) temp ];
input.readFully(rFile);

这可以保证你的字节数组被完全填满,或者如果套接字在你收到那么多字节之前关闭,你会得到一个异常。

为完整性而编辑:但是请注意,如果您的长度超过Integer.MAX_VALUE您的长度,您真的会被冲洗掉。在这种情况下不太可能,但要记住一些事情。您可以不这样做,readFully()但您需要在循环中这样做,并使用返回的字节数作为后续调用的偏移量。这意味着int read(byte[] b, int off, int len)在循环中使用 read 方法。这很有用,例如,如果您想监视从套接字读取数据的进度。

于 2013-06-28T20:00:54.993 回答