IO-File類、Properties類、打印流、序列流、字符編碼

一、File類 
 
1、概述
File類:文件和目錄路徑名的抽象表現形式
特點:
        a、用來將文件或文件夾封裝成對象
        b、方便於對文件與文件夾的屬性信息進行操作
        c、File對象可以作爲參數傳遞給流的構造函數
File對象創建:
方式一:File f =new File("a.txt");
將a.txt封裝成File對象。可以將已有的和不存在的文件或者文件夾封裝成對象。
方式二:File f2=newFile("c:\\abc","b.txt");
將文件所在目錄路徑和文件一起傳入,指定文件路徑。
方式三:File d=new File("c:\\abc");
              File f3=new File(d,"c.txt");
將文件目錄路徑封裝成對象。再創建文件對象。降低了文件與父目錄的關聯性。
 
File.separator表示目錄分隔符,可以跨平臺使用。
 
2、常見方法。
 
a、創建
        boolean createNewFile(); //在指定位置創建文件,如果該文件已經存在,則不創建,返回false。和輸出流不一樣,輸出流對象一建立就創建文件。而且文件已經存在,會覆蓋。
        boolean mkdir();//創建文件夾,只能創建一級文件夾
        boolean mkdirs();//創建多級文件夾

b、刪除
        boolean delete(); //刪除文件或目錄。文件存在,返回true;文件不存在或者正在被執行,返回false。    
        void deleteOnExit();//在程序退出時刪除指定文件

c、判斷
        boolean canExecute();//是否是可執行文件
        boolean exists();//文件是否存在
        boolean isFile();//是否是文件
        boolean isDirectory();//是否是文件夾
        boolean isHidden();//是否是隱藏文件
        boolean isAbsolute();//文件是否是絕對路徑
        記住:在判斷文件對象是否是文件或者目錄時,必須要判斷該文件對象封裝的內容是否存在。通過exists判斷。
 
d、獲取信息
        String getName();//獲取文件名
        String getPath(); //獲取文件的相對路徑(即創建的對象傳入的參數是什麼就獲取到什麼)
        String getParent(); //獲取文件父目錄。返回的是絕對路徑中的父目錄。如果獲取的是相對路徑,返回null。如果相對路徑中有上一層目錄,那麼該目錄就是返回結果。
        String getAbsolutePath();//獲取文件的絕對路徑      
        long lastModified();//返回文件最後一次被修改的時間
        long length();//返回文件長度
 
        boolean renameTo(File dest):重命名
 
e、列出文件及文件過濾
        static File[] listRoots();//列出可用的文件系統根目錄,即系統盤符
        String[] list();
        //列出當前目錄下所有文件,包括隱藏。調用list方法的file對象必須是封裝了一個目錄。該目錄還必須存在。
        String[]list(FilenameFilter filter);
        //返回一個字符串數組,獲取目錄中滿足指定過濾器的文件或目錄。
        FilenameFilter:文件名過濾器,是一個接口,其中包含一個方法,accept(Filedir,String name),返回的是boolean型,對不符合條件的文件過濾掉。
        File[] listFiles();//返回一個抽象路徑名數組,獲取當前文件夾下的所有文件和文件夾
        File[] ListFiles(FilenameFilterfilter);//返回抽象路徑名數組,獲取目錄中滿足指定過濾器的文件或目錄。
 
代碼示例:
import java.io.*;
/*
File類常見方法:
1,創建。
	boolean createNewFile():在指定位置創建文件,如果該文件已經存在,則不創建,返回false。
							和輸出流不一樣,輸出流對象一建立就創建文件。而且文件已經存在,會覆蓋。
	boolean mkdir():在已存在的文件夾下創建文件夾。
	boolean mkdirs():創建多級文件夾。
2,刪除。
	boolean delete():刪除文件或目錄。文件存在,返回true;文件不存在或者正在被執行,返回false。    
    void deleteOnExit();//在程序退出時刪除指定文件
3,判斷。
	boolean exists():文件是否存在。
	boolean canExecute():文件是否能執行。
	boolean isFile():是否是文件。
	boolean isDirectory():是否是目錄。
	boolean isHidden():是否是隱藏文件。
	boolean isAbsolute():路徑是否是絕對路徑。即使文件不存在,也會判斷是不是絕對路徑。
	 
4,獲取信息。
	String getName():返回文件名。
	String getPath():返回文件路徑。
	String getParent():返回父目錄。該方法返回的是絕對路徑中的父目錄;如果相對路徑中有上一層目錄則返回該目錄;如果獲取的是相對路徑則返回null。
					   例:文件路徑爲絕對路徑c:\\abc\\file.txt,返回c: \abc;
					       文件路徑爲相對路徑abc\\file.txt,返回\abc;
						   文件路徑爲相對路徑file.txt,返回null;
 
	String getAbsolutePath():返回文件的絕對路徑。
	long lastModified():最後一次被修改的時間。
	long length():文件的長度。
 
	boolean renameTo(File dest):重命名
 
5,列出文件及文件過濾
	static File[] listRoots();//列出可用的文件系統根目錄,即系統盤符
 
    String[] list();//列出當前目錄下所有文件,包括隱藏。調用list方法的file對象必須是封裝了一個目錄。該目錄還必須存在。
    
	String[]list(FilenameFilter filter);//返回一個字符串數組,獲取目錄中滿足指定過濾器的文件或目錄。
    FilenameFilter:文件名過濾器,是一個接口,其中包含一個方法,boolean accept(File dir,String name):對不符合條件的文件過濾掉。
    
	File[] listFiles();//返回一個抽象路徑名數組,獲取當前文件夾下的所有文件和文件夾
    File[] ListFiles(FilenameFilter filter);//返回抽象路徑名數組,獲取目錄中滿足指定過濾器的文件或目錄。
*/
import java.io.*;
class FileDemo  
{
	public static void main(String[] args) throws IOException
	{
		list();
	}
 
	public static void list()
	{		
		File dir = new File("d:");//調用list方法的file對象必須是封裝了一個目錄。該目錄還必須存在。
		//列出當前目錄下所有文件,包括隱藏。
		String[] names = dir.list();
		for(String name : names)
		{
			sop(name);
		}
		sop("---------------------------------------");
		//返回一個字符串數組,獲取目錄中滿足指定過濾器的文件或目錄。
		String[] jpg = dir.list(new FilenameFilter()//FilenameFilter 接口只有一個accept方法,可以使用匿名內部類。
		{
			public boolean accept(File dir,String name)
			{
				return name.endsWith(".JPG");
			}
		});
		for(String name : jpg)
		{
			sop(name);
		}
		sop("---------------------------------------");
		//返回一個抽象路徑名數組,獲取當前文件夾下的所有文件和文件夾
		File[] files = dir.listFiles();
		for(File f : files)
		{
			sop(f.getName()+"--"+f.length());
		}
 
	}
 
	public static void listRoots()
	{
		File[] files = File.listRoots();
		for(File file : files)
		{
			sop(file);
		}
	}
	public static void method()throws IOException
	{
		//創建File對象
		File f = new File("file.txt");
 
		//在指定位置創建文件,如果該文件已經存在,則不創建,返回false。
		f.createNewFile();
 
		//刪除文件或目錄。文件存在,返回true;文件不存在或者正在被執行,返回false。    
		//f.delete();
 
		//在程序退出時刪除指定文件
		//f.deleteOnExit();
 
		//創建文件夾
		File dir = new File("abc");
		dir.mkdirs();
		//創建多級文件夾。
		File dir1 = new File("abc\\kkk\\ddd\\fd\\dd");
		dir.mkdirs();
 
		//在判斷文件對象是否是文件或目錄時,必須要先判斷該文件對象封裝的內容是否存在
		//通過exists判斷。
		f.exists();//文件是否存在。
		f.canExecute();//文件是否能執行。
		f.isFile();//是否是文件
		f.isDirectory();//是否是目錄。
		f.isAbsolute();//路徑是否是絕對路徑。
 
		f.getPath();//返回文件路徑。
		f.getAbsolutePath();//返回文件的絕對路徑。
		f.getParent();//該方法返回的是絕對路徑中的父目錄。如果獲取的是相對路徑則返回null。
		f.renameTo(new File("d:\\haha.txt"));
 
 
	}
 
	//創建File對象
	public static void consMethod()throws IOException
	{
		//將a.txt封裝成對象。可以將已有的或未出現的文件或文件夾封裝成對象。
		File f1 = new File("a.txt");
 
		File f2 = new File("c:\\abc","b.txt");
 
		File d = new File("c:\\abc");
		File f3 = new File(d,"c.txt");
 
		//File f4 = new File("c:\\abd\\c.txt");
		//File.separator表示目錄分隔符,可以跨平臺使用。
		File f4 = new File("c:"+File.separator+"abd"+File.separator+"c.txt");
	}
 
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}
 
3、遞歸
遞歸:
1,限定條件
2,要注意遞歸的次數,儘量避免內存溢出。因爲每次調用自身的時候都會先執行下一次調用自己的方法,所以會不斷在棧內存中開闢新空間,次數過多,會導致內存溢出。
 
例:列出指定目錄下文件或文件夾,包含子目錄中的內容。
import java.io.*;
/*
列出指定目錄下文件或文件夾,包含子目錄中的內容。
 
遞歸:
1,限定條件
2,要注意遞歸的次數,儘量避免內存溢出。
 
*/
class  Filelist
{
	public static void main(String[] args) 
	{
		File dir = new File("g:\\myjava");
		showDir(dir);
	}
 
	public static void showDir(File dir)
	{
		sop(dir+"---------");
		File[] files = dir.listFiles();
		for(File f : files)
		{
			if(f.isDirectory())
				showDir(f);
			else
				sop(f);
		}
	}
 
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}
例:刪除一個帶內容的目錄。
import java.io.*;
/*
刪除一個帶內容的目錄。
刪除原理:
在windows中,刪除目錄是從裏往外刪的。
既然是從裏往外刪除,就要用到遞歸。
*/
 
class RemoveDir 
{
	public static void main(String[] args) 
	{
		File dir = new File("d:\\a");
		removeDir(dir);
	}
	public static void removeDir(File dir)
	{
		File[] files = dir.listFiles();
		for(File f : files)
		{
			if(!f.isHidden()&&f.isDirectory())
				removeDir(f);
			else
				f.delete();
		}
		dir.delete();
	}
}
例:將一個指定目錄下的java文件的絕對路徑,存儲到一個文本文件中。建立一個java文件列表清單。
import java.io.*;
import java.util.*;
/*
將一個指定目錄下的java文件的絕對路徑,存儲到一個文本文件中。
建立一個java文件列表清單。
 
思路: 
1、對指定的目錄進行遞歸。 
2、獲取遞歸過程所有的java文件的路徑。 
3、將這些路徑存儲到集合中。 
4、將集合中的數據寫入到一個文件中。 
 
*/
 
 
class JavaFileList 
{
	public static void main(String[] args) 
	{
		File dir = new File("g:\\myjavacode");
		List<File> list = new ArrayList<File>();
		fileToList(dir,list);
		System.out.println(list.size());
 
		writeToFile(list,"g:\\myjavacode\\javalist.txt");
	}
 
	public static void fileToList(File dir,List<File> list)
	{
		File[] files = dir.listFiles();
		for(File f : files)
		{
			if(f.isDirectory())
				fileToList(f,list);
			else
			{
				if(f.getName().endsWith(".java"))
					list.add(f);
			}
		}
	}
 
	public static void writeToFile(List<File> list,String javaListFile)
	{
		BufferedWriter bw = null;
		try
		{
			bw = new BufferedWriter(new FileWriter(javaListFile));
			for(File f : list)
			{
				String path = f.getAbsolutePath();
				bw.write(path);
				bw.newLine();
				bw.flush();
			}
		}
		catch (IOException e)
		{
			System.out.println(e.toString());
		}
		finally
		{
			try
			{
				if(bw!=null)
					bw.close();
			}
			catch (IOException e)
			{
				System.out.println(e.toString());
			}
		}
	}
}
 
二、Properties類
 
1、概述
    Properties是Hashtable的子類,它具備Map集合的特點。而且它裏面 存儲的鍵值對都是字符串,無泛型定義。是集合中和IO技術想結合的集合容器。
    特點:
        1)可用於鍵值對形式的配置文件
        2)在加載時,需要數據有固定的格式,常用的是:鍵=值
 
2、特有方法
1、設置
        Object setProperty(String key,String value);//設置鍵和值
2、獲取
        String getProperty(String key); //指定key獲取value
        Set<String> stringPropertyName();//返回屬性列表的鍵集,存入Set集合
3、加載流和存入流
        void load(InputStream instream); //將字節流中的數據加載進集合。
        void store(OutputStreamout,String comments);//對應load(InputStream )將屬性列表(鍵值對)寫入輸出流。comments屬性列表的描述。
 
        void load(Reader reader);//將字符流中的數據加載進集合。
        void store(Writerwriter, String comments);//對應load(Reader)將屬性列表(鍵值對)寫入輸出流。comments屬性列表的描述。
 
        void list(PrintStream out);//將屬性列表輸出到指定的輸出流
 
代碼示例: 
 
import java.io.*;
import java.util.*;
class PropertiesDemo 
{
	public static void main(String[] args) throws IOException
	{
		load();
	}
 
	public static void load()throws IOException
	{
		Properties prop = new Properties();
		FileInputStream fis = new FileInputStream("info.txt");
		
		//將流中數據加載進集合。
		prop.load(fis);
 
		prop.setProperty("lisi","99");//只能修改內存中的數據,文件中數據不會改變。
 
		FileOutputStream fos = new FileOutputStream("info.txt");
		prop.store(fos,"correct lisi age");
		System.out.println(prop);
	}
 
	/*
	想要將info.txt中的鍵值數據存到集合中進行操作。
	思路:
	1,用一個流和文件相關聯。
	2,讀取一行數據,將該行數據用“=”進行切割。
	3,等號左邊作爲鍵,右邊作爲值。存入到Properties集合中即可。
 
	*/
	public static void method()throws IOException
	{
		BufferedReader br = new BufferedReader(new FileReader("info.txt"));
		String line = null;
		Properties prop = new Properties();
		while((line=br.readLine())!=null)
		{
			String[] arr = line.split("=");
			prop.setProperty(arr[0],arr[1]);
		}
		br.close();
		System.out.println(prop);
	}
 
	public static void setAndGet()
	{
		Properties prop = new Properties();
		prop.setProperty("zhangsan","30");
		prop.setProperty("lisi","39");
		System.out.println(prop);
 
		String value = prop.getProperty("lisi");
		System.out.println(value);
		
		prop.setProperty("lisi","99");
 
		Set<String> names = prop.stringPropertyNames();
		for(String name : names)
		{
			System.out.println(name+":"+prop.getProperty(name));
		}
 
	}
}
例:用於記錄應用程序運行次數。如果使用次數已到,那麼給出註冊提示。
import java.io.*;
import java.util.*;
/*
需求:用於記錄應用程序運行次數。如果使用次數已到,那麼給出註冊提示。      
分析: 
很容易想到的是:計數器。可是該計數器定義在程序中,隨着該應用程序的退出,該計數器也在內存中消失了。 
所以要建立一個配置文件,用於記錄該軟件的使用次數。
該配置文件使用鍵值對的形式。鍵值對數據是map集合。
數據是以文件形式存儲。使用io技術。那麼map+io——>Properties。 
	 
思路:1、用讀取流關聯文本信息文件。如果存在則讀取,如果不存在,則創建 
      2、每次運行,將文件數據存入集合中,讀取值,判斷次數,如果小於等於5次,則次數增加1次,如果大於則輸出提示信息。 
      3、將值小於等於5次的信息數據存入文件中 
 
*/
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);
		prop.load(fis);
		int count = 0;
		String value = prop.getProperty("time");
		if(value!=null)
			count = Integer.parseInt(value);
			if (count>=5)
			{
				System.out.println("您好,使用次數已到,請註冊!");
				return ;
			}
		count++;
		prop.setProperty("time",count+"");
		FileOutputStream fos = new FileOutputStream(file);
		prop.store(fos,"");
		fos.close();
		fis.close();
 
	}	
}
  
 
 
三、打印流
 
1、概述
打印流包括:PrintStream和PrintWriter
該流提供了打印方法,可將各種類型的數據都原樣打印。
 
2、字節打印流:PrintStream
構造方法中可接收的參數類型:
        a、File對象。File
        b、字符串路徑:String
        c、字符輸出流:OutputStream
 
3、字符串打印流:PrintWriter
構造方法中可接受的參數類型
        a、File對象:File
        b、字符串路徑:String
        c、字節輸出流:OutputStream
        d、字符輸出流:Writer
 
代碼示例:
import java.io.*;
 
class PrintStreamDemo 
{
	public static void main(String[] args) throws IOException
	{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
 
		PrintWriter out = new PrintWriter(System.out,true);//true 代表自動刷新。
		String line = null;
		while ((line=br.readLine())!=null)
		{
			if("over".equals(line))
				break;
			out.println(line.toUpperCase());
			//out.flush();//刷新是針對流的
		}
		out.close();
		br.close();
	}
}
 
四、序列流
 
1、概述
SequenceInputStream對多個流進行合併。也被稱爲合併流。
常用構造函數
SequenceInputStream(Enumeration<?extends FileInputStream> e)
 
2、常見合併多個流文件步驟
        1、創建集合,並將流對象添加進集合
        2、創建Enumeration對象,將集合元素加入。
        3、創建SequenceInputStream對象,合併流對象
        4、創建寫入流對象,FileOutputStream關聯寫入文件
        5、利用SequenceInputStream對象和FileOutputStream對象讀數據進行反覆讀寫操作。
 
代碼示例:
import java.io.*;
import java.util.*;
class SequenceInputStreamDemo 
{
	public static void main(String[] args) throws IOException
	{
		Vector<FileInputStream> v = new Vector<FileInputStream>();
 
		v.add(new FileInputStream("d:\\1.txt"));
		v.add(new FileInputStream("d:\\2.txt"));
		v.add(new FileInputStream("d:\\3.txt"));
 
		Enumeration<FileInputStream> en = v.elements();
 
		SequenceInputStream sis = new SequenceInputStream(en);
 
		FileOutputStream fos = new FileOutputStream("d:\\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();
	}
}
例:切割併合並文件
import java.io.*;
import java.util.*;
 
class SplitFile 
{
	public static void main(String[] args) throws IOException
	{
		splitFile();
		mergeFile();
	}
	public static void splitFile()throws IOException
	{
		FileInputStream fis = new FileInputStream("d:\\1.JPG");
		FileOutputStream fos = null;
 
		byte[] buf = new byte[1024*1024];
 
		int len = 0;
		int count = 1;
		while((len=fis.read(buf))!=-1)
		{
			fos = new FileOutputStream("d:\\splitfiles\\"+(count++)+".part");
			fos.write(buf,0,len);
			fos.close();
		}
		fis.close();
	}
 
	public static void mergeFile()throws IOException
	{
		ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
		al.add(new FileInputStream("d:\\splitfiles\\1.part"));
		al.add(new FileInputStream("d:\\splitfiles\\2.part"));
		al.add(new FileInputStream("d:\\splitfiles\\3.part"));
		al.add(new FileInputStream("d:\\splitfiles\\4.part"));
		al.add(new FileInputStream("d:\\splitfiles\\5.part"));
 
		final Iterator<FileInputStream> it = al.iterator();  
        Enumeration<FileInputStream> en = new Enumeration<FileInputStream>()  
		{  
			public boolean hasMoreElements()  
			{  
				return it.hasNext();  
			}  
 
			public FileInputStream nextElement()  
			{  
				return it.next();  
			}  
		};
		
		SequenceInputStream sis = new SequenceInputStream(en);
		FileOutputStream fos = new FileOutputStream("d:\\0.JPG");
 
		byte[] buf = new byte[1024];
		int len = 0;
		while((len=sis.read(buf))!=-1)
		{
			fos.write(buf,0,len);
		}
		fos.close();
		sis.close();
	}
}
 
 
五、對象的序列化(持久化)
ObjectInputStream& ObjectOutputStrea
將對象數據從堆內存存入到硬盤中,將對象序列化。
代碼示例:
import java.io.*;
class  ObjectStreamDemo
{
	public static void main(String[] args) throws Exception
	{
		//writeobj();
		readobj();
		
	}
 
	public static void readobj()throws Exception
	{
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));
		
		Person p = (Person)ois.readObject();
		System.out.println(p);
		ois.close();
	}
 
	public static void writeobj()throws IOException
	{
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));
		oos.writeObject(new Person("lisi",30));
		oos.close();
	}
 
}
 
class Person implements Serializable
{
	static final long serialVersionUID = 42L;// 保證序列號唯一
	String name;
	transient int age;//transient修飾 非靜態也不會被序列化。
	static String country = "cn";//靜態是不能被序列化的。
	Person(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
	public String toString()
	{
		return name+":"+age+" "+country;
	}
}
 
六、管道流
PipedInputStream&PipedOutputStream
輸入輸出可以直接進行連接,通常結合線程使用。
代碼示例:
import java.io.*;
class Read implements Runnable
{
	private PipedInputStream in;
	Read(PipedInputStream in)
	{
		this.in = in;
	}
	public void run()
	{
		try
		{
			byte[] buf = new byte[1024];
			int len = in.read(buf);
			String s = new String(buf,0,len);
			System.out.println(s);
			in.close();
		}
		catch (IOException e)
		{
			throw new RuntimeException("管道讀取流失敗");
		}
	}
}
 
class Write implements Runnable
{
	private PipedOutputStream out;
	Write(PipedOutputStream out)
	{
		this.out = out;
	}
	public void run()
	{
		try
		{
			out.write("piped lai la".getBytes());
			out.close();
		}
		catch (IOException e)
		{
			throw new RuntimeException("管道輸出流失敗");
		}
	}
}
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();
	}
}
 
七、RandomAccessFile
    RandomAccessFile
    該類不算是IO體系中的子類。而是直接繼承自Object。
    但它是IO包中的成員,因爲它具備讀和寫的功能。
    內部封裝了一個數組,而且通過指針對數組的元素進行操作。
    可以通過getFilePointer獲取指針的位置,
    同時可以通過seek改變指針的位置。
 
    其實完成讀寫的原理就是內部封裝了字節輸入流和字節輸出流。
 
    通過構造函數可以看出,該類只能操作文件。
    而且操作文件還有模式:只讀r,讀寫rw.
    如果模式爲只讀 r :不會創建文件。會去讀一個已存在的文件,如果該文件不存在,則會出現異常。
    如果模式爲讀寫 rw :操作的文件不存在,會自動創建。如果存在則不會覆蓋。
代碼示例:
import java.io.*;
/*
RandomAccessFile
該類不算是IO體系中的子類。而是直接繼承自Object。
但它是IO包中的成員,因爲它具備讀和寫的功能。
內部封裝了一個數組,而且通過指針對數組的元素進行操作。
可以通過getFilePointer獲取指針的位置,
同時可以通過seek改變指針的位置。
 
其實完成讀寫的原理就是內部封裝了字節輸入流和字節輸出流。
 
通過構造函數可以看出,該類只能操作文件。
而且操作文件還有模式:只讀r,讀寫rw.
如果模式爲只讀 r :不會創建文件。會去讀一個已存在的文件,如果該文件不存在,則會出現異常。
如果模式爲讀寫 rw :操作的文件不存在,會自動創建。如果存在則不會覆蓋。
 
 
*/
class RandomAccessFileDemo 
{
	public static void main(String[] args) throws IOException
	{
		writeFile();
		System.out.println("Hello World!");
		readFile();
	}
 
	public static void readFile()throws IOException
	{		
		RandomAccessFile raf = new RandomAccessFile("raf.txt","r");
		//調整對象指針。
		raf.seek(8*0);
 
		//跳過指定的字節數
		raf.skipBytes(8);
 
		byte[] buf = new byte[4];
		raf.read(buf);
		String name = new String(buf);
		System.out.println("name="+name);
		int age = raf.readInt();
		System.out.println("age="+age);
 
		raf.close();
	}
 
	public static void writeFile()throws IOException
	{
		RandomAccessFile raf = new RandomAccessFile("raf.txt","rw");
		raf.write("李四".getBytes());
		raf.writeInt(97);//4個字節
		raf.write("王五".getBytes());
		raf.writeInt(99);
 
		raf.seek(8*3);
		raf.write("周七".getBytes());
		raf.writeInt(103);
		raf.close();
	}
}
 
八、操作基本數據類型的流對象DataInputStream& DataOutputStream
代碼示例:
import java.io.*;
 
class DataStreamDemo 
{
	public static void main(String[] args) throws IOException
	{
		writeData();
		System.out.println("Hello World!");
		readData();
	}
 
	public static void readData()throws IOException
	{		
		DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
 
		int n = dis.readInt();
		boolean b = dis.readBoolean();
		double d = dis.readDouble();
		
		System.out.println("n="+n);
		System.out.println("b="+b);
		System.out.println("d="+d);
 
		dis.close();
	}
 
	public static void writeData()throws IOException
	{
		DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
		
		dos.writeInt(234);
		dos.writeBoolean(true);
		dos.writeDouble(9888.756);
 
		dos.close();
	}
}
 
九、操作數組的流對象
ByteArrayInputStream&ByteArrayOutputStream
CharArrayReader&CharArrayWriter
StringReader&StringWriter
代碼示例:
import java.io.*;
/*
用於操作字節數組的流對象。
 
ByteArrayInputStream:在構造的時候,需要接收數據源。而且數據源是一個字節數組。
 
ByteArrayOutputStream:在構造的時候,不用定義數據目的,因爲該對象內部已經封裝了可變長度的字節數組。這就是數據目的地。
 
因爲這兩個流對象都操作數組,並沒有使用系統資源,所以不用close關閉。
 
源設備:
	鍵盤 System.in  硬盤 FileStream  內存 ArrayStream
目的設備:
	控制檯: System.out  硬盤 FileStream  內存 ArrayStream 
 
用流的讀寫思想來操作數據。
 
*/
class ByteArrayStreamDemo 
{
	public static void main(String[] args) throws IOException
	{
		//數據源
		ByteArrayInputStream bis = new ByteArrayInputStream("abcdefg".getBytes());
	
		//數據目的
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		int by = 0;
		while((by=bis.read())!=-1)
		{
			bos.write(by);
		}
		System.out.println(bos.size());
		System.out.println(bos.toString());
	}
}
 
十、字符編碼
 
1、常見編碼表
ASCII:美國標準信息交換碼。用一個字節的7位表示。
ISO8859-1:拉丁碼錶。歐洲碼錶。用一個字節的8位表示。
GB2312:中國的中文編碼表。
GBK:中國的中文編碼表升級。
Unicode:國際標準碼,融合了多種文字。所有文字都用兩個字節表示。
UTF-8:最多用三個字節表示一個字符。
 
例:轉換流的字符編碼
import java.io.*;
class EncodeStream 
{
	public static void main(String[] args) 
	{
		System.out.println("Hello World!");
	}
 
	public static void readText()throws IOException
	{
		InputStreamReader isr = new InputStreamReader(new FileInputStream("utf.txt","UTF-8"));
		char[] buf = new char[10];
		int len = isr.read(buf);
		String s = new String(buf,0,len);
		System.out.println(s);
		isr.close();
	}
	
	public static void writeText()throws IOException
	{
		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("utf.txt","UTF-8"));
		osw.write("你好");
		osw.close();
	}
}
例:編解碼
import java.util.*;
/*
編碼:字符串變成字符數組。
解碼:字符數組變成字符串。
 
String-->byte[]; str.getBytes(charsetName);
 
byte[]-->String; new String(byte[],charsetName);
*/
class  EncodeDemo
{
	public static void main(String[] args) throws Exception
	{
		String s = "你好";
		byte[] b1 = s.getBytes("GBK");
		System.out.println(Arrays.toString(b1));
 
		String s1 = new String(b1,"ISO8859-1");
		System.out.println(s1);
 
		byte[] b2 = s1.getBytes("ISO8859-1");
		System.out.println(Arrays.toString(b2));
 
		String s2 = new String(b2,"GBK");
		System.out.println(s2);
	}
}
例:從鍵盤輸入學生信息,計算學生總成績,並把學生信息和計算出的總分數高低順序存放在磁盤文件“stuinfo.txt”中。
/*
有五個學生,每個學生有三門課的成績。
從鍵盤輸入以上數據(包括姓名,三門課成績)。
輸入格式:zhangsan,30,40,50。
計算出總成績,並把學生信息和計算出的總分數高低順序存放在磁盤文件“stuinfo.txt”中。
 
1,描述學生類。
2,定義一個可操作學生對象的工具類。
 
思路;
1,通過獲取鍵盤錄入一行數據,並將該行中的信息取出封裝成學生對象。
2,因爲學生有很多,那麼就需要存儲,使用到集合。因爲要對學生的總分排序。所以可以使用TreeSet集合。
3,將集合信息寫入文件中。
*/
import java.io.*;
import java.util.*;
 
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;
		sum = math + chinese + english;
	}
	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;
	}
	public int hashCode()
	{
		return name.hashCode()+sum*78;
	}
	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;
	}
	public String toString()
	{
		return "studet["+name+", "+math+", "+chinese+", "+english+"]";
	}
}
 
class StudentInfoTool
{
	public static Set<Student> getStudents()throws IOException
	{
		return getStudents(null);
	}
	public static Set<Student> getStudents(Comparator<Student> cmp)throws IOException
	{
		BufferedReader br = 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=br.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);
		}
		br.close();
		return stus;
	}
 
	public static void write2File(Set<Student> stus)throws IOException
	{
		BufferedWriter bw = new BufferedWriter(new FileWriter("stuinfo.txt"));
		for(Student stu : stus)
		{
			bw.write(stu.toString()+"\t");
			bw.write(stu.getSum()+"");
			bw.newLine();
			bw.flush();
		}
		bw.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);
		System.out.println("Hello World!");
	}
}
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章