Java字符问题集

字符集

ASCII编码

图片来源:百度百科
ascii字符码


问题集

Java自动生成bat的换行和乱码问题

想用java自动创建Windows中的bat批处理文件,但是遇到了换行和中文乱码问题,记录如下

换行问题

不同系统的换行符:

  • windows下的文本文件换行符:\r\n (一定是\r在前,\n在后)
  • linux/unix下的文本文件换行符:\r
  • Mac下的文本文件换行符:\n

参考自:Java写到.txt文件,如何实现换行 - huiyi789

各软件识别换行符:

  • Java在处理String或者在console输出的时候,无论是\r或是\n都能换行。
  • 但是偏偏在txt中,哪个都不是标准的换行,只有合起来的\r\n才是换行(对于整个windows默认的换行来说,都是这样)。
  • 意思是\r敲个回车,表明这行结束了,光标回到本行的最前面去,然后再\n下移一行来个新行。

参考自:关于换行符 - tonygao

乱码问题

  手动创建编写Bat文件时,将该bat文件以 ANSI 1 编码进行保存,则能正常地在所有文本编辑软件中正常查看,运行时也不会出现中文乱码。但java中无法设置ANSI编码,于是尝试了utf-8和GBK编码,效果如下:

java以不同编码的输出流将中文写入到bat文件中的效果:

编码Windows记事本打开是否乱码notepad++打开是否乱码EditPlus打开是否乱码运行该Bat文件是否显示乱码
utf-8乱码
GBK乱码乱码
  • 因为最终要运行bat文件,CMD中需要有中文查看运行日志,所以不能使用uft-8。
  • 而GBK编码下,记事本软件不乱码,能正常查看中文,notepad++软件更改为以gb2312编码读取文本后,也能正常查看中文。所以决定使用GBK编码。
  • notepad++软件更改为以gb2312编码读取文本(仅以gb2312编码读取,不以gb2312编码保存):菜单栏 ⇨ 编码 ⇨ 编码字符集 ⇨ 中文 ⇨ GB2312(simplified)

  测试代码如下:

	public static void main(String[] args) throws IOException {
		File file = new File("D:/test.bat");
		//创建输出流
        OutputStreamWriter ows = null;
        try {
            ows = new OutputStreamWriter(new FileOutputStream(file),"utf-8");//此处更换不同编码进行测试
        } catch (UnsupportedEncodingException e) {
            System.err.println("编码设置错误,请检查编码名称的拼写及大小写。");
            e.printStackTrace();
            return ;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return ;
        }

		//写入到文件
        try {
            ows.write("@echo 测试CMD中能否正常显示中文。");//cmd中“@echo”用于回显打印字符
            ows.write("\r\n");//windows下的文本软件使用“\r\n”来表示换行
            ows.write("@echo This is the second line.");
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

		//清空输出流缓存 及 关闭输出流
        try {
            ows.flush();
            ows.close();
        } catch (IOException e) {
            return;
        }
	}

Java读取及处理注册表文件的异常问题

最近用Java读取Windows注册表的导出备份文件出现了问题,最终发现了原因。

问题原因

  • 首先介绍下0号字符:0号字符是ASCII编码中的第一个字符,而ASCII编码的前32个字符都是不可见字符。ASCII编码一共只有128个字符,UTF-8编码兼容ASCII编码,也就是说UTF-8编码的前128个字符就是ASCII编码,并且顺序也一致。
    另外“不可见字符”的含义是:在诸如记事本、Editplus软件中是不显示的,并且也不会有一个空位来表示这里有个不可见字符,用这些软件打开导出文件时看起来是很正常的!
  • 然后Java中使用 FileReader 对象按行读取数据时的行结束标识符有三个:组合在一起的“\r\n”单独存在的“\r”单独存在的“\n”。并且FileReader字符流对象的底层仍是读字节,再将字节转为字符,所以Java是能读到0号字符的,再用输出流输出时会以某种符号表示0号字符;
  • 其次发现注册表的导出文件是UTF-8格式,并且每个内容字节的后面都有一个0号字符,包括原本的换行符也有0号字符。而0号字符是不可见字符,这里以符号表示:原本的\r\n变成了\r♦\n♦。而这也就导致了后续的字符串处理问题。
  • 最后,上述原因共同导致了一个问题。用记事本打开文件看到的内容是这样的:
    ABC
    DEF
    
    此时以为这个文件的编码是ABC\r\nDEF,而实际上文件的编码是A♦B♦C♦\r♦\n♦D♦E♦F♦,可以看到\r\n被分开了,于是FileReader对象读取并输出的结果如下:
    A♦B♦C♦
    ♦
    ♦
    D♦E♦F♦
    

截图举例

实际输出的部分截图,如下:
在这里插入图片描述
而在记事本中看到是是这样的:

[HKEY_LOCAL_MACHINE]

[HKEY_LOCAL_MACHINE\BCD00000000]

[HKEY_LOCAL_MACHINE\BCD00000000\Description]

解决方法


  1. ASNI:不同的国家和地区制定了不同的标准,由此产生了 GB2312、GBK、GB18030、Big5、Shift_JIS 等各自的编码标准。这些使用多个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文Windows操作系统中,ANSI 编码代表 GBK 编码;在繁体中文Windows操作系统中,ANSI编码代表Big5;在日文Windows操作系统中,ANSI 编码代表 Shift_JIS 编码。 来源 -百度百科 ↩︎

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java中的字符集编码是通过Java字符编码API进行处理的。Java中的字符串是以Unicode编码来表示的,因此,如果你要处理其他字符编码(如GBK、UTF-8等),你需要进行编码和解码。 以下是Java字符集编码的一些常用API: 1. String.getBytes()方法:将字符串转换为指定编码的字节数组。 例如,将字符串s以UTF-8编码转换为字节数组,可以使用以下代码: ```java byte[] utf8Bytes = s.getBytes("UTF-8"); ``` 2. new String(byte[] bytes, String charsetName)构造函数:使用指定编码将字节数组转换为字符串。 例如,将字节数组utf8Bytes以UTF-8编码转换为字符串,可以使用以下代码: ```java String s = new String(utf8Bytes, "UTF-8"); ``` 3. InputStreamReader和OutputStreamWriter类:用于将字节流转换为字符流,并指定字符集编码。 例如,将一个字节流inStream以GBK编码转换为字符流,可以使用以下代码: ```java InputStreamReader isr = new InputStreamReader(inStream, "GBK"); ``` 4. BufferedReader和BufferedWriter类:用于处理字符流,并提供了一些方便的读写方法。 例如,使用BufferedReader读取一个以UTF-8编码的文本文件,可以使用以下代码: ```java BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("file.txt"), "UTF-8")); String line; while ((line = reader.readLine()) != null) { // 处理每一行文本 } ``` 需要注意的是,在使用字符集编码时,通常需要注意编码方式的一致性,以避免出现乱码等问题

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值