gpt4 book ai didi

java - JS和Java中相同图像的不同Base64字符串

转载 作者:行者123 更新时间:2023-11-28 23:56:53 25 4
gpt4 key购买 nike

我正在开发一个在 Apache Tomcat 上运行的网络应用程序。此 webapp 从相机创建图像并将其 base64 编码发送到 Servlet。然后 servlet 应该保存该图像。一切正常,除了当我打开图像时图像显示不完整。我比较了 base64 字符串并注意到,发送的字符串和 Java 打印的字符串之间存在差异。您知道这些差异可能来自何处吗?

区别如下:- Java 字符串更长- 前 ~7610 个字节相等- 在第 7610 个字节之后,字符串不同

private Path saveAsFile(InputStream stream) throws IOException {
byte[] bytes = new byte[1024];
String base64String = "";
while (stream.read(bytes) != -1) {
String tmp = new String(bytes, StandardCharsets.UTF_8);
base64String += tmp;
}
//this prints out a longer base64 String than the Javascript part
System.out.println(base64String);
String replaced = base64String.replaceFirst("data:image/png;base64,", "");

byte[] replacedbytes = Base64.decodeBase64(replaced);

Path temp = Files.createTempFile("photo", ".png");
FileOutputStream fos = new FileOutputStream(temp.toFile());
fos.write(replacedbytes);
return temp;
}

提前致谢!

最佳答案

这个:

byte[] bytes = new byte[1024];
String base64String = "";
while (stream.read(bytes) != -1) {
String tmp = new String(bytes, StandardCharsets.UTF_8);
base64String += tmp;
}

不是在 java 中读取流的有效方法。 (基本上,您必须考虑 stream.read() 返回的值作为缓冲区中实际有效的字节数,并使用 new String(bytes, 0, theAboveValue, charset)作为字符串构造函数。

除此之外,您没有正确关闭 FileOutputStream

但即便如此,这里还有其他问题(在连接流之前解码字符集可能是一个等待发生的错误 - 但它会起作用,因为 base64 实际上是纯 ASCII,没有多字节字符会在这里导致错误。纯属运气)。

清理代码的 IO 部分,它应该看起来像:

private Path saveAsFile(InputStream stream) throws IOException {
byte[] bytes = new byte[1024];
int readBytes = 0;
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
while ((readBytes = stream.read(bytes)) != -1) {
buffer.write(bytes, 0, readBytes);
}

//this prints out a longer base64 String than the Javascript part
String base64String = new String(buffer.getBytes, "US-ASCII");
String replaced = base64String.replaceFirst("data:image/png;base64,", "");
byte[] replacedbytes = Base64.decodeBase64(replaced);

Path temp = Files.createTempFile("photo", ".png");
FileOutputStream fos = new FileOutputStream(temp.toFile());
fos.write(replacedbytes);
fos.close();// You should not miss that too! And put it in a "finally" step not to leak file descriptors.
return temp;

这可能效果更好,但就内存消耗而言是低效的(将字节转换为字符串再转换为字节,每一步都进行复制!)。

有更好的方法!使用库进行此类复制可能会更好。 Apache Commons IO 和 Commons Codec 有很好的 Base64InputStreamIOUtils.copy 类,可以在这里提供帮助。

在这种情况下,它可以读作:

private Path saveAsFile(InputStream stream) throws IOException {
// Maybe you should advance the stream to skip the "data/image stuff"...
//stream.skip(theActualNumberOfBytesToSkip);
try (Base64InputStream decoded = new Base64InputStream(stream); FileOutputStream file = /*whatever*/) {
IOUtils.copy(decoded, file);
}
}

关于java - JS和Java中相同图像的不同Base64字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47350474/

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