1

我有一个程序,我生成一个巨大的矩阵,一旦计算出来,我必须在以后重用它。出于这个原因,我想将它缓存到本地硬盘,以便以后可以读取它。我只是通过将数据写入文件然后再读取它来使用它。

但是,在 java 中执行此类任务时,我应该考虑什么特别之处。例如,我是否需要对其进行序列化或者可能会做一些特别的事情。在存储重要的应用程序使用数据的地方,我是否应该注意做这些事情。它应该是纯 ASCII/xml 还是什么?
数据不敏感,但数据的完整性很重要。

4

5 回答 5

2

您有几种存储数据的选项。您可以尝试简单地在标题中说明宽度是多少,然后将所有内容放入带有分隔符的列表中(例如,,,'\n''\t'' '。否则,您可以使用特殊的 ObjectOutputStream 来存储数据。请注意:这可能比您的解决方案效率低下。但是,它会更容易使用。

除此之外,您可以自由选择。我通常使用 FileWriter 并以纯文本形式写入所有数据。如果您追求超高效率,那么 FileOutputStream 就是您所需要的。

于 2011-06-26T16:46:45.210 回答
2

如果您的数据真的很大,我会推荐一些二进制形式——这将使它更小、更快地读取,尤其是解析(XML 或 JSON 比读取/写入二进制数据慢很多倍)。序列化也会带来很多开销,因此您可能需要检查 DataInputStream 和 DataOutputStream。如果您知道您将只编写特定类型的数字,或者您知道数据的顺序 - 这些肯定是最快的。

不要忘记用缓冲流包装文件流 - 它们将使您的操作速度更快一个数量级。

类似的东西(8192 是示例缓冲区大小 - 您可以根据需要对其进行调整):

    final File file = null; // get file somehow
    final DataOutputStream dos = new DataOutputStream(
       new BufferedOutputStream(new FileOutputStream(file), 8192));
    try {
        for (int x: ....) { //loop through your matrix (might be different if matrix is sparse)
           for (int y: ....) {
               if (matrix[x,y] != 0.0) {
                   dos.writeInt(x);
                   dos.writeInt(y);
                   dos.writeDouble(matrix[x,y]);                                     
               } 
           }
        }
     } finally {
       dos.writeInt(-1); // mark end (might be done differently)
       dos.close();
     }

并输入:

    final File file = null; // get file somehow
    final DataInputStream dis = new DataInputStream(
      new BufferedInputStream(new FileInputStream(file), 8192));
    try {
        int x;
        while((x = dis.readInt()) != -1) { 
           int y = dis.readInt();
           double value = dis.readDouble();
           // store x,y, value in matrix
        } 
    } finally {
       dis.close();
    }

正如 Ryan Amos 正确指出的那样,如果矩阵不是稀疏的,只写值(但所有值)可能会更快:

出去:

    dos.write(xSize);
    dos.write(ySize);
    for (int x=0; x<xSize; x++) {
        for (int y=0; y<ySize; y++) {
            value = matrix[x,y];
            dos.write(value);
        }
    }

在:

   int xSize = dis.readInt();
   int ySize = dis.readInt();
   for (int x=0; x<xSize; x++) {
        for (int y=0; y<ySize; y++) {
              double value = dis.readDouble();
              matrix[x,y] = value;
        }
   }

(请注意我没有编译它 - 所以你可能需要更正一些东西 - 它不在我的脑海中)。

如果没有缓冲区,您将逐字节读取,这将使其变慢。

还有一条评论 - 对于如此庞大的数据集,您应该考虑使用 SparseMatrix 并仅写入/读取非零元素(除非您确实拥有那么多重要元素)。

正如上面评论中所写 - 如果您真的想写入/读取该大小矩阵中的每个元素,那么您已经在谈论写入时间而不是几秒钟。

于 2011-06-26T16:50:00.780 回答
1

如果您的条目是数字,那么您可以将矩阵的每一行保存为文件中的一行,由一些分隔符分隔。那么你不需要特殊的序列化。:)

于 2011-06-26T16:44:46.500 回答
1

这完全取决于您稍后将如何输出它,或者您是否还将它存储在数据库或其他地方。如果您从不输出它或将其存储在其他任何地方,那么文本文件就可以了。

于 2011-06-26T16:47:27.367 回答
1

如果不需要持久化数据(即在 java 程序终止后保留它),将它保存在内存中的 Java 变量中会更快。有很多类型可以满足您的要求(hashmap、arraylist...)。如果您需要保留数据以在后续程序执行中使用它,您可以使用标准文件读/写方法将其存储在文件中。纯 ASCII 比 XML 读/写更快。关于文件的完整性,它与操作系统相关,因为 - 最后 - 这将是本地文件系统上的文件。

于 2011-06-26T16:48:59.083 回答