1. 程式人生 > >黑馬程式設計師——Java基礎---IO流(字元流、位元組流、轉換流、流操作規律)

黑馬程式設計師——Java基礎---IO流(字元流、位元組流、轉換流、流操作規律)

三、字元編碼

  • 字元編碼通過轉換流來完成。
  • 在兩個物件進行構造的時候,可以加入字符集(即編碼表),可傳入編碼表的有:
    • 轉換流:InuputStreamReaderOutputStreamWriter。
    • 列印流:PrintStreamPrintWriter,只有輸出流。
  • 轉換流的編碼應用
    1. 可以將字元以指定編碼格式儲存。
    2. 可以對文字資料指定編碼格式來解讀。
    3. 指定編碼表的動作由建構函式完成。
  • 編碼和解碼
    • 編碼:字串變成位元組陣列
      • 預設字符集:
        • String  --->  byte[]  str.getBytes()
      • 指定字符集:
        • String  --->  byte[]  str.getBytes(charsetName)
    • 解碼:位元組陣列變成字串
      • 預設字符集:
        •  byte[]  --->  String new String(byte[])
      • 指定字符集:
        •  byte[]   --->  String newString(byte[],charsetName)
  • 對於編碼和解碼的字符集轉換注意事項
    • 如果編碼失敗,解碼就沒意義了。
    • 如果編碼成功,解碼出現的是亂碼,需要對亂碼通過再次編碼(用解錯碼的編碼表),然後再通過正確的編碼表解碼。針對於IOS8859-1是通用的。
    • 如果用的是GBK編碼,UTF-8解碼,此時通過再次編碼後解碼的方式,就不能成功了,因為UTF-8也支援中文,在UTF-8解的時候,會將對應的位元組數改變,所以不會成功。
  • 特別注意:對於中文的”聯通“,這兩個字比較特別,它的二進位制位正好是和在UTF-8中兩個位元組打頭的相同,所以在文字檔案中,如果單獨寫“聯通”或者和滿足UTF-8編碼格式的字元一起儲存時,記事本就會用UTF-8來進行解碼動作,這樣顯示的就會是亂碼。
練習:
/*
有五個學生,每個學生有3門課的成績,
從鍵盤輸入以上資料(包括姓名,三門課成績),
輸入的格式:如:zhagnsan,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 ma,cn,en;
	private int sum;

	Student(String name,int ma,int cn,int en)
	{
		this.name = name;
		this.ma = ma;
		this.cn = cn;
		this.en = en;
		sum = ma + cn + en;
	}

	//複寫compareTo方法,按分數排序
	public int compareTo(Student s)
	{
		int num = new Integer(this.sum).compareTo(new Integer(s.sum));
		if(num==0)
			return this.name.compareTo(s.name);
		return num;
	}

	public String getName()
	{
		return name;
	}
	public int getSum()
	{
		return sum;
	}
	//複寫hashCode
	public int hashCode()
	{
		return name.hashCode()+sum*78;

	}
	//複寫equals,判斷姓名和總成績是否相同
	public boolean equals(Object obj)
	{
		if(!(obj instanceof Student))
			throw new ClassCastException("型別不匹配");
		Student s = (Student)obj;

		return this.name.equals(s.name) && this.sum==s.sum;
	}
	//複寫toString方法,返回學生資訊。
	public String toString()
	{
		return "student["+name+", "+ma+", "+cn+", "+en+"]";
	}
}
//學生工具類
class StudentInfoTool
{
	//從鍵盤讀取學生資訊方法,以學生自身排序方式存入集合中 
	public static Set<Student> getStudents()throws IOException
	{
		return getStudents(null);
	}
	//從鍵盤讀取學生資訊方法,以比較器排序方式存入集合中  
	public static Set<Student> getStudents(Comparator<Student> cmp)throws IOException
	{
		//獲取鍵盤錄入
		BufferedReader bufr = 
			new BufferedReader(new InputStreamReader(System.in));

		String line = null;
		//定義一個集合,用來儲存學生物件
		Set<Student> stus  = null;
		if(cmp==null)
			stus = new TreeSet<Student>();
		else
			stus = new TreeSet<Student>(cmp);
		//讀取資料
		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 write2File(Set<Student> stus)throws IOException
	{
		//關聯檔案  
		BufferedWriter bufw = new BufferedWriter(new FileWriter("stuinfo.txt"));
		//遍歷集合,將學生資訊寫入到指定檔案
		for(Student stu : stus)
		{
			bufw.write(stu.toString()+"\t");
			bufw.write(stu.getSum()+"");
			bufw.newLine();
			bufw.flush();
		}

		bufw.close();

	}
}

class StudentInfoTest 
{
	public static void main(String[] args) throws IOException
	{
		//定義一個反轉自身比較性的比較器 
		Comparator<Student> cmp = Collections.reverseOrder();
		//呼叫學生工具類的獲取資訊方法,將資訊存入集合中  
		Set<Student> stus = StudentInfoTool.getStudents(cmp);
		//將學生資訊寫入指定檔案中 
		StudentInfoTool.write2File(stus);
	}
}

相關推薦

no