IO知識梳理2
---------------------------------------------------------------------------------------------------------------------------------------------
1、File 重點方法
listRoots():列出 系統的盤符。String list() :列出該盤符下所有的文件夾、文件 保過隱藏部分。list(FilenameFilter filter): 文件過濾,選出指定文件File listFiles() :比list()更常用,因爲被封裝爲對象,所以可以獲取其名字和長度
2、遞歸 函數自身調用自身。
3、遞歸注意事項:這種表現形式,或者說編程手法,稱爲【遞歸。【函數自身調用自身。】】
1、限定條件。
2、要注意遞歸的次數,儘量避免內存溢出。
4、Properties 是 hashtable 的子類
也就是說它具備 map 集合的特點,而且他裏面存儲的【鍵值對】 都是字符串
5、打印流 : 可以直接操作輸入流和文件。
PrintStreamPrintWriter該流提供了打印方法,可以將各種數據類型的數據都原樣打印。
6、合併--分割
SequenceInputStream(en) en爲枚舉值1、 SequenceInputStream 是合併流,參數接收一個枚舉值2、那麼集合中,誰有枚舉呢: Vector把流都裝入到Vector 形成一個結合3、 SequenceInputStream 接收枚舉, 形成合並流。4、 創建一個輸入流,並關聯文件。
-------------------------------------------------------
【1】
常用方法:
1、創建
常用方法:
1、創建
boolean createNewFile(); 在指定位置常見文件,
如果該文件已經存在,則不創建,返回false,同輸出流不一樣,輸出流建立文件,如果存在,則直接覆蓋。
boolean mkdir():創建文件夾(只能是一級目錄)boolean mkdirs():創建多級文件夾(D:\\e\\aa\\ee\\dd)
2、刪除
boolean delete(); 指定刪除void deleteonExit(); 退出時,刪除
3、判斷
exists() 判斷文件或目錄【是否存在】。isDirectory() 是否是目錄isFile() 是否是文件isHidden() 是否是隱藏文件 (Java是不能使用隱藏文件的)isAbsolute() 是否是絕對路徑(E:\\2\\213\2.txt)
4、查找
String getName(); 獲取名稱getPath() :獲取路徑getParent(): 獲取路徑 沒有明確指定負目錄,返回的是空getAbsolutePath() 獲取絕對路徑。long lastModifide() :返回最後修改的時間。[last,modifai]long length() : 文件大小。
---------
【重點的部分】
listRoots():列出 系統的盤符。
String list() :列出該盤符下所有的文件夾、文件 保過隱藏部分。
list(FilenameFilter filter): 文件過濾,選出指定文件
File listFiles() :比list()更常用,因爲被封裝爲對象,所以可以獲取其名字和長度
-----------------------------------
endsWith(".java") 篩選
renameTo(File dest)
分隔符:File.separator 可以跨平臺使用。
因爲E:\\ 跨平臺性不強
【2】
遞歸 概念
函數自身調用自身。
這種表現形式,或者說編程手法,稱爲【遞歸。【函數自身調用自身。】】
遞歸注意:
1、限定條件。
2、要注意遞歸的次數,儘量避免內存溢出。
遞歸中不要建立集合,因爲會自己調用自己會不斷創建集合。
【重點的部分】
listRoots():列出 系統的盤符。
String list() :列出該盤符下所有的文件夾、文件 保過隱藏部分。
list(FilenameFilter filter): 文件過濾,選出指定文件
File listFiles() :比list()更常用,因爲被封裝爲對象,所以可以獲取其名字和長度
-----------------------------------
endsWith(".java") 篩選
renameTo(File dest)
分隔符:File.separator 可以跨平臺使用。
因爲E:\\ 跨平臺性不強
【2】
遞歸 概念
函數自身調用自身。
這種表現形式,或者說編程手法,稱爲【遞歸。【函數自身調用自身。】】
遞歸注意:
1、限定條件。
2、要注意遞歸的次數,儘量避免內存溢出。
遞歸中不要建立集合,因爲會自己調用自己會不斷創建集合。
class $3FileDemo {
public static void main(String[] args) {
File dir = new File("E:\\yunyao\\edjava\\");
//showDir(dir);
//toBin(6);
int sum = getSum(8000);
sop(sum);
}
//遞歸運算示例2:
public static int getSum(int n){
//計算1234一次相加的和
if(n == 1){
return 1;
}
return n+getSum(n-1);
}
//遞歸運算示例:
public static void toBin(int num){
if(num>0){
toBin(num /2 );
//num = num /2 ;
sop(num%2);
}
}
public static void showDir(File dir){
sop("-----------------------------------");
sop(dir);
sop("--------");
File [] files = dir.listFiles();
for(int i = 0; i<files.length; i++){
if(files[i].isDirectory())
showDir(files[i]);//【再次調用本功能】函數自身調用自身。
else
sop(files[i]+"::"+files[i].length());
}
}
public static void sop(Object obj){
System.out.println(obj);
}
}
//最簡單的遞歸: a 調用b b調用c c打印完後,打印b 然後打印a // 有這麼一個規律:先進後出。(棧的規律也)
class Test{
void showA(){
showB();
sop(A);
}
void showB(){
showC();
sop(B);
}
void showC(){
sop(C);
}
}
【3】Properties
Properties 是 hashtable 的子類
也就是說它具備 map 集合的特點,而且他裏面存儲的【鍵值對】 都是字符串
是集合中的 和 IO 技術相結合的容器
該對象的特點: 可以用於鍵值對象的配置文件
是集合中的 和 IO 技術相結合的容器
該對象的特點: 可以用於鍵值對象的配置文件
(因爲配置文件都是存放與電腦,和集合是在內存中。Properties 誕生)
需求。 在指定目錄下編寫一個配置文件,然後把該文件中傳入到Propertise中。
class $8Properties{
public static void main(String[] args) throws IOException{
File f = new File("E:\\bbc.txt");
method_1(f);
method_2(f);//
method_3(f);//
}
//修改某一個數值
public static void method_3(File file)throws IOException{
Properties prop = new Properties();
FileInputStream fis = new FileInputStream(file);
prop.load(fis);
//當需要修改值時,發現setProperty方法只能修改集合中的值,而文件
// 中並沒有修改。查看API 發現store()方法和 load 方法對應:
prop.setProperty("laopo","9");
FileOutputStream fos = new FileOutputStream(file);//同樣一個流
prop.store(fos,"update");//同樣傳入流,後面是註釋標題:
prop.list(System.out);//列出Properties 建議用該方法。
fis.close();
fos.close();
}
//[method_1 終極進化模式。]
public static void method_2(File file)throws IOException{
Properties prop = new Properties();
FileInputStream fis = new FileInputStream(file);
prop.load(fis);//將集合中數據成對加載Properties 集合中。
//System.out.println(prop);
prop.list(System.out);//列出Properties 建議用該方法。
}
public static void method_1(File file)throws IOException{
BufferedReader bufr = new BufferedReader(new FileReader(file));
String line = null;
Properties prop = new Properties();
int index=0;
while((line=bufr.readLine())!=null){
if(line.contains("=")){ //只對鍵值對進行分割
String [] str = line.split("=");
prop.setProperty(str[0],str[1]);
}
}
//查看是否成功將數據插入到Properties
Set<String> set =prop.stringPropertyNames();
for(String s : set ){
System.out.println(s+"::"+prop.getProperty(s));
}
}
}
練習案例:需求:
用於記錄應用程序運行次數。
如果使用次數已到,那麼給出註冊提示。
通常會想到:計數器
但是該計數器定義在程序中,隨着程序的運行而存在於內中,並進行自增
隨着應用程序的退出,該計數器也會在內存中消失。
下一次在啓動該程序,又會重新開始從0計數。
這樣就達不到要求。
可以創建一個 Properties 集合,設定一個計數器鍵值對。
打開某一個應用程序時,建立一個相對應的計數器集合。初始值爲1
再次打開判斷是否有該程序的計數器,沒有,新建,有,值自增。
當這個值達到某個數值時,提示次數已滿。
1、接收文本目錄,創建一個BufferedReader 關聯文件
2、創建Pro 集合,根據文件名寫入鍵值對。
3、主函數可以用一個循環,運行一次,調用一次計數。
4、輸出次數。
public class IO3 {
public static void main(String[] args) throws IOException{
Properties prop = new Properties();//1、創建集合
File file = new File("E:\\cout.ini");//2、把文件封裝爲對象
if(!file.exists()){ //3、判斷文件是否存在
file.createNewFile(); //3-1、如果沒有該文件則創建一個。
}
FileInputStream fis = new FileInputStream(file); //4、建立讀取流並關聯文件
prop.load(fis); //5、載入。鍵值對數據。
int count = 0;
String value = prop.getProperty("Sum"); //6/獲取 key 對應的值 value
System.out.println("模擬啓動");
if(value!=null){ // 7、判斷有沒有該 key
count = Integer.parseInt(value); //7-1、如果有則把 value 值轉換爲int
if(count>=5){
System.out.println("軟件使用次數到期。交錢吧。");
return ;
}
}
count++; // 8、自增一次。
prop.setProperty("Sum",count+""); // 9、 更新數據/一定要通過 count+"" 進行轉換
FileOutputStream fos = new FileOutputStream(file); //10、建立輸入流並關聯文件
prop.store(fos,"update");//11、更新到硬盤文件
fis.close();//12、管理兩個緩衝區。
fos.close();
}
}
【4】打印流 : 可以直接操作輸入流和文件。
PrintStreamPrintWriter
該流提供了打印方法,可以將各種數據類型的數據都原樣打印。
字節打印流
PrintStream
字節打印流
PrintStream
構造函數可以接收的參數類型:1、file對象2、字符串路徑3、字節輸出流 OutputStream
字符打印流
PrintWriter
PrintWriter
構造函數可以接收的參數類型:1、file對象2、字符串路徑3、字節輸出流 OutputStream4、字符輸出流 Writer
【5】 合併--分割
對多個流進行合併
SequenceInputStream(en) en爲枚舉值
對多個流進行合併
SequenceInputStream(en) en爲枚舉值
1、 SequenceInputStream 是合併流,參數接收一個枚舉值2、那麼集合中,誰有枚舉呢: Vector把流都裝入到Vector 形成一個結合3、 SequenceInputStream 接收枚舉, 形成合並流。4、 創建一個輸入流,並關聯文件。
// Vector Enumeration elements SequenceInputStream
實現兩個功能:
1、分割
實現兩個功能:
1、分割
1、創建讀取流並關聯文件,聲明讀寫流源,電腦,視頻文件: FileInputStream2、創建一個byte 類型數組,大小爲需求每個文件的大小3、通過循環方式,new出讀寫流,並裝入數據。4、關閉所有流。
2、合併
老方法:1、因爲合併流 SequenceInputStream 的參數必須是枚舉,所以需要用到Vector2、創建 Vector 新增被分割的文件。3、枚舉 Enumeration en = v.elements4、創建 SequenceInputStream 接收en5、創建讀寫流 FileOutputStream 並管理文件位置。6、記住 一個字節數組來存儲,利用循環。7、關閉所有流
方法2:因爲vector 方法效率很低,所以使用 ArrayList 來處理因爲 ArrayList 只有迭代沒有枚舉 所以,使用迭代 建立 枚舉內部來來返回 轉型。注意,Enumeration 必須重載兩個方法,hashCodeElements nextElement剩餘步驟一致
// Vector Enumeration SequenceInputStream hasMoreElements nextElement
class $93Test1 {
public static void main(String[] args) throws Exception{
File f = new File("E:\\Test\\mp4");
spiltFile_1(); // 切割
Thread.sleep(2000);
toSequenceInputStream_2(f); // 合併
//toSequenceInputStream_1(f); // 低效率合併--摒棄。
Thread.sleep(3000);//延遲幾秒再進行刪除
DeleteFile(f); // 刪除
}
//【2】 發現分割出問題了,刪除錯誤分割文件
public static void DeleteFile(File dir)throws Exception {
try{
File [] files = dir.listFiles();// 把接收到的路徑對象 裝入數組中
for(File file : files){ // 遞歸 判斷內部是否還包含文件夾
if(file.isDirectory()){
DeleteFile(file);
}
System.out.println("Dele:"+file.delete());// 刪除文件
}
System.out.println("OVER");
//System.out.println("OVER\nDele:"+dir.delete());// 刪除文件夾
}
catch (IOException e){
throw new RuntimeException();
}
}
//【1】 分割
public static void spiltFile_1(){
FileInputStream fis =null;
FileOutputStream fos = null;
try{
fis = new FileInputStream("E:\\207.mp4");//讀寫流 關聯文件
int len = 0;
int count = 1;
byte [] by = new byte[1024*1024*10];// 設置 10M
while((len = fis.read(by))!=-1){
fos = new FileOutputStream("E:\\Test\\mp4\\"+(count++)+".part");//創建一個寫入流 並關聯文件
fos.write(by,0,len);//寫入
fos.close();//關閉該流 //循環後,count++ 這個時候關聯新的文件。
}
System.out.println("Spilt is Over!");
}
catch (IOException e){
throw new RuntimeException();
}
finally{
try{
if(fis!=null)//切記關閉流
fis.close();
}
catch (IOException e){
throw new RuntimeException();
}
}
}
//【3】 合併
public static void toSequenceInputStream_2(File dir) throws IOException{
SequenceInputStream sis =null;
FileOutputStream fos =null;
BufferedOutputStream bufi=null;
try{
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();// 用該集合取代 低效的 vector
for(int i = 1; i<= 14 ; i++){
al.add(new FileInputStream("E:\\Test\\mp4\\"+i+".part")); // 遍歷新增 被分割的文件。
}
final Iterator<FileInputStream> it = al.iterator(); // 因爲 ArrayList 沒有枚舉,只有迭代, 那麼我們中轉一下。 記住是 final 修飾
Enumeration<FileInputStream> en = new Enumeration<FileInputStream>(){ // 枚舉 通過內部類 通過 轉換 使枚舉 返回 迭代值
public boolean hasMoreElements(){ // 切記覆蓋該方法 boolean 類型
return it.hasNext();
}
public FileInputStream nextElement(){ // 切記覆蓋該方法 FileInputStrean 類型
return it.next();
}
};
sis = new SequenceInputStream(en);// SequenceInputStream 接收枚舉
//fos = new FileOutputStream("E:\\Test\\mp4\\2222.mp4");
bufi =new BufferedOutputStream(new FileOutputStream("E:\\Test\\mp4\\2222.mp4")); // 爲了效率
int len = 0;
byte [] by = new byte[1024];// 別忘了字節數組
while((len = sis.read(by))!=-1){ // 讀的是數組
bufi.write(by,0,len);//fos.write(by,0,len); // 寫入
//bufi.flush();//fos.flush(); // 刷新,其實可以不寫。 因爲接着就關閉了,自動刷新了。
}
System.out.println("Sequence is Over!");
}
catch (IOException e){
throw new RuntimeException();
}
finally{
try{
if(bufi!=null) //切記關閉流
bufi.close();
}
catch (IOException e)
{
throw new RuntimeException();
}
finally{
try{
if(sis!=null)//切記關閉流
sis.close();
}
catch (IOException e)
{
throw new RuntimeException();
}
}
}
}
// 使用 Vector -- 但是效率不好。
public static void toSequenceInputStream_1(File dir) throws IOException
{
// 1、因爲合併流 SequenceInputStream 的參數必須是枚舉,所以需要用到Vector
// 2、創建 Vector 新增被分割的文件。
// 3、枚舉 Enumeration en = v.elements
// 4、創建 SequenceInputStream 接收en
// 5、創建讀寫流 FileOutputStream 並管理文件位置。
// 6、記住 一個字節數組來存儲,利用循環。
// 7、關閉所有流
File [] files = dir.listFiles();
Vector<FileInputStream> v = new Vector<FileInputStream>();
for(int i = 1 ;i<files.length-1 ; i++){
v.add(new FileInputStream("E:\\Test\\mp4\\"+i+".part"));
}
Enumeration<FileInputStream> en = v.elements();
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream("E:\\Test\\mp4\\008.mp4");
int len = 0;
byte [] by = new byte [1024];
while((len = sis.read(by))!=-1){
fos.write(by,0,len);
fos.flush();
}
System.out.println("Sequence is Over!");
fos.close();
sis.close();
}
}
//end
1、分割,讀取文件的時候,
byte [] by = new byte[1024*1024*10]; 設置 10m 來設定 每一個分割文件的大小
2、合併,遍歷 新增所有分割文件 到集合中 sis = new SequenceInputStream(en) 接收集合轉化的 枚舉值 進行文件的合併。
3、刪除文件時,注意判斷 是否爲文件夾 利用 遞歸 完成。
3、刪除文件時,注意判斷 是否爲文件夾 利用 遞歸 完成。
---------------------------------------------------------------------------------------------------------------------------------------------
----------
android培訓、 java培訓、期待與您交流!----------
----------------------------------------------