我有点困扰这个问题。
我有这个FileDetails类,它存储文件的详细信息/元数据以及
字节数组中的完整文件。我想跨网络发送ObjectOutputStream中的FileDetails对象,接收者将在其中
简单地读取文件并将其投射回FileDetails。
这是代码:
class FileDetails {
private String fileName;
private long fileSize;
private byte[] fileData;
public FileDetails(String fileName, long fileSize, byte[] fileData) {
this.fileName = fileName;
this.fileSize = fileSize;
this.fileData = fileData;
}
public String getFileName() {
return fileName;
}
public long getFileSize() {
return fileSize;
}
public byte[] getFileData() {
return fileData;
}
}
File file = new File("C://test.dat");
RandomAccessFile randFileAccess = new RandomAccessFile(file, "r");
byte[] buff = new byte[(int) file.length()];
randFileAccess.readFully(buff);
FileDetails fd = new FileDetails(file.getname(), file.length(); buff);
FileOutputStream fos = = new FileOutputStream(C://oos.dat);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(fd);
oos.write(buff);
问题在于文件“test.dat”非常大,一次性将其完全读入缓冲区(很大)并不是最佳选择。我本来可以读
将文件分块地放入缓冲区,但这需要我创建文件并将数据保存到磁盘中,而FileDetails对象需要字节数组,所以我不能这样做。
我怎么解决这个问题?我只想要这种方法,即将数据作为字节数组存储在FileDetails对象中,然后将其转换为ObjectOutputStream,因为我将追加
附加ObjectOutStream文件的mp3文件信息并通过Internet发送。
有什么建议吗?还是替代方法?
编辑:实际上,我正在开发一个android应用程序。它在FileDetails对象中存储文件的元数据以及字节数组中的文件数据。
此FileDetails对象将转换为ObjectOutputStream文件。现在,在此ObjectOutputStream文件的前面附加了一个特定的mp3文件,该文件用于识别该文件已由我的应用发送。
该组合的mp3文件(包含“隐藏的” ObjectOutputStream文件)通过“流行”消息应用程序发送到接收器。
接收器通过其“流行”消息应用程序下载mp3文件。现在,我的应用开始生效。它可以识别mp3文件。并从mp3文件中提取ObjectOutputStream文件。并将其投射回FileDetails,并使用元数据检索原始文件。
我的方法正确吗?还有其他方法可以识别我的附加/隐藏文件吗?
非常感谢。
最佳答案
在这里,我添加了read / writeObject方法:
class FileDetails implements Serializable {
private static final int CHUNK_LEN = 0x10000; // 64k
private String fileName;
private long fileSize;
private File file;
// Note: everything can be deduced from a File object
public FileDetails(File file) {
this.fileName = file.getName();
this.fileSize = file.length();
this.file = file;
}
public String getFileName() {
return fileName;
}
public long getFileSize() {
return fileSize;
}
// explicit coding for reading a FileDetails object
private void readObject(ObjectInputStream stream)
throws IOException, ClassNotFoundException {
fileName = stream.readUTF(); // file name
fileSize = stream.readLong(); // file size
// file data as a series of byte[], length CHUNK_LEN
long toRead = fileSize;
// write file data to a File object, same path name
file = new File( fileName );
OutputStream os = new FileOutputStream( file );
while( toRead > 0 ){
// last byte arrays may be shorter than CHUNK_LEN
int chunkLen = toRead > CHUNK_LEN ? CHUNK_LEN : (int)toRead;
byte[] bytes = new byte[chunkLen];
int nread = stream.read( bytes );
// write data to file
os.write( bytes, 0, nread );
toRead -= nread;
}
os.close();
}
// explicit coding for writing a FileDetails object
private void writeObject(ObjectOutputStream stream)
throws IOException {
stream.writeUTF( fileName ); // file name as an "UTF string"
stream.writeLong( fileSize ); // file size
// file data as a series of byte[], length CHUNK_LEN
long toWrite = fileSize;
// read file data from the File object passed to the constructor
InputStream is = new FileInputStream( file );
while( toWrite > 0 ){
// last byte[] may be shorter than CHUNK_LEN
int chunkLen = toWrite > CHUNK_LEN ? CHUNK_LEN : (int)toWrite;
byte[] bytes = new byte[chunkLen];
int nread = is.read( bytes );
stream.write( bytes );
toWrite -= nread;
}
is.close();
}
private void readObjectNoData()
throws ObjectStreamException {
}
}
我已经用一个简短的文件对此进行了测试:
File file = new File( "test.dat" );
FileDetails fd = new FileDetails( file );
FileOutputStream fos = new FileOutputStream("oos.dat");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject( fd );
oos.close();
// test on a local system: rename test.dat to avoid overwriting
file.renameTo( new File( "test.dat.sav" ) );
FileInputStream fis = new FileInputStream("oos.dat");
ObjectInputStream ois = new ObjectInputStream(fis);
FileDetails fd1 = (FileDetails)ois.readObject();
ois.close();
// now the file test.dat has been rewritten under the same path,
// i.e., test.dat exists again and test.dat.sav == test.dat
我不确定接收者是否愿意根据消息中发送的路径名写入某些文件。