很简答的的示例程序,大家看下
我的问题是,我不明白,文件的明明是0-50000这些数字,为什么文件打开以后,里面是各种各样的符号呢,有中文,英文,日文等等各种字符。
我能知道是unicode编码的原因,但是不是很清楚原理
请各位帮忙解释下,或者给个详细解释这个的链接之类的更好。
非常感谢!
很简答的的示例程序,大家看下
我的问题是,我不明白,文件的明明是0-50000这些数字,为什么文件打开以后,里面是各种各样的符号呢,有中文,英文,日文等等各种字符。
我能知道是unicode编码的原因,但是不是很清楚原理
请各位帮忙解释下,或者给个详细解释这个的链接之类的更好。
非常感谢!
FileWriter writer(int c) 重写Writer的write方法,他会调用StreamEncoder
StreamEncoder http://www.docjar.com/html/api/sun/nio/cs/StreamEncoder.java.html
他会将写入单个字符。要写入的字符包含在给定整数值的 16 个低位中,16 高位被忽略,查看链接即可
先看文档中文,它有五个方法
/**
* write(String str)
* 写入字符串。
* write(int oneChar)
* 写入单个字符。要写入的字符包含在给定整数值的 16 个低位中,16 高位被忽略。用于支持高效单字符输出的子类应重写此方法。
* write(char[] buf)
* 写入字符数组
* write(String str, int offset, int count)
* write(char[] buf, int offset, int count)
*/
用的是 write(int oneChar) 这一种,写入单个字符表,用计算器高位被忽略就是
00000000|00110010 //50
1|00000000|00110010 //65536 + 50
-------------------
然后两者其实结果是一样的。过程如下,只看最后两段即可
import java.io.FileWriter;
/**
* Created by star on 11/29/13.
* write(char[] buf, int offset, int count)
* write(String str)
* write(int oneChar)
* write(char[] buf)
* write(String str, int offset, int count)
*/
public class Encode {
public static void main (String [] args) {
FileWriter fw = null;
try {
// *输出字符串"妳好"
// fw = new FileWriter("/home/star/unicode.txt");
// String a = "妳好";
// fw.write(a);
// fw.close();
// *这里打印的不是50,而是50的16进制所代表的值「2」
// fw = new FileWriter("/home/star/unicode.txt");
// int a = 50;
// fw.write(a);
// fw.close();
// *比16位高的位数被忽略。会打印相同的两个「2」
// fw = new FileWriter("/home/star/unicode.txt");
// fw.write(50);
// fw.flush();
// fw.write(65536 +50);
// fw.flush();
// fw.close();
// *我想你要的结果是这样的吧 0x4e00 开始
fw = new FileWriter("/home/star/unicode.txt");
for (int a = 19968 ; a<19968 + 500;a++) {
fw.write(a);
}
fw.close();
} catch (Exception e) {
e.printStackTrace();
System.out.println("文件写入错误");
System.exit(-1);
}
}
}
15 回答8.4k 阅读
2 回答7k 阅读✓ 已解决
8 回答6.2k 阅读
1 回答4.1k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
2 回答3.1k 阅读
2 回答3.8k 阅读
由于你的参数类型为 int ,所以你实际调用的应该是 OutputStreamWriter.write(int)
这个函数的作用是“Writes a single character”。也就是说你写入的是一个直接的字节。
你没有搞清楚“编码”这个概念。“编码”就是把各种信息保存到计算机中的方式。因为计算机是只能处理数字的,所以所有的符号(这里指 A-Z a-z 中文 数字等)都需要有一个对应的“编码”。
小实验:
写一个 Java 程序,里面有:
然后用记事本打开你写入的那个文件,你看到了什么?
你应该看到“0123456789”,因为 48 - 57 对应的正好是 '0' - '9' 的 ASCII 码。完整的 ASCII 码表见 http://zh.wikipedia.org/zh-cn/ASCII 。
下载一个 16 进制编辑器,这里推荐 HxD 打开你之前生成的那个 unicode.dat 文件。你看到的东西应该是类似这样的:
你会发现该文件从第一个字节开始每个字节正好是 0 1 2 3 ...
计算机的每个字节可以表示一个 0 - 255 的数字,那每个数字代表什么含义呢?这就是编码赋予的。
也就是说,你把计算机中处理的“数字”,和编码中作为“符号”的那个“数字”搞混了,在 ASCII 码中恰好有 '0' - '9' 这 9 个数字,但它们是作为符号的,它们的编码是 48 - 57 。
在 Java 中,可以用类型来区别。直接的那个数字是 int 型,而作为符号的是 char 或 String 型。
至于为什么会出现乱码,这是因为记事本把文本文件按照 gbk 来解释,而 gbk 中有中文、日文之类的符号。
关于 Unicode 和各种编码,推荐一篇文章:
字符编解码的故事(ASCII,ANSI,Unicode,Utf-8区别)
那如何才能实现你想实现的功能呢?
可以用 Writer.write(String) 方法: