简体   繁体   English

将Byte Array存储在Object中,然后将其转换为ObjectOutputStream? (卡住)

[英]Storing Byte Array inside an Object, and then converting it to ObjectOutputStream? (Stuck)

I'm kind of stuck with this problem. 我有点不解决这个问题。

I have this FileDetails class which stores details/metadata of the file along with the complete file in a byte array. 我有这个FileDetails类,它存储文件的详细信息/元数据以及字节数组中的完整文件。 I want to send the FileDetails object inside ObjectOutputStream across network, where the receiver will simple read the file and cast it back to FileDetails. 我想在ObjectOutputStream中跨网络发送FileDetails对象,接收器将简单地读取文件并将其强制转换回FileDetails。

Here is the code: 这是代码:

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);

The problem is that the file "test.dat" is quite large and it's not optimal to read it fully into the buffer(very large) in one go. 问题是文件“test.dat”非常大,并且一次性将其完全读入缓冲区(非常大)并不是最佳选择。 I could have read the file into the buffer in chunks, but that would require me to create file and save data into the disk, which I cannot do as FileDetails object takes byte array. 我本可以将文件读入块中的缓冲区,但这需要我创建文件并将数据保存到磁盘中,这是我无法做到的,因为FileDetails对象需要字节数组。

How can I solve this problem? 我怎么解决这个问题? I want this approach only, ie Storing data as byte array in FileDetails object and then converting it to ObjectOutputStream, because I will be appending the appending an mp3 file infornt of the ObjectOutStream file and sending it over the internet. 我只想要这种方法,即在FileDetails对象中将数据存储为字节数组,然后将其转换为ObjectOutputStream,因为我将附加一个附加了ObjectOutStream文件的mp3文件并通过互联网发送它。

Any suggetions? 任何建议? Or alternative approach? 或者替代方法?

Edit: Actually I am developing an android app. 编辑: 其实我正在开发一个Android应用程序。 Where it stores the metadata of the file in a FileDetails object along with the file data in byte array. 它将文件的元数据与字节数组中的文件数据一起存储在FileDetails对象中。 This FileDetails object is converted into an ObjectOutputStream file. 此FileDetails对象将转换为ObjectOutputStream文件。 Now an a specific mp3 file is appended in front of this ObjectOutputStream file, which is used to recognize that the file has been sent by my app. 现在,在此ObjectOutputStream文件前面附加了一个特定的mp3文件,该文件用于识别该文件已由我的应用程序发送。 This combined mp3 file (which contains "hidden" ObjectOutputStream file) is send via a "popular" message app to the receiver. 这个组合的mp3文件(包含“隐藏的”ObjectOutputStream文件)通过“流行的”消息应用程序发送到接收器。 The receiver downloads the mp3 file through his "popular" message app. 接收器通过他的“流行”消息应用程序下载mp3文件。 Now my app comes into action. 现在我的应用程序开始运作了。 It recognizes the mp3 file. 它识别mp3文件。 And extracts the ObjectOutputStream file from the mp3 file. 并从mp3文件中提取ObjectOutputStream文件。 And casts it back to FileDetails and retrieves the Original file with it's metadata. 然后将其转换回FileDetails并使用它的元数据检索原始文件。 Is my approach correct? 我的方法是否正确? Is there any other way to recognize my appended/hidden file? 有没有其他方法来识别我的附加/隐藏文件?

Thanks a lot in advance. 非常感谢提前。

Is it possible to add the class to the receiver? 是否可以将类添加到接收器? Then you could try something like this: 然后你可以尝试这样的事情:

File file = new File("C://test.dat")
InputStream in = null;
   try {
     in = new BufferedInputStream(new FileInputStream(file));
     -> send over the network
    finally {
     if (in != null) {
       in.close();
     }
   }
 }

the receiver could just write the byte to a temporary file (and not hold them in memory) 接收器可以将字节写入临时文件(而不是将它们保存在内存中)

InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream("C://test.dat");
BufferedOutputStream bos = new BufferedOutputStream(fos);
//something like:
byte[] buffer = new byte[1024];
int len = is.read(buffer);
while (len != -1) {
    bos.write(buffer, 0, len);
    len = is.read(buffer);
}

and if the operation is finished, instantiate the object FileDetails fd = new FileDetails(the file you just created,....) 如果操作完成,则实例化对象FileDetails fd = new FileDetails(the file you just created,....)

You can also send the class definition over network, if you must. 如果必须,您还可以通过网络发送类定义。

Here I've added read/writeObject methods: 这里我添加了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 {
  }
}

I've tested this with a short file: 我用短文测试了这个:

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

I'm not sure whether the receiver will be happy with some file being written according to a path name being sent in the message. 我不确定接收器是否满意根据消息中发送的路径名写入某个文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM