繁体   English   中英

如何将很长的字符串写入 java 中的 gzip 文件

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM