存储文本字符串时,需要考虑字符编码方式。
- OutputStreamWriter 类:将使用选定的字符编码方式,把 Unicode 码元的输出流转换为字节流。
- InputStreamReader 类:将包含字节的输入流转换为可以产生 Unicode 码元的读入器。
1 文本输出
文本输出使用 PrintWriter,拥有以文本格式打印字符串和数字的方法
PrintWriter out = new PrintWriter("employee.txt","UTF-8");
//等同于
PrintWriter out = new PrintWriter(new FileOutStream("employee.txt"),"UTF-8");
使用 print,println 和 printf 等方法,写入 employee.txt 中
2 文本输入
2.1 处理任意文本
Scanner 类,可以从任何输入流中构建 Scanner 对象。
2.2 短小文本读入字符串
String content = new String(Files.readAllBytes(path),charset);
2.3 按行读入
List<String> lines = Files.readAllLiines(path,charset);
2.4 大文件惰性处理行
try (Stream<String> lines = Files.lines(path,charset)){...}
2.5 早期 BufferedReader
readLine 方法按行读入,无法获得更多的输入时返回 null。
InputStream inputStream = ...;
try (BufferedReader in = new BufferedReader(new InputStreamReader(inputStream,StandardCharset.UTF_8))){
String line;
while((line = in.readLine()) != null)){
do Something
}
}
lines 方法产生 Stream 对象。
3 字符编码方式
Java 字符使用的是 Unicode 标准,每个编码点 21 位整数,有多种不同的字符编码方式。
最常见的编码方式有 UTF-8、UTF-16、GBK 字符集。
3.1 UTF-8
将每个 Unicode 编码点编码为 1 到 4 个字节的序列
3.2 UTF-16
将每个 Unicode 编码点编码为 1 个或 2 个 16 位值。
有两种形式的 UTF-16,被称为“高位优先”和“低位优先”,也被称为“大小端模式”。
例如 16 位值 0x2122
- 低位优先:0x22 0x21
- 大端模式。数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中;地址由小向大增加,而数据从高位往低位放。
- Mac OS 是大端模式。
- 高位优先:0x21 0x22
- 小端模式。数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,和我们的逻辑方法一致。
- x86 和一般的 OS(如windows,FreeBSD,Linux)使用的是小端模式。
Java 由于虚拟机的关系,屏蔽了大小端问题,都是按照“高位在前”大端模式写出
为了表示使用的是哪一种格式,文件可以以“字节顺序标记”开头,这个标记为 16 位数值 0xFEFF。读入器可以使用这个值来确定字节顺序,然后丢弃它。
3.3 明确指定编码方式
StandardCharsets 类具有类型为 Charset 的静态变量,用于表示每种 Java 虚拟机都必须支持的字符编码方式:
StandardCharsets.UTF_8
StandardCharsets.UTF_16
StandardCharsets.UTF_16BE
StandardCharsets.UTF_16LE
StandardCharsets.UTF_8859_1
StandardCharsets.UTF_US_ASCII
获得另一种编码方式的 Charset
Charset shiftJIS = Charset.forName("Sift-JIS");
在读入或写出文本时,应该使用 Charset 对象。
String str = new String(bytes,StandardCharsets.UTF_8);