【发布时间】:2010-12-02 23:17:50
【问题描述】:
我计划将一组数字存储在一个文件中,并在需要时读取它。什么是这样做的好方法?我可以想到一些方法,例如将一行中的每个元素存储为文本文件或将其序列化并通过该方法存储/调用。速度是我最关心的问题。
谢谢
【问题讨论】:
标签: java arrays file serialization
我计划将一组数字存储在一个文件中,并在需要时读取它。什么是这样做的好方法?我可以想到一些方法,例如将一行中的每个元素存储为文本文件或将其序列化并通过该方法存储/调用。速度是我最关心的问题。
谢谢
【问题讨论】:
标签: java arrays file serialization
如果文件不需要是人类可读的,那么序列化它将是更好的方法性能明智。 如果要将每个数组条目保存为文件中的一行,则需要遍历数组, 做一些 IO,保存文件,稍后将其恢复为完全相同的数组,您需要反向执行所有这些步骤。 此外,IO 操作相当昂贵。
内置的序列化机制可以为您完成所有这些工作,并且可以说是以最有效的方式。
【讨论】:
new ObjectOutputStream(new FileOutputStream("s")).writeObject(new ArrayList());
文件已保存。
【讨论】:
在这种情况下,速度是次要问题。为什么?因为您正在读取文件无论如何,而 I/O 慢(与内存中的操作相比)。我只会每行存储一个数字,以便人类可读。
【讨论】:
如果速度是您最关心的问题,请使用 DataOutputStream 和 DataInputStream 以二进制形式对其进行序列化。 类似:
public void write(DataOutput dout, int arr[]) throws IOException
{
dout.writeInt(arr.length);
for(int a : arr) dout.writeInt(a);
}
public int[] readArray(DataInputStream din) throws IOException
{
int arr[] = new int[din.readInt()];
for(int i=0;i<arr.length;i++)
arr[i] = din.readInt();
return arr;
}
如果这还不够快,请考虑使用IntBuffer 进行批量操作。
二进制形式的优点是:
【讨论】:
如果您只想存储一个数字数组,那么编写您自己的手动序列化/反序列化例程就可以了。它会教你一些关于 IO 操作的知识。
当您处理更复杂的类型(甚至是字符串)时,从长远来看,使用内置的序列化方法可能会为您提供更好的服务,因为它们对于绝大多数用例来说通常更可靠。
虽然我不是 Java 开发人员,但在 Java 中使用序列化看起来相当简单。 Sun 似乎对 Java 序列化有很好的介绍。
http://java.sun.com/developer/technicalArticles/Programming/serialization/
【讨论】:
没有足够的关于您的用例的信息来了解最佳的方法速度。 (这将是多线程的,多久执行一次,数组的大小是多少以及类似的问题)。
话虽如此,唯一真正了解的方法是分析他们。序列化很简单,每行写一个数字也很简单,所以你可以试试这两个,在你需要的场景类型中分析它们,看看哪个更快,看看它们中的任何一个是否达到了你的性能目标。
【讨论】:
一种新颖的方法:如果您的数字数组是唯一整数,您可以将它们写为运行长度编码的“位集”。这将给出一个非常紧凑的表示,意味着更少的 I/O。我建议使用这种方法来存储非常大的唯一整数数组。
例如,假设您的数组包含值[1 ,2 ,3 ,5 ,9],您的位集将如下所示:
[1, 0, 0, 0, 1, 0, 1, 1, 1]
...您的 RLE 编码位集将是:
013113
... 解释为“0 个零、1 个一、3 个零、1 个一等”。
您可以选择将 RLE 编码的字符串保留为字符或使用二进制格式。
【讨论】:
这可能有点矫枉过正,但您可能还需要考虑 JSON 如何巧妙地处理其键:值、基于数组的数据。 您可以将这样的数组保存到单个文件中 { “我的阵列”:{ “1”:“[0 1 2 3 4 5]” “2”:“[0 1 2 3 4 5]”
"n" : "[0 1 2 3 4 5]"
}
}
要检索数组,读取文件内容并将它们存储在 StringBuffer 中,将它们序列化(例如 net.sf.json.JSONSerializer)成 JSON 对象并方便地遍历每组数组。
【讨论】:
遵循序列化是最好的方法。但是,如果您关心的是速度序列化不是正确的选择。 (序列化性能很差)。
【讨论】: