【问题标题】:Saving large short array android保存大型短数组android
【发布时间】:2013-08-09 04:30:03
【问题描述】:

我基本上是在寻找一种在 Android 上以快速的方式保存和重新加载一些大型数组(大约 500 万 short)的方法。我的应用程序需要以一种我可以稍后再使用它们的方式保存它们,所以我不能只将它们保存在内存中......

到目前为止,我已经尝试将它们转换为byte[] 数组,它们似乎保存成功,但我无法取回数据,这就是我保存代码的工作方式(实际上是分离函数,简化这里):

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOuputStream oos = new ObjectOutputStream(baos);
oos.writeObject(data);
oos.close();
baos.close();
FileOutputStream fos = new FileOutputStream(filename); // valid absolute path
fos.write(baos.toByteArray());
fos.close();

加载部分是我卡住的地方,我如何从byte[] 获得short[]? 我还读到数据库也可以工作,但它足够快吗?

我环顾了 Stackoverflow 和 Google,似乎找不到有类似问题的人,或者至少找不到解决方案,但作为初学者,我可能错过了一些明显的东西......

【问题讨论】:

    标签: java android serialization io


    【解决方案1】:

    如果datashort[] 并且您想将整个内容写入文件,请不要使用内存中的缓冲区,直接写入。

    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename));
    try {
        oos.writeObject(data);
    } finally {
        oos.close();
    }
    

    如果您通过ObjectOutputStream 编写它,则必须通过ObjectInputStream 读取它,因为它不仅写入纯数据,还写入一些类型信息。如果你输入一个short[],你会得到一个short[](你可以尝试跳过这些字节,但你必须分析流实际写入的内容)。如果您的 ObjectOutputStream 写入 ByteArrayOutputStream,这也适用。

    如果您不想处理这种混乱,请执行ObjectOutputStream 的基本操作:

    DataOutputStream dos = new DataOutputStream(new FileOutputStream(filename));
    try {
        for (int i = 0; i < data.length; i++) {
            dos.writeShort(data[i]);
        }
    } finally {
        dos.close();
    }
    

    DataOutputStream 写入纯数据,因此您可以根据需要直接以byte[] 的形式读取数据。如果字节顺序很重要:它使用的是 Big-Endian。


    由于这种方法写入单个字节而不是 byte[] 的卡盘,因此在两者之间使用 BufferedOutputStream 会受益。默认使用 8kB 缓冲区,但可以增加它可以提供更好的结果。写入数据现在会将内存中的short 转换为bytes,一旦有足够的数据可用,整个块将被推送到低级操作系统函数来写入。

    int bufferSize = 32 * 1024;
    DataOutputStream dos = new DataOutputStream(
            new BufferedOutputStream(
                    new FileOutputStream(filename),
                    bufferSize)
            );
    try {
        for (int i = 0; i < data.length; i++) {
            dos.writeShort(data[i]);
        }
    } finally {
        dos.close();
    }
    

    【讨论】:

    • 使用您和@dst 的答案似乎可以工作,至少对于输出而言,但大约需要 13 秒?这么长有什么原因吗?
    • 尝试在文件和数据流之间放置一个BufferedOutputStream。您可能正在编写非常缓慢的单个元素。
    • 我使用的是您的第一个代码,缓冲区仍然需要 13 秒。我将尝试使用缓冲区的第二个,看看是否可以修复它。
    • 如果我放弃使用DataOutputStream的灵活性,它需要11秒,所以我想我会坚持原来的OOS。但是大约 500 万条短裤花时间在手机上写字是正常的吗?
    • @NiBr 不是 new DataOutputStream(new BufferedOutputStream(new FileOutputStream(filename))) 帮忙吗?不幸的是,Java 中的值转换非常慢,因为它实际上是在移动和位操作每一件事。低级语言可以简单地以所需方式解释内存,并在一个短数组上逐字节迭代。
    【解决方案2】:

    直接使用文件流,无需通过ByteArrayOutputStream / ByteArrayInputStream 进行缓冲。 byte[] 保存在内存中,不适用于大量数据。

    写入new ObjectOutputStream(new FileOutputStream(filename)),您可以使用new ObjectInputStream(new FileInputStream(filename)) 取回您的对象。如果你愿意,你也可以像Christopher's answer中提到的那样做一些缓冲。

    【讨论】:

      【解决方案3】:

      您可能可以在这里使用该方法:byte array to short array and back again in java,然后只写入和读取字节数组。我还建议使用 BufferedOutputStream 而不仅仅是 FileOutputStream。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多