简体   繁体   English

读取已分割为两个文件的Java序列化对象?

[英]Reading Java serialized object that has been split across two files?

I'm writing an Android application. 我正在写一个Android应用程序。 One problem is your app cannot contain a file whose uncompressed size is bigger than about 1Mb. 一个问题是您的应用程序不能包含未压缩大小大于1Mb的文件。 I have a serialized object that I want to load that totals about 2Mb. 我有一个序列化的对象,我想加载总共大约2Mb。 My plan was to split this file into two smaller files, then load the object by combining both files at runtime. 我的计划是将此文件拆分为两个较小的文件,然后通过在运行时组合这两个文件来加载对象。

However, I cannot work out how to use eg InputStream and ObjectInputStream to specify that I want to read the data from two input streams. 但是,我无法弄清楚如何使用例如InputStream和ObjectInputStream来指定我想从两个输入流中读取数据。 How can I do this? 我怎样才能做到这一点?

For example, say my object was split between file O1 and O2. 例如,假设我的对象在文件O1和O2之间分开。 How can I say "Load the object by reading the data from O1 then from O2"? 我怎么说“通过从O1读取数据然后从O2加载对象”?

As Tom Hawtin pointed out in the comments, you should be able to use Java's built-in SequenceInputStream class to deserialize an object that is split across multiple files. 正如Tom Hawtin在评论中指出的那样,您应该能够使用Java的内置SequenceInputStream类来反SequenceInputStream分割跨多个文件的对象。 This approach also allows you to deserialize an object split across any number of files, because SequenceInputStream 's constructor accepts two InputStream objects, one of which could be another SequenceInputStream . 此方法还允许您反序列化跨任意数量文件的对象,因为SequenceInputStream的构造函数接受两个InputStream对象,其中一个可能是另一个SequenceInputStream

I created a small example that should work on Android, although I have only tested it on a desktop Java installation. 我创建了一个应该在Android上运行的小例子,尽管我只在桌面Java安装上测试过它。 The example works on the assumption that you have serialized an object of type Foo and split the serialized version between two files names myobj.part1 and myobj.part2 . 该示例的工作原理是您已经序列化了Foo类型的对象,并将序列化版本拆分为两个文件名myobj.part1myobj.part2

The example is pretty self explanatory, but if you have any questions, please let me know. 这个例子非常自我解释,但如果您有任何疑问,请告诉我。

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.SequenceInputStream;

...

ObjectInputStream in = null;

try {
    in = new ObjectInputStream(
        new SequenceInputStream(
                new FileInputStream("myobj.part1"),
                new FileInputStream("myobj.part2")));

    Foo foo = (Foo) in.readObject();

    // Do something with the deserialized object...
    foo.doSomething();
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (in != null) {
        try { 
            in.close();
        } catch (IOException e) { }
    }
}

ObjectInputStream just takes the InputStream in its constructor, so clearly the task is implementing an InputStream concrete subclass that reads two files in sequence (rather than just one as FileInputStream does). ObjectInputStream只在其构造函数中获取InputStream ,因此很明显该任务是实现一个InputStream具体子类,它按顺序读取两个文件(而不是像FileInputStream那样只读取一个文件)。 Basically your concrete subclass must implement read(byte[]) by delegating to the first, then (when that's exhausted) the second one of two FileInputStream s it holds as attributes (pass them into your concrete subclass's constructor). 基本上你的具体子类必须通过委托给第一个来实现read(byte[]) ,然后(当它用尽时)它作为属性保存的两个FileInputStream的第二个(将它们传递给你的具体子类的构造函数)。

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

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