gpt4 book ai didi

java - 我需要 ByteArrayInputStream 的读取缓冲区吗

转载 作者:行者123 更新时间:2023-11-30 03:01:16 28 4
gpt4 key购买 nike

我有一个 JPA AttributeConverter,用于将 String 转换为 gzipped byte[] 并返回。

转换方法相当简单:

public byte[] convertToDatabaseColumn(String attribute) {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gos = new GZIPOutputStream(baos)) {

gos.write(attribute.getBytes(StandardCharsets.UTF_8));
gos.finish();
gos.flush();

return baos.toByteArray();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

我的问题是关于转换方法:

public String convertToEntityAttribute(byte[] dbData) {
try (GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(dbData));
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {

byte[] buffer = new byte[1024];

int len;
while ((len = gis.read(buffer)) > 0) {
baos.write(buffer, 0, len);
}

return new String(baos.toByteArray(), StandardCharsets.UTF_8);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

鉴于字节数组dbData已经在内存中,那么缓冲区中还有什么点吗?直接逐字节读入 baos 完全跳过 buffer 不是更“性能”吗?

如果读取方法正在进行底层操作系统调用,则缓冲区是有意义的,但它不在这里......

最佳答案

Given that the byte array dbData is already in memory, is there any point in the buffer?

缓冲区用于提高性能。与一次读取一个字节相比,它们通常确实可以提高性能,这是这里唯一的选择。

Is it not more "performant" to read byte-by-byte straight into the baos skipping the buffer altogether?

您的 baos 中的字节已被压缩,如果您可以读取这些字节,则您不会使用 GZIPInputStream。

<小时/>

如果您想要效率和简单性,我建议您直接从 ByteArrayInput/OutputStream 读取/写入,而不使用 byte[]。

public byte[] convertToDatabaseColumn(String text) {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
Writer out = new OutputStreamWriter(
new GZIPOutputStream(baos), StandardCharsets.UTF_8))) {
out.write(text);
out.close();
return baos.toByteArray();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

public String convertToEntityAttribute(byte[] dbData) {
try (Reader reader = new InputStreamReader(
new GZIPInputStream(new ByteArrayInputStream(dbData)),
StandardCharsets.UTF_8) {

char[] chars = new char[512];
StringBuilder sb = new StringBuilder();
for (int len; (len = reader.read(chars)) > 0;)
sb.append(chars, 0, len);

return sb.toString();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

为了简化这一点,假设您的字符串不包含换行符,您可以这样做

public static byte[] convertToDatabaseColumn(String text) throws IOException {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
Writer out = new OutputStreamWriter(
new GZIPOutputStream(baos), StandardCharsets.UTF_8)) {
out.write(text);
out.write("\n");
out.close();
return baos.toByteArray();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

public static String convertToEntityAttribute(byte[] dbData) throws IOException {
try (BufferedReader br = new BufferedReader(
new InputStreamReader(
new GZIPInputStream(new ByteArrayInputStream(dbData)),
StandardCharsets.UTF_8))) {

return br.readLine();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

public static void main(String[] args) throws IOException {
byte[] bytes = convertToDatabaseColumn("Hello world, 0123456789 0123456789");
System.out.println(convertToEntityAttribute(bytes));
}

关于java - 我需要 ByteArrayInputStream 的读取缓冲区吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35873978/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com