java.io,io流,2020.12.28
每日心得
假終於放完了,不過感冒還沒好,班上大部分好了吧,可是我們老師吊了兩天水卻還加重了,不可思議。。
java.io
I/O(Streams)流
通過資料流、序列化和檔案系統提供系統輸入和輸出,這是文件的解釋.這裡有一個概念,Stream
-->流,指一種資料運送的方式,流分很多種,有位元組流,字元流;這個包主要用於java-->Input&Output
與外面的程式進行輸入或輸出,輸入與輸出是相對的概念,當java
是輸入方時,被輸入方則是輸出方,輸出同理;這裡又有InputStream
,OutputStream
,輸入輸出流.
但這其中也分同一機器,系統中的不同程序通訊使用FileInputStream
FileOutputStream
還有不同機器即跨機器的通訊.net
InputStream(輸入流抽象類)
.read();//(核心方法)只能一次讀一個返回一個int,範圍(0-255),如果沒有位元組讀了,到達流的末尾,返回-1;這個方法會阻塞,只能給予三種情況,一返回一個範圍內的正整數,二是返回-1,三丟擲異常,超出這三種情況則會發生阻塞,程式碼會一直停在這裡不會繼續執行下去; .read(byte b[]);//返回int,總共讀到的緩衝中有多少位元組數,可以幾個位元組一起讀,緩衝即是b[]; .read(byte b[],//int off ,int len);off偏移量,指定可以在b中哪裡存存多少,可能b中前面一些資料會有用,所以避免將記憶體佔了 .skips(long l);//跳過部分不要了,已經讀了,但是沒有使用而已 .available();//返回int,io流中總共可以讀到多少資料byte .close();//關閉流,釋放資源 .mark(int);//標記讀到位置,可能需要返回來重新讀取 .reset();//重置到mark的位置再往後面讀 .markSupported();//返回布林值,能否使用mark方法,有些資料無法使用mark
OutputStream(輸出抽象類)
這裡提到一個概念buffer
緩衝器,作一個比較(一個瓶子的資料倒入另一個瓶子,因為瓶口太小,為了方便使用漏斗,當一個瓶子資料倒完時,不一定都在另一個瓶子中,可能有些還在漏斗中,在路上,漏斗類似緩衝;)
.write(int b);//int四個位元組32位,一次寫一個位元組,低八位,高於八位會去掉(向輸出流寫入一個位元組。要寫入的位元組是引數b的八個低位.b的24個高位將被忽略。) .write(byte[]b);//將b.length個位元組從指定的byte陣列寫入此輸出流.write(b)的常規協定是:應該與呼叫 write(b, 0, b.length) 的效果完全相同。 .write(byte[]b,int offer,int len);//與輸入流概念類似 .flush();//沖刷,將路上的位元組資料即緩衝器的東西直接衝入目標瓶子(直接衝到重新整理此輸出流並強制寫出所有緩衝的輸出位元組) .close();//與輸入流概念一致
File檔案類
通過這個類生成的物件-->某個目錄或者某個目錄下檔案資訊的封裝,並不是直接指向某個檔案,路徑名稱怎麼寫取決於其作業系統的不同而不同。
在這裡還會有一個知識-->檔案分隔符:Windows
-->反斜槓,正斜槓也識別;Linux
-->正斜槓,不識別反斜槓;所以我們一般使用正斜槓,在java
中使用反斜槓需要使用兩個反斜槓表示,因為其使轉義字元的原因,但正斜槓只用寫一個。pathname
,路徑名稱;directory
,目錄;file
,檔案;
File file=new File("");//裡面可以直接傳一個路徑(pathname),也可以傳一個父目錄(parent)與一個子目錄(child)或者檔案,也可以傳一個uri(抽象路徑名);
.canRead()//can..的各種方法,在windows中基本為true,linux中不,有許可權碼(可執行,可讀,可寫等);
.creatNewFile();//返回值為布林值,建立一個new檔案;
.creatTempFile();//返回值為布林值,生成一個臨時檔案在系統的臨時檔案目錄下;
.delete();//返回值為布林值,不能直接刪除有檔案或者資料夾的資料夾,若某檔案的流還未關閉,也無法刪除;
相對路徑:
.等於(./)表示當前資料夾..表示上一層資料夾,/代表根目錄
相對於應用程式所執行的那個目錄
get。。Path();//獲取各種路徑;
getName();//檔名稱,資料夾名稱;
可以獲取父檔案(Parent)的名稱再獲取其絕對路徑來使用;
絕對路徑:
檔案在總盤上的路徑;
.is..();//判斷是不是路徑,目錄,檔案是否隱藏等;
.lastModified();//返回的毫秒數,最後修改時間可以使用new Date()包裝方便檢視;
.length();//檔案大小;
.list();//返回一個數組,子檔案列表;
//檔案過濾器(可以在這裡面加判斷,根據檔案型別進行過濾,返回false則不放入ss中)
File file=new File("");
String[] ss=file.list(new FilenameFilter(){
public boolean accept(File dir,String name){
syso("name"+name);
//return false;
return name.endWith(.java);
}
});
syso(ss.length);
.mkdir();//建立當前目錄;
.mkdirs();//若父目錄不存在,則會一起建立,一般用這個;
.renameTo(File dest);//重新命名此抽象路徑名錶示的檔案;
FileInputStream
File file= new File("");
FileInputSteam fis=new FileInputStream(file);
//while(true){
// int ch=fis.read();//一個一個位元組讀
// if(-1==ch){
// break;
//}
//syso((char)ch);
//}
byte[]buffer = new byte[1024];
while(true){
int length=fis.read(buffer);//讀位元組陣列
if(-1==length){
break;
}
syso(new String(buffer,0,length));//可能為空,所以對有效位元組進行拼接
}
fis.close();
FileOutputStream
File file= new File("");
FileOutputSteam fos=new FileOutputStream(file,true);//後面加一個true表示追加模式,不加為覆蓋模式,預設為覆蓋模式,寫入的資料會覆蓋之前寫的;
fos.write(97);
fos.write(10);
fos.write(13);
fos.write(98);
fos.write("hello world\n".getByes());
fos.close();
寫資料時,可能會報thows FileNotFoundException,這個異常意思是下面兩種情況
1、當前檔案存在,但是無法開啟,或者不能寫入;
2、當前檔案不存在,但是沒辦法建立;(而並不是找不到檔案的異常;它是允許檔案不存在,寫的時候可以建立;)
作業:實現資料夾的複製,資料夾下要有多個資料夾和檔案;(使用遞迴)
遞迴:兩個條件-->自己呼叫自己,要有終止條件;
一個簡單的遞迴實現,階乘
f(x)=x*f(x-1);
x==1 f(1)=1;
public static int ff(int x){
if(x==1){
return 1;
}
return x*ff(x-1);
}
資料夾的複製,我找到了一篇文章十分清晰,"https://www.cnblogs.com/yuhudashen/p/7988831.html"他的程式碼註釋十分明白,很容易看懂,思路是寫了兩方法一個是複製檔案,一個是複製資料夾,在複製資料夾中判斷資料夾裡需要複製的是資料夾還是檔案,再呼叫相應的方法,我這借用一下。我自己打了一遍:
package task;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class CopyFile {
public static void main(String[] args) throws Exception {
copy("src", "src2");
System.out.println("複製完成");
}
public static void copy(String src,String des) throws Exception{
File file1=new File(src);
File[]fs=file1.listFiles();
File file2=new File(des);
if(!file2.exists()){
file2.mkdirs();
}
for(File f:fs){
if(f.isFile()){
fileCopy(f.getPath(), des+"\\"+f.getName());
}else if(f.isDirectory()){
copy(f.getPath(), des+"\\"+f.getName());//資料夾複製,遞迴呼叫自己
}
}
}
//檔案複製
public static void fileCopy(String src,String des) throws Exception{
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(des));
int i=-1;
byte[] bt=new byte[2014];
while((i=bis.read(bt))!=-1){
bos.write(bt,0,i);
}
bis.close();
bos.close();
}
}