在android中通过TCP发送文件时损坏

时间:2013-06-28 19:11:28

标签: java android file-io tcp

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

1 个答案:

答案 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方法。例如,如果要监视从套接字读取数据的进度,这很有用。