1. 程式人生 > >黑馬程式設計師-JAVA高階(IO輸入與輸出)PART3

黑馬程式設計師-JAVA高階(IO輸入與輸出)PART3

---------------------- ASP.Net+Android+IOS開發.Net培訓、期待與您交流! ----------------------

這部分的內容主要有以下幾個知識點:

1.File類;

2.Properties類;

3.IO體系的其他一些流;

一、File類

File類用來將檔案或者資料夾封裝成物件,方便對檔案和資料夾的屬性資訊進行操作。同時,File物件可以作為引數傳遞給流的建構函式。

1.常用的三種建構函式

//File(String pathname);
File f1 = new File("a.txt");

//File(String parent, String child);
File f2 = new File("c:\\abc","b.txt");

//File(File parent, String child);
File d = new File("c:\\abc");
File f3 = new File(d,"c.txt");
小點:File.separator,跨平臺的目錄分隔符。

2.File物件的常見方法

建立:

createNewFile():在指定位置建立檔案,如果該檔案已經存在,則不建立返回false

mkdir():建立目錄(資料夾)。

mkdirs():建立多級目錄。

刪除:

delete():刪除檔案或資料夾,如果刪除的是資料夾,只有當資料夾為空時才可以刪除成功。

deleteOnExite():當程式退出時刪除指定檔案或資料夾。

判斷:

canExecute():判斷是否可執行。

canRead():判斷是否可讀。

canWrite():判斷是否可修改。

exists():判斷檔案是否存在。

isFile():判斷是否是檔案。

isDirectory():判斷是否是目錄(資料夾)。

isHidden():判斷是否隱藏。

isAbsolute():判斷是否是絕對路徑。

獲取資訊:

getName():獲取名稱。

getParent():獲取父目錄,如果沒有指定,返回null。

getPath():獲取路徑名。

getAbsolutePath():獲取絕對路徑名。

lastModified():獲取最後一次修改的時間。

length():獲取檔案的長度。

其他:

renameTo(File dest):重新命名檔案。

list():列出目錄下的所有檔案和目錄名。

list(FilenameFilter filter)

:列出滿足過濾器的檔案和目錄。

listRoots():列出可用的檔案系統根目錄。

示例程式碼1

/*
File類
*/
import java.io.*;

class FileDemo 
{
	public static void main(String[] args) throws IOException
	{
		//consMethod();	
		method_4();
	}

	//renameTo()
	public static void method_4() 
	{
		File f1 = new File("c:\\version.conf");
		File f2 = new File("d:\\nimei.conf");

		f2.renameTo(f1);
	}

	//獲取資訊
	public static void method_3() throws IOException
	{
		File f = new File("nimei\\file.txt");

		sop("path:"+f.getPath());//獲取路徑
		sop("abspath:"+f.getAbsolutePath());//獲取絕對路徑
		sop("parent:"+f.getParent());//只有當封裝的是多級目錄時才有返回值,否則返回null
		sop("lastModified:"+f.lastModified());
		sop("length:"+f.length());
	}

	//判斷
	public static void method_2() throws IOException
	{
		File f = new File("file.txt");

		sop(f.mkdir());
		//sop(f.createNewFile());

		sop("canExecute:"+f.canExecute());
		sop("canRead:"+f.canRead());
		sop("canWrite:"+f.canWrite());
		sop("exists:"+f.exists());
		sop("isAbsolute:"+f.isAbsolute());//只判斷給的路徑,不必檔案或目錄存在
		//在判斷檔案物件是否是檔案或目錄時,必須先通過exists()判斷該檔案物件封裝的內容是否存在
		sop("isFile:"+f.isFile());//判斷是否是檔案
		sop("isDirectory:"+f.isDirectory());//判斷是否是目錄
		sop("isHidden:"+f.isHidden());//判斷是否是隱藏的檔案
	}

	//建立和刪除
	public static void method_1() throws IOException
	{
		File f = new File("aaa\\bbb\\ccc\\ddd\\eee\\fff");

		//f.deleteOnExit();//當程式退出時刪除指定檔案
		//如果建立成功返回true,如果需要建立的檔案已經存在則建立失敗,這點與流不同
		//sop("create:"+f.createNewFile());
		//sop("delete:"+f.delete());//刪除檔案或資料夾,如果是資料夾只有當期為空的時候才可以刪除,否則刪除失敗

		//sop("mkdir:"+f.mkdir());//建立目錄(資料夾),只能已存在的目錄下建立一級目錄
		sop("mkdirs:"+f.mkdirs());//建立多級目錄
	}

	//建立File物件,可以將已有的和未出現的檔案或者資料夾封裝成物件
	public static void consMethod()
	{
		//File(String pathname);
		File f1 = new File("a.txt");
		//File(String parent, String child);
		File f2 = new File("c:\\abc","b.txt");
		//File(File parent, String child);
		File d = new File("c:\\abc");
		File f3 = new File(d,"c.txt");

		//跨平臺的目錄分隔符,File.separator
		File f4 = new File("c:"+File.separator+"aaa"+File.separator+"bbb"+
			File.separator+"d.txt");

		sop("f1:"+f1);
		sop("f2:"+f2);
		sop("f3:"+f3);
		sop("f4:"+f4);
	}

	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}
示例程式碼2
import java.io.*;

class FileDemo2 
{
	public static void main(String[] args) 
	{
		//listRootsDemo();
		listFilterNameDemo();
	}

	//File物件的list(FilenameFilter filter)方法
	//只打印.java檔案
	public static void listFilterNameDemo()
	{
		File f = new File("d:\\bxdjavademo");
		String[] names = f.list(new FilenameFilter(){
			public boolean accept(File dir,String name){
				//System.out.println(dir);
				//System.out.println(name);
				/*
				if(name.endsWith(".mkv"))
					return true;
				return false;
				*/
				return name.endsWith(".java");
			}
		});

		for(String name:names)
			System.out.println(name);
	}

	//File物件的list()方法
	public static void listDemo()
	{
		File f = new File("c:\\");//使用list方法的File物件必須是目錄,該目錄還必須存在
		String[] names = f.list();
		//會列印c盤下所有的檔案和目錄,包括隱藏的
		for(String name:names)
		{
			System.out.println(name);
		}
	}

	//File類的listRoots()方法
	public static void listRootsDemo()
	{
		File[] files = File.listRoots();

		for(File f:files)
		{
			System.out.println(f);
		}
	}
}

3.列出目錄下的所有內容-遞迴

需求:列出指定目錄下的檔案和資料夾,包含子目錄中的內容。

分析:因為目錄中還有目錄,只要使用同一個列出目錄功能的函式完成即可。在列出過程中出現的還是目錄的話,可以再次呼叫本功能,也就是函式自身呼叫自身。這種表現形式或程式設計手法,成為遞迴。

遞迴要注意:限定條件;注意遞迴的次數,避免記憶體溢位。

/*
列出指定目錄下的所有內容,包括檔案和資料夾以及資料夾中的內容
*/
import java.io.*;

class FileDemo3 
{
	public static void main(String[] args) 
	{
		File dir = new File("D:\\testdir");
		showDir(dir);
		//toBin(6);
		//System.out.println("\r\nsum:"+getSum(9000));//注意遞迴次數,避免記憶體溢位
	}

	public static void showDir(File dir)
	{
		/*
		如果是第一級目錄則列印整個絕對路徑,
		否則只打印檔案或者資料夾的名字
		*/
		System.out.println(dir);;

		File[] files = dir.listFiles();
		for(File file:files)
		{
			if(file.isDirectory())
				showDir(file);
			else
				System.out.println(file);
		}
	}


	//使用遞迴的方法獲取從1到num的連續整數的和
	public static int getSum(int num)
	{
		if(num==1)
			return 1;
		else
			return num+getSum(num-1);
	}

	//用遞迴的方法列印一個正整數的二進位制形式
	public static void toBin(int num)
	{
		if(num>0)
		{
			toBin(num/2);
			System.out.print(num%2);
		}
	}
}
優化以上程式碼,使不同級的目錄帶層次
/*
列出指定目錄下的所有內容,帶層次
*/
import java.io.*;

class FileDemo4 
{
	public static void main(String[] args) 
	{
		File dir = new File("D:\\testdir");

		showDir(dir,0);
	}

	public static String getLevel(int level)
	{
		StringBuilder sb = new StringBuilder();
		sb.append("|--");
		for(int x=0;x

4.刪除帶內容的目錄 原理,在windows中,刪除目錄是從裡往外刪除的,所以就需要用到遞迴。
/*
刪除帶內容的目錄
*/
import java.io.*;

class RemoveDirDemo
{
	public static void main(String[] args) 
	{
		File dir = new File("d:\\testdir");
		deleteFile(dir);
	}

	public static void deleteFile(File dir)
	{
		File[] files = dir.listFiles();
		for(File file : files)
		{
			if(file.isDirectory())//判斷是否是目錄,如果是,遞迴執行函式
				deleteFile(file);
			else
			{
				//刪除檔案,列印刪除結果
				String r = file.delete()?" success":" fail";
				sop("delete file "+file+r);
			}

		}

		//刪除目錄,列印刪除結果
		String rs = dir.delete()?" success":" fail";
		sop("delete dir "+dir+rs);
	}

	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}

5.建立Java檔案列表 將一個目錄下的所有java檔案的絕對路徑,儲存到一個文字檔案中。 思路: (1)對指定的目錄進行遞迴; (2)獲取遞迴過程中所有的java檔案; (3)將這些檔案物件儲存到集合中; (4)將集合中的資料寫入到一個檔案中。
/*
將一個指定目錄下的java檔案的絕對路徑儲存到一個文字檔案中,
建立一個java檔案列表
*/
import java.io.*;
import java.util.*;

class JavaListFileDemo 
{
	public static void main(String[] args) 
	{
		File dir = new File("d:\\bxdjavademo");
		List list = new ArrayList();

		fileToList(dir,list);

		//System.out.println(list.size());
		File file = new File(dir,"javalist.txt");
		writeToFile(file,list);
	}

	//將所有java檔案的File物件儲存到集合中
	public static void fileToList(File dir, List list)
	{
		File[] files = dir.listFiles();

		for(File file : files)
		{
			if(file.isDirectory())
				fileToList(file,list);
			else
				if(file.getName().endsWith(".java"))
					list.add(file);
		}
	}

	//將集合中File物件對應檔案的絕對路徑寫入到檔案中
	public static void writeToFile(File file,List list)
	{
		BufferedWriter bufw = null;
		try
		{
			bufw = new BufferedWriter(new FileWriter(file));
			for(File f:list)
			{
				String abspath = f.getAbsolutePath();
				bufw.write(abspath);
				bufw.newLine();
				bufw.flush();
			}
		}
		catch (IOException e)
		{
			/*
			如果throw e,則必須在該方法後面加上throws IOException
			如果throw new RuntimeException()則不用
			*/
			throw new RuntimeException("寫入失敗");
		}
		finally
		{
			if(bufw!=null)
				try
				{
					bufw.close();
				}
				catch (IOException e)
				{
					throw new RuntimeException("關閉失敗");
				}
		}
	}
}

二、Properties物件及其應用

Properties是hashtable的子類,具備map集合的特點,儲存的鍵值對都是字串。是集合中和IO技術相結合的容器。該物件可以用於鍵值對形式的配置檔案。在載入資料時,需要有固定格式,鍵=值。

1.Properties物件

/*
Properties物件
*/
import java.util.*;
import java.io.*;

class PropertiesDemo 
{
	public static void main(String[] args) 
	{
		//setAndGet();
		//method_1();
		loadDemo();
	}

	public static void loadDemo() 
	{
		Properties prop = new Properties();
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try
		{
			fis = new FileInputStream("info.txt");
			prop.load(fis);//從輸入流中讀取屬性列表

			prop.setProperty("wangwu","25");
			fos = new FileOutputStream("info.txt");
			prop.store(fos,"nimei,wocao");//將Properties中的屬性列表寫出到輸出流
		}
		catch (IOException e)
		{
			throw new RuntimeException("出現異常");
		}
		finally
		{
			if(fis!=null)
				try
				{
					fis.close();
				}
				catch (IOException e)
				{
					throw new RuntimeException("讀取流關閉異常");
				}
			if(fos!=null)
				try
				{
					fos.close();
				}
				catch (IOException e)
				{
					throw new RuntimeException("寫入流關閉異常");
				}
		}

		//System.out.println(prop);
		prop.list(System.out);
	}

	//將流中的資料儲存到集合中
	public static void method_1()
	{
		Properties prop = new Properties();
		BufferedReader bufw = null;
		try
		{
			bufw = new BufferedReader(new FileReader("info.txt"));
			String line = null;
			while((line=bufw.readLine())!=null)
			{
				String[] arr = line.split("=");
				prop.setProperty(arr[0],arr[1]);
			}
		}
		catch (IOException e)
		{
			throw new RuntimeException("讀取檔案異常");
		}
		finally
		{
			if(bufw!=null)
				try
				{
					bufw.close();
				}
				catch (IOException e)
				{
					throw new RuntimeException("關閉異常");
				}
		}

		System.out.println(prop);
	}

	//設定和獲取
	public static void setAndGet()
	{
		Properties prop = new Properties();

		prop.setProperty("zhangsan","39");
		prop.setProperty("lisi","38");

		//System.out.println(prop);
		Set names = prop.stringPropertyNames();
		for(String name:names)
			System.out.println(name+":"+prop.getProperty(name));
	}
}

2.記錄應用程式的啟動次數,如果達到使用次數限制則給出提示

建立一個配置檔案,用於記錄程式的啟動次數。配置檔案使用鍵值對的形式,便於閱讀和操作資料。配置檔案可以實現應用程式資料的共享。

/*
將應用程式的啟動次數寫入配置檔案中,
達到限制次數後,給出註冊提示
*/
import java.io.*;
import java.util.*;

class RunCountDemo 
{
	public static void main(String[] args) 
	{
		Properties prop = new Properties();
		File f = new File("count.ini");
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try
		{
			if(!f.exists())
				f.createNewFile();

			fis = new FileInputStream(f);
			prop.load(fis);

			int count = 0;
			String times = prop.getProperty("times");
			if(times!=null)
			{
				count = Integer.parseInt(times);
				if(count>=5)
				{
					System.out.println("您好,使用次數已到,請付錢");
					return;
				}
			}

			count++;
			prop.setProperty("times",count+"");

			fos = new FileOutputStream(f);
			prop.store(fos,null);

		}
		catch (IOException e)
		{
			throw new RuntimeException("流異常");
		}
		finally
		{
			if(fis!=null)
				try
				{
					fis.close();
				}
				catch (IOException e)
				{
					throw new RuntimeException("讀取流關閉異常");
				}
			if(fos!=null)
				try
				{
					fos.close();
				}
				catch (IOException e)
				{
					throw new RuntimeException("寫入流關閉異常");
				}
		}
	}
}

三、IO體系的一些其他流

1.PrintStream和PrintWriter

PrintStream建構函式可接收的引數型別:File物件;字串路徑String;位元組輸出流OutputStream

PrintWriter建構函式可接收的引數型別:File物件;字串路徑String;位元組輸出流OutputStream;字元輸出流Writer

import java.io.*;

class PrintWriterDemo 
{
	public static void main(String[] args) throws IOException 
	{
		BufferedReader bufw = new BufferedReader(new InputStreamReader(System.in));
		//自動重新整理,只有在呼叫 println、printf 或 format 的其中一個方法時才可以
		PrintWriter pw = new PrintWriter(new FileWriter("a.txt"),true);

		String line = null;
		while((line=bufw.readLine())!=null)
		{
			if("over".equals(line))
				break;
			pw.println(line.toUpperCase());
			//pw.flush();
		}

		bufw.close();
		pw.close();
	}
}

2.序列流SequenceInputStream

import java.io.*;
import java.util.*;

class SequenceInputStreamDemo 
{
	public static void main(String[] args) throws IOException
	{
		Vector v = new Vector();

		v.add(new FileInputStream("c:\\1.mp3"));
		v.add(new FileInputStream("c:\\2.mp3"));
		v.add(new FileInputStream("c:\\3.mp3"));

		Enumeration en = v.elements();

		BufferedInputStream bufis = new BufferedInputStream(new SequenceInputStream(en));
		BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\4.mp3"));

		byte[] buf = new byte[1024];
		int len = 0;
		while((len = bufis.read(buf))!=-1)
		{
			bufos.write(buf,0,len);
		}

		bufis.close();
		bufos.close();
	}
}

3.切割檔案

import java.io.*;
import java.util.*;

class SplitFileDemo 
{
	public static void main(String[] args) throws IOException
	{
		//splitFile();
		merge();
	}

	//合併檔案
	public static void merge() throws IOException
	{
		ArrayList list = new ArrayList();
		for(int x=1;x<=4;x++)
		{
			list.add(new FileInputStream("splitfiles\\"+x+".part"));
		}

		final Iterator it = list.iterator();
		Enumeration en = new Enumeration(){
			public boolean hasMoreElements()
			{
				return it.hasNext();
			}
			public FileInputStream nextElement()
			{
				return it.next();
			}
		};
		
		SequenceInputStream sis = new SequenceInputStream(en);
		FileOutputStream fos = new FileOutputStream("splitfiles\\lala.jpg");
		byte[] buf = new byte[1024];
		int len = 0;
		while((len=sis.read(buf))!=-1)
			fos.write(buf,0,len);

		sis.close();
		fos.close();
	}

	//切割檔案
	public static void splitFile() throws IOException
	{
		FileInputStream fis = new FileInputStream("aaa.jpg");
		FileOutputStream fos = null;

		byte[] buf = new byte[1024*1024];
		int len = 0;
		int index = 1;
		while((len=fis.read(buf))!=-1)
		{
			fos = new FileOutputStream("splitfiles\\"+(index++)+".part");
			fos.write(buf,0,len);
			fos.close();
		}

		fis.close();
	}
}

---------------------- ASP.Net+Android+IOS開發.Net培訓、期待與您交流! ----------------------