Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的字符编码_Java_Utf 8 - Fatal编程技术网

Java中的字符编码

Java中的字符编码,java,utf-8,Java,Utf 8,我用记事本打开文件,在上面写:“ą”保存并关闭 我试着用两种方式阅读这个文件 第一: InputStream inputStream = Files.newInputStream(Paths.get("file.txt")); int result = inputStream.read(); System.out.println(result); System.out.println((char) result); 196 Ä 第

我用记事本打开文件,在上面写:“ą”保存并关闭

我试着用两种方式阅读这个文件

第一:

        InputStream inputStream = Files.newInputStream(Paths.get("file.txt"));
        int result = inputStream.read();
        System.out.println(result);
        System.out.println((char) result);
196 Ä

第二:

        InputStream inputStream = Files.newInputStream(Paths.get("file.txt"));
        Reader reader = new InputStreamReader(inputStream);
        int result = reader.read();
        System.out.println(result);
        System.out.println((char) result);
261 ą

问题: 1) 在二进制模式下,此字母保存为196?为什么不是261? 2) 此字母另存为196,采用哪种编码


我试图理解为什么会有差异

您得到的是
拉丁字母的
十进制
值 您需要使用
UTF-8
编码标准
保存
文件

当你用类似的标准阅读它们时,一定要确保

0x0105 261带OGONEKą的拉丁文小写字母A

0x00C4 196带分音符的拉丁文大写字母A�


请参阅:-

尝试使用UTF-8编码的
InputStreamReader
,该编码与从记事本++写入文件时使用的编码相匹配:

// this will use UTF-8 encoding by default
BufferedReader in = Files.newBufferedReader(Paths.get("file.txt"));

String str;
if ((str = in.readLine()) != null) {
    System.out.println(str);
}
in.close();

我没有一个确切的/可复制的答案来解释为什么您会看到您看到的输出,但是如果您使用错误的编码进行读取,您不一定会看到您保存的内容。例如,如果单个字符
ą
用两个字节编码,但您以ASCII格式读取,那么您可能会返回两个字符,这两个字符与原始文件不匹配。

因为您以不同的编码读取这两个字母,所以可以通过
InputStreamReader::getEncoding
检查您的编码

String s = "ą";

char iso_8859_1 = new String(s.getBytes(), "iso-8859-1").charAt(0);
char utf_8 = new String(s.getBytes(), "utf-8").charAt(0);   

System.out.println((int) iso_8859_1 + " " + iso_8859_1);
System.out.println((int) utf_8 + " " + utf_8);
输出是

196 Ä
261 ą

UTF-8将范围
U+0080
-
U+07FF
中的值编码为两个字节,格式为
110xxxxx
10xxxxxx
(更多信息请参见)。因此,只有
xxxxx xxxxxx
11个字节可用于值

ą
是其中的
0105
是十六进制值(十进制值是
261
)。作为二进制,它可以表示为

      01       05    (hex)
00000001 00000101    (bin)
     xxx xxxxxxxx <- values for U+0080 - U+07FF range encode only those bits

     001 00000101 <- which means `x` will be replaced by only this part 
分为(两个字节):

现在,
InputStream
将数据读取为原始字节。因此,当您调用
inputStream.read()时第一次获取
11000100
时,它是以十进制表示的
196
。调用
inputStream.read()
第二次将返回
10000101
,它是十进制的
133

Reader
s是在Java1.1中引入的,因此我们可以避免代码中出现这种混乱。相反,我们可以指定编码读取器应该使用什么(或让它使用默认值)来获得正确编码的值,如本例中的
00000001 00000101
(不带掩码),它等于十六进制形式的
0105
,十进制形式的
261


总之

  • 如果要以文本形式读取数据,请使用
    Reader
    s(使用正确指定的编码)
  • 如果要将数据作为原始字节读取,请使用
    Stream
    s

您将一个字符的文件保存在记事本中的编码是什么?记事本++显示“utf-8无bom”,但我在utf-8表“ą”中没有看到带有代码的字母:196 OP已经意识到了这一点。所以,他不是这个意思。字符
ą
编码为两个字节(
C4 85
),其中
C4
是十进制的
196
。所以他们实际上只读取了第一个字节。@TiiJ7谢谢你的侦探工作。我不知道该如何解决这个问题,但编码问题是我首先想到的:-)
110xxxxx 10xxxxxx
   00100   000101
11000100 10000101