14、Java檔案操作stream、File、IO
1、檔案操作涉及到的基本概念
File
File類 是檔案操作的主要物件
中文意義就是 檔案 顧名思意
萬物皆檔案,在計算上看到的所有東西都是檔案儲存,不管是你的圖片、視訊、資料庫資料等等都是按照基本的二進位制規則儲存到計算機中的儲存系統中。
Java中使用File類:
得到一個檔案物件:
String filename="/tmp/user/java/bin/javac.sh";
File file=new File(filename);
建立一個目錄:
String dirname="/tmp/user/java/bin";
File d=new File(dirname);
// 現在建立目錄
d.mkdirs();
位元組流和字元流
位元組流:位元組流讀取的時候,讀到一個位元組就返回一個位元組;主要用於讀取圖片,MP3,AVI視訊檔案。
字元流:字元流使用了位元組流讀到一個或多個位元組,如讀取中文時,就會一次讀取2個位元組。只要是處理純文字資料,就要優先考慮使用字元流。
區別:
位元組流操作的基本單元為位元組;字元流操作的基本單元為Unicode碼元。
位元組流預設不使用緩衝區;字元流使用緩衝區。
位元組流通常用於處理二進位制資料,實際上它可以處理任意型別的資料,但它不支援直接寫入或讀取Unicode碼元;字元流通常處理文字資料,它支援寫入及讀取Unicode碼元。
IO
流:代表任何有能力產出資料的資料來源物件或者是有能力接受資料的接收端物件 ;其作用是為資料來源和目的地建立一個輸送通道
IO流:是程式中一套用於資料傳輸的機制。IO流是Input流和Output流的簡稱。流的輸入輸出是以程式為參照物。
1、輸入流
資料從外部流向程式。例如讀取檔案,就是從外部流入程式。
2、輸出流
資料從程式流向外部。例如將程式中的資料寫入到檔案中。
2、Java檔案操作
建立檔案
我們可以從中建立一個File
物件
-
路徑名
-
父路徑名和子路徑名
-
URI(統一資源識別符號)
我們可以使用File類的以下建構函式之一建立一個檔案:
File(Stringpathname)
File(Fileparent,Stringchild)
File(Stringparent,Stringchild)
File(URIuri)
##如果我們有一個檔案路徑名字串test.txt,我們可以建立一個抽象路徑名作為下面的程式碼。
FiledummyFile=newFile("test.txt");
booleanfileCreated=dummyFile.createNewFile();
使用File物件,我們可以建立新檔案,刪除現有檔案,重新命名檔案,更改檔案的許可權等。
File類中的isFile()和isDirectory()告訴File物件是否表示檔案或目錄。
檔案的存在:
我們可以使用File類的exists()方法檢查File物件的抽象路徑名是否存在。
boolean fileExists = dummyFile.exists();
當前工作目錄:
JVM的當前工作目錄是根據我們如何執行java命令來設定的。
我們可以通過讀取user.dir系統屬性來獲取JVM的當前工作目錄,如下所示:
String workingDir = System.getProperty("user.dir");
使用System.setProperty()方法更改當前工作目錄。
System.setProperty("user.dir", "C:\\myDir");
要在Windows上指定C:\ test作為user.dir系統屬性值,我們執行如下所示的程式:
java -Duser.dir=C:\test your-java-class
3、Java輸入流
1、分類
抽象基本元件是InputStream類。
InputStream
|
+--FileInputStream
|
+--ByteArrayInputStream
|
+--PipedInputStream
|
+--FilterInputStream
|
+--BufferedInputStream
|
+--PushbackInputStream
|
+--DataInputStream
|
+--ObjectInputStream
我們有FileInputStream,ByteArrayInputStream和PipedInputStream,FilterInputStream的具體類。
方法
超類InputStream包含從輸入流讀取資料的基本方法,所有具體類都支援這些方法。
對輸入流的基本操作是從其讀取資料。InputStream類中定義的一些重要方法在下表中列出。
ID | 方法/說明 |
---|---|
1 | read()讀取一個位元組並將讀取的位元組作為int返回。當到達輸入流的結尾時,它返回-1。 |
2 | read(byte[] buffer)讀取最大值直到指定緩衝區的長度。它返回在緩衝區中讀取的位元組數。如果到達輸入流的結尾,則返回-1。 |
3 | read(byte [] buffer,int offset,int length)讀取最大值到指定長度位元組。資料從偏移索引開始寫入緩衝區。它返回讀取的位元組數或-1,如果到達輸入流的結束。 |
3 | close()關閉輸入流 |
4 | available()返回可以從此輸入流讀取但不阻塞的估計位元組數。 |
2、檔案輸入流
在Java I/O中,流意味著資料流。流中的資料可以是位元組,字元,物件等。
要從檔案讀取,我們需要建立一個FileInputStream類的物件,它將表示輸入流。
String srcFile = "test.txt";
FileInputStream fin = new FileInputStream(srcFile);
3、緩衝輸入流
BufferedInputStream通過緩衝資料向輸入流新增功能。
它維護一個內部緩衝區以儲存從底層輸入流讀取的位元組。
我們建立緩衝區輸入流如下:
String srcFile =“test.txt";BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
以下程式碼顯示如何使用BufferedInputStream從檔案讀取。
import java.io.BufferedInputStream;
import java.io.FileInputStream;
public class Main {
public static void main(String[] args) {
String srcFile = "test.txt";
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
srcFile))) {
// Read one byte at a time and display it
byte byteData;
while ((byteData = (byte) bis.read()) != -1) {
System.out.print((char) byteData);
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
4、Java雙輸出流
1、基本概念
在抽象超類OutputStream中定義了三個重要的方法:write(),flush()和close()。
write()方法將位元組寫入輸出流。
它有三個版本,允許我們一次寫一個位元組或多個位元組。
flush()方法用於將任何緩衝的位元組重新整理到資料宿。
close()方法關閉輸出流。
要使用BufferedOutputStream裝飾器以更好的速度寫入檔案,請使用以下語句:
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("your output file path"));
要將資料寫入ByteArrayOutputStream,請使用
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(buffer); // buffer is a byte array
2、Java 檔案輸出流
要寫入檔案,我們需要建立一個FileOutputStream類的物件,它將表示輸出流。
// Create a file output stream
String destFile = "test.txt";
FileOutputStream fos = new FileOutputStream(destFile);
3、Java 資料輸出流
DataOutputStream可以將Java基本資料型別值寫入輸出流。
DataOutputStream類包含一個寫入資料型別的寫入方法。它支援使用writeUTF(String text)方法將字串寫入輸出流。
要將Java原始資料型別值寫入名為primitives.dat的檔案,我們將按如下所示構造DataOutputStream的物件:
DataOutputStream dos = new DataOutputStream(new FileOutputStream("primitives.dat"));
5、常用操作實戰
1、建立、刪除資料夾
Stringpath="F:\\test";
FilemyFile=newFile(path);
if(!myFile.exists()) {
// 建立資料夾
myFile.mkdir();
// myFile.mkdirs();
// 刪除資料夾
myFile.delete();
}
// mkdirs()可以建立多級資料夾, mkdir()只會建立一級的資料夾
2、建立、刪除檔案
Stringcontent="Hello World";
// 第一種方法:根據檔案路徑和檔名
Stringpath="F:\\test";
Stringfilename="test.txt";
FilemyFile=newFile(path,filename);
// 第二種方法
Stringfile="F:\\test\\test.txt";
FilemyFile=newFile(file);
if(!myFile.exists()) {
// 建立檔案(前提是目錄已存在,若不在,需新建目錄即資料夾)
myFile.createNewFile();
// 刪除檔案
myFile.delete();
}
3、寫入檔案
// 第一種:位元組流FileOutputStream
FileOutputStreamfop=newFileOutputStream(myFile);
byte[]contentInBytes=content.getBytes();
fop.write(contentInBytes);
fop.flush();
fop.close();
// 第二種:FileWriter(引數true為追加內容,若無則是覆蓋內容)
FileWriterfw=newFileWriter(myFile,true);
fw.write(content);
fw.close();
// 第三種:BufferedWriter
BufferedWriterbw=newBufferedWriter(newFileWriter(myFile,true));
bw.write(content);
bw.flush();
bw.close();
// 第四種:列印流PrintStream和PrintWriter
// 位元組列印流:PrintStream
// 字元列印流:PrintWriter
PrintWriterpw=newPrintWriter(newFileWriter(myFile,true));
pw.println(content); // 換行
pw.print(content); // 不換行
pw.close();
// 常用BufferedWriter和PrintWriter
4、讀取檔案
FileInputStream:
// 第一種:以位元組為單位讀取檔案,常用於讀二進位制檔案,如圖片、聲音、影像等檔案。
InputStreamin=newFileInputStream(myFile);
// 一次讀一個位元組
inttempbyte;
while((tempbyte=in.read())!=-1) {
System.out.write(tempbyte);
}
in.close();
// 一次讀多個位元組
intbyteread=0;
byte[]tempbytes=newbyte[100];
ReadFromFile.showAvailableBytes(in);
while((byteread=in.read(tempbytes))!=-1) {
System.out.write(tempbytes,0,byteread);
}
// System.out.write()方法是字元流,System.out.println()方法是位元組流
InputStreamReader:
// 第二種:以字元為單位讀取檔案,常用於讀文字,數字等型別的檔案
Readerreader=newInputStreamReader(newFileInputStream(myFile));
// 一次讀一個位元組
inttempchar;
while((tempchar=reader.read())!=-1) {
// 對於windows下,\r\n這兩個字元在一起時,表示一個換行。
// 但如果這兩個字元分開顯示時,會換兩次行。
// 因此,遮蔽掉\r,或者遮蔽\n。否則,將會多出很多空行。
if(((char)tempchar)!='\r') {
System.out.print((char)tempchar);
}
}
reader.close();
// 一次讀多個位元組
char[]tempchars=newchar[30];
intcharread=0;
// 讀入多個字元到字元陣列中,charread為一次讀取字元數
while((charread=reader.read(tempchars))!=-1) {
// 同樣遮蔽掉\r不顯示
if((charread==tempchars.length)&&(tempchars[tempchars.length-1]!='\r')) {
System.out.print(tempchars);
}else{
for(inti=0;i<charread;i++) {
if(tempchars[i]=='\r') {
continue;
}else{
System.out.print(tempchars[i]);
}
}
}
}
BufferedReader:
// 第三種:以行為單位讀取檔案,常用於讀面向行的格式化檔案
BufferedReaderreader=newBufferedReader(newFileReader(myFile));
StringtempString=null;
intline=1;
// 一次讀入一行,直到讀入null為檔案結束
while((tempString=reader.readLine())!=null) {
// 顯示行號
System.out.println("line "+line+": "+tempString);
line++;
}
reader.close();
// 常用BufferedReader
5、遍歷檔案(以刪除一個資料夾下所有檔案為例)
File[]files=myFile.listFiles();
for(inti=0;i<files.length;i++){
if(files[i].isDirectory()){
files[i].delete();
}
}