Java基礎_IO流(下)

IO流(下)

五、File類

    流操作的是數據,而數據最常見的體現形式就是文件,而文件又包含大量的屬性信息,並且文件的對象非常多,所以java語言對文件進行了描述,即File類。

    流只能操作文件,不能操作文件夾;File類將文件或者文件夾封裝成對象,方便對於文件或文件夾屬性信息進行操作,並且File對象可以作爲參數傳遞給流的構造函數,使用非常方便。

    File類常見的方法:

    1、創建:

    boolean  createNewFile():在指定位置創建文件,已存在則不創建,返回false,輸出流對象一建立就創建文件,並且文件存在則覆蓋。

    boolean  mkdir():創建文件夾;

    boolean  mkdirs():創建多級文件夾。

    2、刪除:

    boolean  delete():刪除失敗返回false;

    void  deleteOnExit():在程序退出時刪除指定文件。

    3、判斷:

    boolean  exists():文件是否存在;注意:在操作之前必須判斷文件是否存在;

    boolean  isFile():是否是文件;

    boolean  isDirectory():是否是目錄;

    boolean  isHidden():是否隱藏;

    boolean  isAbsolute():是否是絕對路徑;

    4、獲取信息:

    getName():獲取名稱;

    getPath():獲取路徑;

    getParent():獲取父目錄;

    getAbsolutePath():獲取絕對路徑;

    long  length():獲取長度;

    listRoots():根目錄;

    list():獲取文件列表;調用該方法之前,必須保證file對象封裝了一個目錄,存在;

    遞歸:函數自己調用自己,稱爲遞歸;遞歸注意:1、限定條件,2、遞歸次數不能過大,避免內存溢出。

下面代碼體現:

1、File類常用方法的簡單演示:

1.1:

package itheima.day20;

import java.io.File;
import java.io.IOException;

public class FileDemo {

	public static void main(String[] args) {
//		consMethod();
//		method_1();
//		method_3();
		method_4();
	}
//	2、創建
	public static void method_1(){
		File f = new File("file.txt");
		try {
			sop("create:"+f.createNewFile());
			
		} catch (IOException e) {
			throw new RuntimeException("文件創建異常!");
			
		}
//		刪除,刪除失敗,返回false
		sop("delete::"+f.delete());
//		在程序退出時刪除指定文件
		f.deleteOnExit();
	}
//	判斷
	public static void method_2(){
		File f = new File("file2.txt");
		try {
			f.createNewFile();
		} catch (IOException e) {
			e.printStackTrace();
		}
//		判斷文件是否可執行
		sop("canExcute:"+f.canExecute());
		sop("exists:"+f.exists());
		
		File dir  = new File("abc\\aa\\bb\\cc\\dd\\ee");
//		創建文件夾,多層目錄
		sop("mkdirs:"+dir.mkdirs());
	}
	
	public static void method_3(){
		
//		只是封裝成一個文件對象而已,未創建
		File f = new File("file3.txt");
//		對一個File對象判斷是文件或者目錄之前,必須判斷它是否存在
		sop("exist"+f.exists());
		sop("dir:"+f.isDirectory());
		sop("File:"+f.isFile());
	}
//	獲取
	public static void method_4(){
		File f = new File("abc\\a.txt");
//		獲取封裝的路徑
		sop("path:"+f.getPath());
//		獲取絕對路徑
		sop("abspath:"+f.getAbsolutePath());
//		獲取父目錄
		sop("parent:"+f.getParent());
	}
	public static void method_5(){
		File f1= new File("c:\\Test.java");
		File f2= new File("c:\\hahaha.java");
//		剪切
		sop("rename:"+f1.renameTo(f2));
		
	}
//	1、創建File對象
	public static void consMethod(){
//		將a.txt封裝成爲對象,可以將已有的和未出現的文件或者文件夾封裝成爲對象
		File f1 = new File("ss.txt");
//		File.separator:與系統有關的分隔符;父目錄+文件名
		File f2 = new File("c:"+File.separator+"abc","b.txt");
		
//		把目錄封裝成爲File
		File d = new File("c:"+File.separator+"abc");
		File f3 = new File(d,"c.txt");
		
		sop("f1:::"+f1);
		sop("f2:::"+f2);
		sop("f3:::"+f3);
	}
	
	public static void sop(Object obj){
		System.out.println(obj);
	}
}
1.2:
package itheima.day20;

import java.io.File;
import java.io.FilenameFilter;

public class FileDemo2 {

	public static void main(String[] args) {
//		listRootsDemo();
//		listDemo();
		listDemo_3();
//		listDemo_2();
	}
	public static void listRootsDemo(){
//		C:\;D:\;E:\;F:\;G:\ 機器裏面的有效盤符
		File[] files = File.listRoots();
		for(File f:files){
			System.out.println(f);
		}
	}

	public static void listDemo(){
		File f = new File("c:\\");
//		獲取目錄的列表,包含隱藏文件
		String[] names = f.list();
		for(String name:names){
			System.out.println(name);
		}
	}
	public static void listDemo_2(){
			File dir = new File("c:\\");
			
			String [] arr = dir.list(new FilenameFilter(){
//			文件名過濾器
				@Override
				public boolean accept(File dir, String name) {
					return name.endsWith(".txt");
				}
			});
			for(String name:arr){
				System.out.println(name);
			}	
	}
	public static void listDemo_3(){
		File dir = new File("c:\\");
//		文件列表
		File[] files = dir.listFiles();
		for(File f:files){
			System.out.println(f.getName()+"::::"+f.length());
		}
	}
}

2、列出指定目錄下文件或者文件夾,包含目錄中的內容:

package itheima.day20;

import java.io.File;
//列出指定目錄下文件或者文件夾,包含目錄中的內容
//也就是列出指定目錄下所有內容
public class FileDemo3 {

	public static void main(String[] args) {
		File dir = new File("D:\\java\\workspace1\\JavaFoundation");
		showDir(dir,0);
	}
	public static void showDir(File dir,int level){
		System.out.println(getLevel(level)+dir.getName());
		level++;
		File[] files = dir.listFiles();
		for(int x =0;x<files.length;x++){
			if(files[x].isDirectory())
				showDir(files[x],level);
			else
				System.out.println(getLevel(level)+files[x]);
		}
	}
	public static String getLevel(int level){
		StringBuilder sb = new StringBuilder();
		sb.append("|--");
		for(int x =0; x<level;x++){
//			sb.append("|--");
			sb.insert(0, "|  ");
		}
		return sb.toString();
	}
}

3、刪除一個帶內容的目錄:

package itheima.day20;

import java.io.File;

//刪除一個帶內容的目錄
// 刪除原理:從裏往外刪
public class RemoveDir {

	public static void main(String[] args) {	
		File dir = new File("d:\\Test");
		removeDir(dir);
	}
	
	public static void removeDir(File dir){
		File[] files = dir.listFiles();
		
		for(int x=0;x<files.length;x++){
			if(files[x].isDirectory()/* && !files[x].isHidden()*/)
				removeDir(files[x]);
			else
				System.out.println(files[x].toString()+"----"+files[x].delete());
		}
		System.out.println(dir+"::dir::"+dir.delete());
	}
}

4、將一個指定目錄下的java文件的絕對路徑,存儲到一個文本文件中:

package itheima.day20;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/*將一個指定目錄下的java文件的絕對路徑,存儲到一個文本文件中,
 * 建立一個java文件列表文件。
 * 思路:1、對指定的目錄進行遞歸;
 * 		2、獲取遞歸過程中的java文件路徑
 * 		3、將這些路徑存儲到集合中
 * 		4、將集合中的數據寫入到一個文件中。
 * */
public class JavaFileList {

	public static void main(String[] args) {
		
		File dir = new File("d:\\java\\workspace1\\Test");
		List<File> list = new ArrayList<File>();
		fileToList(dir,list);
		
		File file = new File("javalist.txt");
		writeToFile(list,file.toString());
		
		Iterator<File> it = list.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}	
	}
	public static void fileToList(File dir,List<File> list){
		File[] files = dir.listFiles();
		for(File file:files){
			if(file.isDirectory())
				fileToList(file,list);
			else{
				if(file.getName().endsWith(".java"))
					list.add(file);
			}
		}
	}
	public static void writeToFile(List<File> list, String javaListFile){
		BufferedWriter bufw = null;
		try {
			bufw = new BufferedWriter(new FileWriter(javaListFile));
			for(File f:list){
				String path = f.getAbsolutePath();
				bufw.write(path);
				bufw.newLine();
				bufw.flush();
			}
		} catch (IOException e) {
			throw new RuntimeException("IO讀寫異常!");
		}finally{
			try {
				if(bufw!=null)
					bufw.close();
			} catch (IOException e) {
				throw new RuntimeException("文件關閉異常!");
			}
		}
	}
}

六、Properties類:

    Properties是hashtable的子類,它具備map集合的特點,並且它裏面存儲的鍵值對都是字符串的形式;Properties是集合中和IO技術相結合的容器,該類對象的特點:可以用來存儲鍵值對形式的配置文件,那麼加載數據時,需要數據有固定的格式,鍵=值。

5.0:properties類常用方法的演示:

package itheima.day20;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;

public class PropertiesDemo {

	public static void main(String[] args) {
//		setAndGet();
		method_1();
//		loadDemo();
	}
	public static void loadDemo(){
		Properties prop = new Properties();
		try {
			FileInputStream fis = new FileInputStream("info.txt");
			prop.load(fis);
//			System.out.println(prop);
//			調用Hashtable中的put方法,改變Property中的屬性
			prop.setProperty("wangwu", "15");
			
			FileOutputStream fos = new FileOutputStream("info.txt");
//			存到一個流中,然後存到文件中,持久化
			prop.store(fos, "heihei");//註釋
			
			prop.list(System.out);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
//	演示如何將流中的數據存儲到集合中,想要將info.txt中鍵值數據存到集合中進行操作。
//	思路:1、用一個流和info.txt文件關聯
//	  		2、讀取一行數據,將該行數據用"="進行切割
//	  		3、等號左邊作爲建,右邊作爲值,存入到Properties中
	public static void method_1(){
		BufferedReader bufr = null;
		try {
			bufr = new BufferedReader(new FileReader("info.txt"));
			
			String line = null;
			Properties prop = new Properties();
			while((line = bufr.readLine())!=null){
//				System.out.println(line);
				String[] arr = line.split("=");
				prop.setProperty(arr[0], arr[1]);
			}
		System.out.println(prop);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				if(bufr!=null)
					bufr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
//	設置和獲取元素
	public static void setAndGet(){
		
		Properties prop = new Properties();
//		底層調用的是Hashtable的put方法
		prop.setProperty("zhangsan1", "30");
		prop.setProperty("zhangsan2", "20");
//		把map轉成Set,再取
		Set<String> names= prop.stringPropertyNames();
		for(String s: names){
			System.out.println(s+":"+prop.getProperty(s));
		}
	}
}

5、寫一個試用軟件,如果使用次數已到,那麼給出註冊提示:

package itheima.day20;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

//用於記錄應用程序運行次數,
// 如果使用次數已到,那麼給出註冊提示
//配置文件可以實現應用程序數據的共享
public class RunCount {
	
	public static void main(String[] args)throws IOException {
		
		Properties prop = new Properties();
		File file = new File("count.ini");
//		文件不存在,則創建
		if(!file.exists())
			file.createNewFile();
		FileInputStream fis = new FileInputStream(file);
//		properties與輸入流相關聯
		prop.load(fis);
	    
		int count = 0;
//		獲取time屬性的值
		String value = prop.getProperty("time");
		if(value !=null){
//			將值的字符串形式轉成Integer
			count = Integer.parseInt(value);
			if(count>5){
				throw new RuntimeException("哥們,您老人家的大壽已盡,請交錢!!!");
			}
		}
		
		count++;
		prop.setProperty("time", count+"");
		FileOutputStream fos = new FileOutputStream(file);
//		把properties對象與輸出流相關聯,存儲到指定文件中
		prop.store(fos, "money");
		fos.close();
		fis.close();
	}
}

七、IO中的其他類

    7.1、序列流:SequenceInputStream:用於對多個流進行合併。

6、合併3個輸入流爲一個輸入流:

package itheima.day20;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;

//將多個流對象合併成一個流對象
public class SequenceDemo {

	public static void main(String[] args) throws IOException {
		
		Vector<FileInputStream> v = new Vector<FileInputStream>();
		v.add(new FileInputStream("1.txt"));
		v.add(new FileInputStream("2.txt"));
		v.add(new FileInputStream("3.txt"));
		
		Enumeration<FileInputStream> en = v.elements();
//		該對象是JDK1.0時出現,合併流對象,輸入流
		SequenceInputStream sis = new SequenceInputStream(en);
		
		FileOutputStream fos = new FileOutputStream("4.txt");
		
		byte[] buf = new byte[1024];
		int len =0;
		while((len = sis.read(buf)) != -1){
			fos.write(buf,0,len);
		}
		fos.close();
		sis.close();
	}
}

7、切割一個mp3文件:

package itheima.day20;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;

//切割文件
public class SplitFileDemo {

	public static void main(String[] args) throws IOException {
		splitFile();
		merge();
	}
//	切割
	public static void splitFile() throws IOException{
		
		FileInputStream fis = new FileInputStream("1.mp3");
		FileOutputStream fos = null;
		
		byte[] buf = new byte[1024*1024];
		int len = 0;
		int count =1;
		while((len = fis.read(buf)) != -1){
//			產生一個文件
			fos = new FileOutputStream((count++)+".part");
			fos.write(buf,0,len);
			fos.close();
		}
		fis.close();
	}
//	合併文件
	public static void merge() throws IOException{
		
//		把這些流對象存到一個ArrayList集合中
		ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
		for(int i=1;i<6;i++){
			al.add(new FileInputStream(i+".part"));
		}
		
		final Iterator<FileInputStream> it = al.iterator();
//		匿名內部類,不能訪問外部類的局部變量
		Enumeration<FileInputStream> en = new Enumeration<FileInputStream>(){
			@Override
			public boolean hasMoreElements() {
				return it.hasNext();
			}
			@Override
			public FileInputStream nextElement() {
				return it.next();
			}	
		};
//		構造函數爲一個Enumeration對象,合併這些流
		SequenceInputStream sis = new SequenceInputStream(en);
		FileOutputStream fos = new FileOutputStream("2.mp3");
		byte[] buf = new byte[1024];
		int len =0;
		 while((len =sis.read(buf))!=-1){
			 fos.write(buf, 0, len);
			 fos.flush();
		 }
		 fos.close();
		 sis.close();
	}	
}

    7.2、管道流:PipedInputStream和PipedOutputStream:可以合併兩個流,涉及到多線程。

8、演示管道流:

package itheima.day21;

import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

//管道流
public class PipedStreamDemo {

	public static void main(String[] args) throws IOException {
		PipedInputStream in = new PipedInputStream();
		PipedOutputStream out = new PipedOutputStream();
//		鏈接
		in.connect(out);
//		把管道輸入流與管道輸出流封裝成線程的任務
		Read r = new Read(in);
		Write w = new Write(out);
//		線程啓動
		new Thread(r).start();
		new Thread(w).start();
	}
}
//讀取的任務,封裝到一個線程中
class Read implements Runnable{	
	
	private PipedInputStream in;
	Read(PipedInputStream in){
		this.in = in;
	}
	@Override
	public void run() {
		byte[] buf = new byte[1024];
		try {
			int len = in.read(buf);
			String s = new String(buf,0,len);
			System.out.println(s);
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
//寫出的任務,封裝到一個線程中
class Write implements Runnable{
	
	private PipedOutputStream out;
	Write(PipedOutputStream out){
		this.out = out;
	}
	@Override
	public void run() {
		try {
			out.write("lai le ,ge men ,heihei ".getBytes());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

    7.3、RandomAccessFile:隨機訪問,自身具備讀寫方法,通過skipBytes(int x)和seek(int x)來實現隨機訪問。

    7.4、PrintWriter和PrintStream:可以直接轉換輸入流和文件。

代碼演示:

package itheima.day20;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

//凡是與流對象相關聯的對象,都是比較重要的流對象
//打印流:該流提供了打印方法,可以將各種數據類型的數據都原樣打印
//字節打印流:PrintStream
//構造函數可以接收的參數類型:
//1、file對象  File
//2、字符串路徑  String
//3、字節輸出流 OutputStream

//字符打印流 PrintWriter
//構造函數可以接收的類型:
//1、file對象  File
//2、字符串路徑  String
//3、字節輸出流 OutputStream
//4、字符輸出流 Writer
public class PrintStreamDemo {

	public static void main(String[] args) throws IOException {
//		字節流轉換成字符流,並加入緩衝區技術
		BufferedReader bufr = 
				new BufferedReader(new InputStreamReader(System.in));
//		通用性極強,指定打印目的。並自動刷新,對write方法無效
		PrintWriter  out = new PrintWriter(System.out,true);
		String line = null;
		while((line = bufr.readLine())!=null){
			if("over".equalsIgnoreCase(line))
				break;
			out.println(line.toUpperCase());
//			out.write(line.toUpperCase());
		}
		out.close();
		bufr.close();
	}
}

    7.5、ObjectInputStream和ObjectOutputStream:操作對象,但被操作的對象需要實現Serializable接口(一個標記接口,沒有要覆蓋的方法)。

代碼演示:

package itheima.day21;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

//直接操作對象的流
public class ObjectInputStreamDemo {

	public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
		writeObj();
		readObj();
	}
//	將對內存中的對象存到硬盤上
	public static void writeObj() throws FileNotFoundException, IOException{
//		必須關聯一個輸出流
		ObjectOutputStream oos = 
				new ObjectOutputStream(new FileOutputStream("person.obj"));
		oos.writeObject(new Person("lisi",45));
		oos.close();
	}
//	讀取硬盤上存儲的對象
	public static void readObj() throws FileNotFoundException, IOException, ClassNotFoundException{
//		必須關聯一個輸入流
		ObjectInputStream ois = 
				new ObjectInputStream(new FileInputStream("person.obj"));
		Person p = (Person)ois.readObject();
		System.out.println(p);
		ois.close();
	}
	
}
class Person implements Serializable
{
//	序列號是根據成員變量構造出來的
	static final long serialVersionUID = 42L;//可以自己指定一個ID號
	private String name;
	private int age;//transient 不序列化
	static public String country = "cn";
//	靜態不能序列化,序列化只能是堆內存中的數據
	Person(String name,int age ){
		this.name = name;
		this.age  = age;
	}
	
	public String toString(){
		return name+"::"+age+":::"+country;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}

    7.6、DataInputStream和DataOutputStream:操作基本數據類型。

    7.7、ByteArrayInputStream與ByteArrayOutputStream:操作字節數組;

         CharArrayReader與CharArrayWriter :操作字符數組;

                   StringReader 與 StringWriter:操作字符串;

八、字符編碼

    字符流的出現是爲了方便操作字符,字符流 = 字節流+編碼;字符流是先獲取到一定的字節,然後通過查閱相應的編碼表,變成相應的字符,其實計算機中存儲的是二進制形式的字節碼。

    InputStreamReader、OutputStreamWriter這兩個轉換流在字符流與字節流的轉換時,可以指定特定的編碼表,指定編碼表的動作可以由構造函數完成,詳情可以查閱API ,(UnsupportedEncodingException)。

    編碼表:計算機只能識別二進制數據,早期由來是電信號,爲了方法計算機的使用,讓它識別不同國家的文字,那麼將各個國家的文字用特定的數字在計算機中表示,並一一對應,形成了一張映射表,這張現實生活中的文字與計算機中二進制數據一一對應的映射表,稱爲編碼表。

    常見編碼表:

    1、ASCII:美國標準信息交換碼,用一個字節的7位表示;

    2、ISO8859-1:拉丁碼錶,歐洲碼錶;用一個字節的8位表示;

    3、GBK2312:中國的中文編碼表;

    4、GBK:中國的中文編碼升級版,融合了更多的中文文字符號,兩個字節表示;

    5、Unicode:國際標準碼,融合了多種文字,兩個字節表示;

    6、UTF-8:可以理解爲Unicode的優化版,最多用三個字節表示一個字符。

    編碼:字符串-->字節數組:String-->byte[]  s.getBytes(charsetName);

    解碼:字節數組-->字符串:Byte[]-->String  new String(byte[],charsetName);

    當發生亂碼時,可以先解碼,然後再重新編碼即可。例如:將一箇中文用gbk編碼,用iso8859-1解碼,亂碼;解決方式:對亂碼進行iso8859-1編碼,再用gbk解碼即可。

    但:用gbk編碼,用utf-8解碼,亂碼,再用utf-8編碼,用gbk解碼還是亂碼。這是因爲:用gbk編碼後的數字去查utf-8的碼錶時utf-8不識別,就直接用一個未知字符來表示,而這個未知字符是3個字節的;原數字碼已經變化了,所以還原不回來,亂碼。

9、編碼演示1:

package itheima.day21;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

public class EncodeDemo {
	public static void main(String[] args) throws UnsupportedEncodingException {
		String s = "你好";
		byte[] b1 = s.getBytes("GBK");
		System.out.println(Arrays.toString(b1));//[-60, -29, -70, -61]
		
		String s1 = new String(b1,"GBK");
		System.out.println("s1 = "+s1);//s1 = 你好
		
		byte[] b2 = s.getBytes("UTF-8");
		
		System.out.println(Arrays.toString(b2));//[-28, -67, -96, -27, -91, -67]
		String s2 = new String(b2,"UTF-8");
		System.out.println("s2 = "+s2);//s2 = 你好
		
//		”聯通“的GBK編碼正好符合了UTF-8的解碼形式
		String ss = "聯通";//u8加有自己的標識頭
		byte[] by = ss.getBytes("gbk");
		
		for(byte b:by){
			System.out.println(Integer.toBinaryString(b&255));
		}	
	}
}

10、編碼演示2:

package itheima.day21;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;

public class EncodeStream {

	public static void main(String[] args) throws IOException {
		writeText();
		readText();
	}
	public static void writeText() throws IOException{
//		轉換流可以指定編碼表
		OutputStreamWriter osw =
				new OutputStreamWriter(new FileOutputStream("utf.txt"),"UTF-8");
		osw.write("你好");
		osw.close();
	}
	public static void readText() throws IOException{
		
		InputStreamReader isr = new InputStreamReader(new FileInputStream("utf.txt"),"GBK");
		
		char[] buf = new char[10];
		int len = isr.read(buf);
		String str = new String(buf,0,len);
		System.out.println(str);
		isr.close();
	}
}

11、綜合練習一枚:

package itheima.day21;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

/*有五個學生,每個學生有3們課的成績,從鍵盤輸入以上數據(姓名,成績)
 * 輸入格式:zs,56,48,59計算出總成績
 * 並把學生的信息和計算出的總分按高低順序存放在磁盤文件"stud.txt"中。
 * */
/*1、描述學生對象
 * 2、定義一個可操作學生對象的工具類
 * 思想:
 * 1、通過獲取鍵盤錄入一行數據,並將該行中的信息取出封裝成爲學生對象
 * 2、因爲學生有很多,那麼就需要存儲,使用集合,要排序,TreeSet
 * 3、將集合中的信息寫入到一個文件中
 * */

public class StudentInfoTest {

	public static void main(String[] args) throws IOException {
		
		Comparator<Student> cmp = Collections.reverseOrder();
		Set<Student> stus = StudentInfoTool.getStudents(cmp);
		StudentInfoTool.write2File(stus);
	}
}

class Student implements Comparable<Student>
{
	private String name;
	private int math,chinese,english;
	private int sum;
	
	Student(String name,int math,int chinese,int english){
		this.name = name;
		this.math = math;
		this.chinese = chinese;
		this.english = english;
		this.sum = math+chinese+english;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getSum() {
		return sum;
	}

	public void setSum(int sum) {
		this.sum = sum;
	}

	@Override
	public int hashCode() {
		return name.hashCode()+sum*23;
	}

	@Override
	public boolean equals(Object obj) {
		if(!(obj instanceof Student))
				throw new ClassCastException("類型不匹配異常");
		Student stu = (Student)obj;
		return this.name.equals(stu.name) && (this.sum == stu.sum);
	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", math=" + math + ", chinese="
				+ chinese + ", english=" + english + ", sum=" + sum + "]";
	}

	@Override
	public int compareTo(Student o) {
		int  num = this.sum - o.sum;
		if(num==0)
			return this.name.compareTo(o.name);
		return num;
	}	
}

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("student.txt"));
		
		for(Student stu:stus){
			bufw.write(stu.toString());
			bufw.newLine();
			bufw.flush();
		}
		bufw.close();
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章