[英]how to write very long string to a gzip file in java
我有一个很长的字符串,想写入一个 gzip 文件
我尝试使用GZIPOutputStream
编写一个 gzip 文件
但是当我使用string.getBytes()
时哪里有异常
java.lang.OutOfMemoryError: Requested array size exceeds VM limit
at java.lang.StringCoding.encode(StringCoding.java:350)
at java.lang.String.getBytes(String.java:941)
有我的代码,我该怎么做才能成功写入文件?
public static void way1() throws IOException {
String filePath = "foo";
String content = "very large string";
try (OutputStream os = Files.newOutputStream(Paths.get(filePath));
GZIPOutputStream gos = new GZIPOutputStream(os)) {
gos.write(content.getBytes(StandardCharsets.UTF_8));
}
}
public static void way2() throws IOException {
String filePath = "foo";
String content = "very large string";
try (OutputStream os = Files.newOutputStream(Paths.get(filePath));
GZIPOutputStream gos = new GZIPOutputStream(os);
WritableByteChannel fc = Channels.newChannel(gos)) {
fc.write(ByteBuffer.wrap(content.getBytes(StandardCharsets.UTF_8)));
}
}
似乎当您将 String 转换为 byte[](使用 content.getBytes(StandardCharsets.UTF_8))时,byte[] 只需要大量的 memory。 而不是立即将完整的 String 转换为 byte[] 使用选择的编码从它创建一个 ByteBuffer,然后将此 ByteBuffer 写入 GZIPOutputStream,这样您将至少将所需的 memory 大小降低一半。 要创建 ByteBuffer,您可以使用:
Charset charset = StandardCharsets.UTF_8;
String content = "very large string";
ByteBuffer byteBuffer = charset.encode(content );
API of ByteBuffer: https://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html And this might be usefull: How to put the content of a ByteBuffer into an OutputStream?
或者,您还可以为 java 堆增加 memory 的数量: 增加 Java 中的堆大小
所有这些都与您的方式非常相似,就像这样(我没有测试过)
public static void way2() throws IOException {
String filePath = "foo";
String content = "very large string";
try (OutputStream os = Files.newOutputStream(Paths.get(filePath));
GZIPOutputStream gos = new GZIPOutputStream(os);
WritableByteChannel fc = Channels.newChannel(gos)) {
Charset charset = StandardCharsets.UTF_8;
ByteBuffer byteBuffer = charset.encode(content );
fc.write(byteBuffer );
}
}
如果您有ResultSet
,请尝试以下操作:
public static void string2Zipfile(ResultSet rs, int columnIndex, Path outputFile) throws SQLException, IOException {
try (InputStream os = rs.getBinaryStream(columnIndex)) {
try (GZIPOutputStream gos = new GZIPOutputStream(Files.newOutputStream(outputFile))) {
os.transferTo(gos);
}
}
}
我使用@Chaosfire 建议,像这样编辑代码,它成功写入文件
public static void way1() throws IOException {
String filePath = "foo";
List<String> originContent = new ArrayList<>();
try (OutputStream os = Files.newOutputStream(Paths.get(filePath));
GZIPOutputStream gos = new GZIPOutputStream(os)) {
Lists.partition(originContent, 1000000).stream().map(part -> String.join("\r\n", part)).forEach(str -> {
try {
gos.write(str.getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
throw new RuntimeException(e);
}
});
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.