java randomaccessfile 乱码_Java 8 RandomAccessFile 读取 UTF-8 乱码
问题结论
为什么 RandomAccessFile 的 readLine() 读 UTF-8 文件是乱码?
RandomAccessFile 的函数 readLine() 使用 ISO-8859-1 解码文件,所以读取 UTF-8 的文件会造成乱码。解决方式就是再使用ISO-8859-1编码得到原先的byte[]数组,再用这个数组重新构造 String 即可。
但是使用ISO-8859-1解码并没有在文档中提及,这个隐藏特性的来源是什么呢?
源码之下,了无秘密
首先查看 readLine() 的源码
public final String readLine() throws IOException {
StringBuffer input = new StringBuffer();
int c = -1;
boolean eol = false;
while (!eol) {
switch (c = read()) {
case -1:
case '\n':
eol = true;
break;
case '\r':
eol = true;
long cur = getFilePointer();
if ((read()) != '\n') {
seek(cur);
}
break;
default:
input.append((char)c);
break;
}
}
if ((c == -1) && (input.length() == 0)) {
return null;
}
return input.toString();
}
readLine 实际上就是通过迭代 read() 函数读取单个字节,并把每个字节转化成 char 类型依次装入 input 中,在遇到换行符之后停止操作。这里我们可以注意到有趣的一点,就是他对于不同协议中的两种换行符都做了考虑。
所以我们继续探索 read() 函数
read() 源码
public int read() throws IOException {
return read0();
}
read() 函数非常的简单,通过注释我了解到,read() 的作用就是读取一个字节的内容,并把这个字节装入 int 中返回。
思考
再回头看 readLine(),这两个函数都非常的简单,无论是代码还是注释根本就没有提什么 ISO-8859-1标准,那这一行是怎么莫名其妙的被以 ISO-8859-1 解码的呢。
这是因为,Java 的 char 类型使用的是Unicode。而ISO-8859-1是一位定长的字符集,Unicode 的前256位和ISO-8859-1是重合的。换句话说,Unicode的前256位就是ISO-8859-1。所以在 readLine() 中对每一字节进行读取并立即转化成 char 类型的过程,就相当于完成了 ISO-8859-1 解码。
而我们要想得到原始的 byte 串怎么办呢?有两种方法,一种就是把 readLine() 读出的 String 用 ISO-8859-1 编码转回 编码前的 byte[] 数组。
import java.io.IOException;
import java.io.RandomAccessFile;
public class LearnBytes {
public static void main(String[] args) throws IOException {
String path = "files/t.txt";
RandomAccessFile rf = new RandomAccessFile(path, "rw");
String buffer = rf.readLine();
byte[] originalBytes = buffer.getBytes("ISO-8859-1”); //反编码回文件中本原始的字节流
String utf8 = new String(originalBytes); //String 构造函数默认接受 UTF-8 编码
}
}
另一种方法就是通过 read() 自己写一个readLine()函数,返回值是byte[]类型。
总结
It’s not a bug. It’s an undocumented feature.
参考及补充
严格来讲,ISO-8859-1 和 Java char 使用的 Unicode 是字符集。而 UTF-8 是基于 Unicode 的编码方式。
java randomaccessfile 乱码_Java 8 RandomAccessFile 读取 UTF-8 乱码相关推荐
- java 读写文件乱码_Java 解决读写本地文件中文乱码的问题
Java 解决读写本地文件中文乱码的问题 前言: 在用Java程序进行读写含中文的txt文件时,经常会出现读出或写入的内容会出现乱码.原因其实很简单,就是系统的编码和程序的编码采用了不同的编码格式.通 ...
- java zip 压缩乱码_java实现zip压缩中文文件名乱码怎么办?
java实现zip压缩中文文件名乱码怎么办? java实现zip压缩中文文件名乱码的解决办法: 一.文件压缩的中文乱码问题 1.中文文件名的乱码解决 对于压缩的文件,当文件名称是中文时,若使用JDK ...
- java 过滤器 中文_java中Filter过滤器解决中文乱码办法
java中Filter过滤器解决中文乱码办法 发布时间:2020-04-07 10:19:09 来源:亿速云 阅读:16 作者:小新 这篇文章主要为大家详细介绍了java中Filter过滤器解决中文乱 ...
- php mysql中文乱码怎么解决_php读取mysql中文乱码怎么解决?
解决方法:1.在网页文件中使用设置UTF-8编码:2.新建数据库时设置UTF-8编码:3.PHP连接数据库时,使用"mysql_query("set names 'utf8'&qu ...
- java 字节流乱码_java用字节流读取中文乱码怎么解决?
首先,如果你明确的知道使用的编码,那么你可以在读取完毕生成字符串的时候直接指定编码. 例如: FileInputStream in = new FileInputStream("aaa.tx ...
- java 调用 dll 乱码_java调用c++ dll出现中文乱码
最近的开发用到了使用java调用本机动态连接库的功能,将文件路径通过java调用C++代码对文件进行操作.在调用中如果路径中包含有中文字符就会出现问题,程序运行就会中止.下面用一个小例子,来说明记录下 ...
- java dll 乱码_java调用c++ dll出现中文乱码 | 学步园
最近的开发用到了使用java调用本机动态连接库的功能,将文件路径通过java调用C++代码对文件进行操作.在调用中如果路径中包含有中文字符就会出现问题,程序运行就会中止.下面用一个小例子,来说明记录下 ...
- java通字乱码_Java解决通信过程的中文乱码的问题
Java解决通信过程的中文乱码的问题 前言: Java的编程中,经常会碰到汉字的处里及显示的问题,比如一大堆乱码或问号. 这是因为JAVA中默认的编码方式是UNICODE,而中国人通常使用的文件和DB ...
- java中判断字符串乱码_java中如何判断字符串是否乱码
java中如何判断字符串是否乱码 发布时间:2020-06-18 13:43:41 来源:亿速云 阅读:113 作者:鸽子 项目中有一个功能 在IE中GET方式提交会产生乱码 但有两个入口都会走这同一 ...
最新文章
- 如何把字符串类型转换成整型?
- 一种定位内存泄露的方法(Linux)
- Leetcode每日必刷题库第5题,如何实现最长回文子串?
- 《编码的奥秘》---学习编程一年半的体会
- linux之通过tail命令动态跟踪日志文件里面的末尾信息
- JUnit-4.12报java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribing异常的解决
- RuoYi-Cloud 部署篇_01(linux环境 mysql+nginx版本)
- docker安装文档
- Pentium II Pentium III架构/微架构/流水线 (2) - P6详解 - 前端(指令预取/译码/动态分支预测静态分支预测)
- 169、多数元素(python)
- 关于shopex网店系统和网店助理的几点优化建议
- 计算机专业职业规划英语小作文,关于职业规划的英语作文
- 安装工程造价课程设计_安装工程造价课程设计心得体会及建议
- 34604-52-9,Ms-PEG3-Ms甲磺酸基是良好的离去基,也可用作伯醇的保护基
- SpringMvc导入Excel
- 这份整理的图解Java(全彩版)火了,完整PDF开放下载
- 日常水文章之Linux+arm+阿里IOT sdk+Cmake
- 手把手教你免费、批量转换HEIC图片到JPG
- WMS item与LPN的关系
- AI 靠眨眼反制假视频;马斯克等联名承诺不发展AI武器系统 | 一周 AI 新闻