黑馬程式設計師-JAVA高階(IO輸入與輸出)PART3
---------------------- ASP.Net+Android+IOS開發、.Net培訓、期待與您交流! ----------------------
這部分的內容主要有以下幾個知識點:
1.File類;
2.Properties類;
3.IO體系的其他一些流;
一、File類
File類用來將檔案或者資料夾封裝成物件,方便對檔案和資料夾的屬性資訊進行操作。同時,File物件可以作為引數傳遞給流的建構函式。
1.常用的三種建構函式
小點:File.separator,跨平臺的目錄分隔符。//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");
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培訓、期待與您交流! ----------------------