Java:编码的详解
ASCII:美国信息标准信息码,用一个字节的7为表示。
ISO8859-1:拉丁码表 欧洲码表 ,用一个字节的8位表示。
GB2312:中国的中文编码表。
GBK:中国的中文编码表升级,融合了更多的中文文字符号。
Unicode:国际标准码,融合了多种文字。所有文字都用两个字节表示,Java使用的就是这种编码表。
UTF-8:最多用三个字节来表示一个字符。
//例子1:
import java.io.*; class EncodeStream { public static void main(String[] args)throws IOException { //writeText(); readText(); } public static void writeText()throws IOException { OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("GBK.txt"));//默认是GBK编码 //OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("UTF-8.txt"),"utf-8"); //OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("Unicode.txt"),"Unicode"); //OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("ASCII.txt"),"ASCII"); //OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("ISO8859-1.txt"),"ISO8859-1"); osw.write("你好!"); osw.flush(); osw.close(); } public static void readText()throws IOException { InputStreamReader isr = new InputStreamReader(new FileInputStream("GBK.txt"),"GBK"); char[] buf = new char[1024]; int len = 0; while((len = isr.read(buf))!=-1) { String s = new String(buf,0,len); System.out.println(s); } String str = isr.getEncoding(); System.out.println(str); isr.close(); } }
编码:字符串变成字节数组
String------>byte[] str.getBytes()/默认GBK/或str.getBytes(Charset charset)/设置编码模式/
解码:字节数组变成字符串
byte[]------>String new String(byte[])/默认GBK/或new String(byte[],Charset charset)/设置编码模式/
//例子2:
import java.util.*; class EncodeDemo { public static void main(String[] args)throws Exception { String s = "你好"; //编码 byte[] b1 = s.getBytes("GBK");//[-60, -29, -70, -61]四个字节 //byte[] b1 = s.getBytes("UTF-8");//[-28, -67, -96, -27, -91, -67]六个字节 //byte[] b1 = s.getBytes("Unicode");//[-2, -1, 79, 96, 89, 125] //byte[] b1 = s.getBytes("ISO8859-1");//[63, 63]两个字节 //System.out.println(Arrays.toString(b1)); //解码 String str1 = new String(b1,"ISO8859-1");//应该是GBK的编码,结果解成了ISO8859-1编码,此时会出现乱码,需要重新编码解码 System.out.println(str1);//发现乱码结果是???? //对乱码再一次编码 byte[] b2 = str1.getBytes("ISO8859-1"); System.out.println(Arrays.toString(b2));//[-60, -29, -70, -61] //再一次解码 String str2 = new String(b2); System.out.println(str2);//你好 } }
在文本中写入"联通"这两个字时,会出现特殊的编码现象
//例子3:
class EncodeDemo2 { public static void main(String[] args)throws Exception { String s = "联通";//这两个字出现GDK编码和UTF-8编码重复的现象 byte[] by = s.getBytes("gbk"); for(byte b: by) { System.out.println(Integer.toBinaryString(b&255)); } } } /* 11000001 10101010 11001101 10101000 以上复合UTF-8的编码 */
对文件的综合应用:
例子4:
练习:有5个学生,每个学生有3门课的成绩,从键盘输入以上数据(包括姓名,三门课的成绩),输出格式:如:zhangsan 30,40,60。计算出总成绩,并把每个学生的信息和计算出的总分数按照高低顺序存放在磁盘文件“stud.txt”中。
步骤:
1.描述学生对象。
2.定义一个可以操作学生对象的工具类。
思想:
1.通过获取从键盘录入的一行数据,并将该行中的数据取出来封装成学生对象。
2.因为学生有很多,就需要存储。使用到集合,因为要对学生的总分数进行排序,所以可以使用TreeSet集合。
3.将集合中的信息写入到文件中。
import java.io.*; import java.util.*; class Student implements Comparable<Student> { private String name; private int math; private int English; private int Chinese; private int ScoreSum; Student(String name,int math,int English,int Chinese) { this.name = name; this.math = math; this.English = English; this.Chinese = Chinese; ScoreSum = math+English+Chinese; } public String getname() { return name; } public int getScoreSum() { return ScoreSum; } public int hashCode() { return name.hashCode()+ScoreSum*78; } public boolean equals(Object obj) { if(!(obj instanceof Student)) throw new RuntimeException("不是学生对象!"); Student s = (Student)obj; return this.name.equals(s.name) && this.ScoreSum==s.ScoreSum; } public int compareTo(Student s) { int num = new Integer(this.ScoreSum).compareTo(new Integer(s.ScoreSum)); return num==0? this.name.compareTo(s.name):num; } public String toString() { return "Student["+name+","+math+","+English+","+Chinese+"]"; } } class StudentInfoTool { public static Set<Student> getStudent()throws IOException { BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); Set<Student> stus = new TreeSet<Student>(new Mycomparator());//也可以采用逆转比较器的方法 String line = null; while((line = bufr.readLine())!=null) { if("over".equals(line)) break; String[] info = line.split(","); Student stu = new Student(info[0],Integer.parseInt(info[1]),Integer.parseInt(info[2]),Integer.parseInt(info[3])); stus.add(stu); } bufr.close(); return stus; } public static void WriteInfo(Set<Student> stus)throws IOException { BufferedWriter bufw = new BufferedWriter(new FileWriter("stud.txt")); //BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out)); for(Student stu:stus) { bufw.write(stu.toString()+"\t"); bufw.write(stu.getScoreSum()+""); bufw.newLine(); bufw.flush(); } bufw.close(); } } class StudentFileTest { public static void main(String[] args)throws IOException { Set<Student> set = StudentInfoTool.getStudent(); StudentInfoTool.WriteInfo(set); } } class Mycomparator implements Comparator<Student> { public int compare(Student s1,Student s2) { if(s1.getScoreSum()>s2.getScoreSum()) return -1; if(s1.getScoreSum()<s2.getScoreSum()) return 1; else return 0; } } /* 输入数据: zhangsan,78,89,87 lisi,89,86,78 wangwu,78,56,68 zhaoliu,89,99,100 zhouqi,45,68,97 打印结果: Student[zhaoliu,89,99,100] 288 Student[zhangsan,78,89,87] 254 Student[lisi,89,86,78] 253 Student[zhouqi,45,68,97] 210 Student[wangwu,78,56,68] 202 */
程序猿神奇的手,每时每刻,这双手都在改变着世界的交互方式!