gpt4 book ai didi

java - 从 Windows 和 Linux 读取文件会产生不同的结果(字符编码?)

转载 作者:IT王子 更新时间:2023-10-29 00:38:21 26 4
gpt4 key购买 nike

目前我正在尝试读取一个 mime 格式的文件,其中包含一些 png 的二进制字符串数据。

在 Windows 中,读取文件会为我提供正确的二进制字符串,这意味着我只需复制该字符串并将扩展名更改为 png 即可看到图片。


Windows读取文件后的例子如下:

    --fh-mms-multipart-next-part-1308191573195-0-53229
Content-Type: image/png;name=app_icon.png
Content-ID: "<app_icon>"
content-location: app_icon.png

‰PNG

等...等...

Linux下读取文件后的例子如下:

    --fh-mms-multipart-next-part-1308191573195-0-53229
Content-Type: image/png;name=app_icon.png
Content-ID: "<app_icon>"
content-location: app_icon.png

�PNG

等...等...


我无法将 Linux 版本转换成图片,因为它都变成了一些带有很多倒置“?”的时髦符号。和“1/2”符号。

任何人都可以告诉我发生了什么事并可能提供解决方案吗?现在已经玩了一个多星期的代码。

最佳答案

�是三个字符的序列 - 0xEF 0xBF 0xBD , 并且是 Unicode 代码点的 UTF-8 表示 0xFFFD .代码点本身就是 replacement character用于非法 UTF-8 序列。

显然,出于某种原因,您的源代码(在 Linux 上)中涉及的一组例程未正确处理 PNG header 。 PNG header以字节 0x89 开头(然后是 0x500x4E0x47 ),这在 Windows 中得到了正确处理(可能会将文件视为 CP1252 字节序列)。在 CP1252 , 0x89字符显示为 .

然而,在 Linux 上,这个字节被 UTF-8 例程解码(或认为将文件作为 UTF-8 序列处理是好的库)。由于 0x89 本身不是 ASCII-7 范围内的有效代码点(引用:the UTF-8 encoding scheme),因此无法映射到 0x00-0x7F 范围内的有效 UTF-8 代码点。此外,它不能映射到表示为多字节 UTF-8 序列的有效代码点,因为所有多字节序列都以至少 2 位设置为 1 ( 11.... ) 开始,因为这是开始文件的,它也不能是一个连续字节。结果是 UTF-8 解码器现在替换了 0x89使用 UTF-8 替换字符 0xEF 0xBF 0xBD (多么愚蠢,考虑到该文件不是以 UTF-8 开头的),它将显示在 ISO-8859-1 中作为� .

如果您需要解决这个问题,您需要在 Linux 中确保以下内容:

  • 使用适合文件的编码(即非 UTF-8)读取 PNG 文件中的字节;如果您以字符序列* 的形式读取文件,这显然是必需的,而如果您单独读取字节,则没有必要。您可能正在正确执行此操作,因此也值得验证后续步骤。
  • 当您查看文件内容时,请使用合适的编辑器/ View ,该编辑器/ View 不会对文件执行任何内部解码为 UTF-8 字节序列。使用合适的字体也会有所帮助,因为您可能希望防止无法表示字形(对于 0xFFFD 它实际上是菱形字符 �)的前所未有的情况,并且可能导致进一步的更改(不太可能,但您永远不知道编辑器/查看器是如何编写的)。
  • 用合适的编码(也许是 ISO-8859-1,而不是 UTF-8)写出文件(如果您这样做)也是一个好主意。如果您将文件内容作为字节而不是字符处理并存储在内存中,那么将这些内容写入输出流(不涉及任何字符串或字符引用)就足够了。

* 显然,如果将字节序列转换为字符或字符串对象,Java 运行时会将字节序列解码为 UTF-16 代码点。

关于java - 从 Windows 和 Linux 读取文件会产生不同的结果(字符编码?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6366912/

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