我需要使用一个包含字符串、字符串对的大文件,并且因为我想将它与 JAR 一起发送,所以我选择在应用程序的资源文件夹中包含一个序列化和 gzip 压缩的版本。这就是我创建序列化的方式:
ObjectOutputStream out = new ObjectOutputStream(
new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream(OUT_FILE_PATH, false))));
out.writeObject(map);
out.close();
我选择使用 HashMap<String,String>
,生成的文件为 60MB, map 包含大约 400 万个条目。
现在,当我需要 map 时,我使用以下方法对其进行反序列化:
final InputStream in = FileUtils.getResource("map.ser.gz");
final ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new GZIPInputStream(in)));
map = (Map<String, String>) ois.readObject();
ois.close();
这大约需要 10~15 秒。有没有更好的方法将这么大的 map 存储在 JAR 中?我问是因为我还使用 Stanford CoreNLP 库,它本身使用大模型文件,但在这方面似乎表现更好。我试图找到读取模型文件的代码但放弃了。
最佳答案
你的问题是你压缩了数据。将其存储为纯文本。
性能下降很可能是在解压缩流时。 Jars 已 压缩,因此存储压缩文件不会节省空间。
基本上:
- 以纯文本格式存储文件
- 使用
Files.lines(Paths.get("myfilenane.txt"))
流式传输行 - 使用最少的代码消费每一行
像这样,假设数据的形式是 key=value
(就像一个 Properties 文件):
Map<String, String> map = new HashMap<>();
Files.lines(Paths.get("myfilenane.txt"))
.map(s -> s.split("="))
.forEach(a -> map.put(a[0], a[1]));
免责声明:代码可能无法像在我手机上输入的那样编译或工作(但很有可能会工作)
关于Java:在资源中存储一张大 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37948161/