在計算機中,通常使用各種各樣的檔案來儲存數據,如何在Java程式中操作這些檔案呢?java.io包提供了一些介面和類,對檔案進行基本的操作,包括對檔案和目錄屬性的操作、對檔案讀寫的操作等。
File物件既可表示檔案,也可表示目錄,在程式中一個File物件可以代表一個檔案或目錄。利用它可用來對檔案或目錄進行基本操作。它可以查出與檔案相關的資訊。
File類的常用方法如下所示:
使用File類操作檔案和目錄屬性的步驟一般如下:
(1)引入File類。
import java.io.File;
(2)構造一個檔案物件
File file=new File(「text.txt」);
(3)利用File類的方法存取檔案或目錄屬性,具體使用如下:
方法 | 作用 |
---|---|
file.exists(); | 判斷檔案或目錄是否存在 |
file.isFile(); | 判斷是否是檔案 |
file.isDirectory(); | 判斷是否是目錄 |
file.getName(); | 獲取檔案或目錄的名稱 |
file.getPath(); | 獲取檔案或目錄的相對路徑 |
file.getAbsolutePath(); | 獲取檔案或目錄的絕對路徑 |
file.lastModified(); | 獲取檔案或目錄的最後修改日期 |
file.length(); | 獲取檔案或目錄的大小,單位爲位元組 |
範例一:
import java.io.File;
import java.io.IOException;
public class TestFile {
public static void main(String[] args) {
// File f = new File("D:/shuju/新建文字文件.txt");
// System.out.println(f.isFile());//是不是檔案
// System.out.println(f.isDirectory());//是不是目錄
// System.out.println(f.exists());//是不是存在
File file = new File("D:/abc/def/ggg/a.txt");
System.out.println(file.exists());
// file.getPath();//相對路徑
// file.getAbsolutePath();//絕對路徑
// file.getName();//檔名
// file.length();//大小
file.getParentFile().mkdirs();//mkdir()單級目錄建立
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(file.exists());
file.delete();//只能夠刪除最後一級
// System.out.println(file.exists());
File f2 = new File("abc.txt");//直接從工程開始建立
creatFile("abc.txt");
}
public static void creatFile(String path){
File f = new File(path);
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
輸出結果:
範例二:使用File類建立和刪除檔案。
實現步驟如下:
(1)引入File類。
(2)構造一個檔案物件。
(3)呼叫File類的方法建立和刪除檔案。
程式碼展示:
import java.io.File;
public class FileMethods {
public static void main(String[] args) throws Exception {
//建立和刪除檔案
FileMethods fm = new FileMethods();
File f = new File("D:/myDoc/test.txt");
fm.creat(f);
fm.delete(f);
}
//建立檔案的方法
public void creat(File file)throws Exception {
if (!file.exists()) {
file.createNewFile();
}
}
//刪除檔案的方法
public void delete(File file)throws Exception {
if (file.exists()) {
file.delete();
}
}
}
範例三:實現檢視檔案屬性、建立和刪除檔案功能。
程式碼展示:
import java.io.File;
public class test1 {
public static void main(String[] args) {
File f = new File("D:/myDoc/text.txt");
System.out.println("名稱:"+f.getName());
System.out.println("相對路徑:" + f.getPath());
System.out.println("絕對路徑:" + f.getAbsolutePath());
System.out.println("檔案大小:"+f.length()+"位元組");
// f.getParentFile().mkdirs();
// try {
// f.createNewFile();
// } catch (IOException e) {
// e.printStackTrace();
// }
}
}
輸出結果:
之前講述瞭如何利用File類對檔案或目錄的屬性進行操作,但File類不能存取檔案的內容,既不能從檔案中讀取數據或往檔案裡寫數據。
讀檔案是指把檔案中的數據讀取到記憶體中。寫檔案是把記憶體中的數據寫到檔案中。通過流讀寫檔案。
流是指一連串流動的字元,是以先進先出的方式發送和接收數據的通道。
流分爲輸入流和輸出流。輸入/輸出流是指相對於計算機記憶體來說的,如果數據輸入到記憶體,則稱爲輸入流,如果從記憶體中輸出則稱爲輸出流。Java的輸出流主要由OutputStream和Write作爲基礎類別,而輸入流則主要由InputStream和Reader作爲基礎類別。
在java.io包中,封裝了許多輸入/輸出流的API。在程式中,這些輸入/輸出流類的物件稱爲流物件。可以通過這些流物件將記憶體中的數據以流的方式寫入檔案,也可以通過流物件將檔案中的數據以流的方式讀取帶記憶體。
構造流物件時往往會和數據源聯繫起來。數據源分爲源數據源和目標數據源。輸入流關聯的是源數據源。輸出流關聯的則是目標數據源。
輸入/輸出流又分爲位元組流和字元流兩種。
位元組流是8位元通用位元組流,其基本單位是位元組。位元組流的基礎類別是InputStream類和OutputStream類,它們是抽象類。
字元流是16位元Unicode字元流,基本單位是Unicode字元。字元流最適合用來處理字串和文字,因爲它們支援國際上大多數的字元集和語言。字元流的基礎類別是Reader類和Writer類,它們也是抽象類。
InputStream類常用方法:
方法 | 說明 |
---|---|
int read( ) | 從輸入流中讀取下一個位元組數據 |
int read(byte[] b) | 從輸入流中讀取數據,並將數據儲存在緩衝區陣列b中,返回實際讀取的位元組數。 |
int read(byte[] b,int off,int len) | 從輸入流中讀取最多len長度的位元組,儲存到位元組陣列b中,儲存的位置從off開始 |
void close( ) | 關閉輸入流 |
int available() | 可以從輸入流中讀取的位元組數目 |
InputStream類的常用子類有FileInputStream,用於從檔案中讀取數據。
子類FileInputStream常用的構造方法:
FileInputStream(File file);
FileInputStream(String name);
範例四:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class TestFileInPutSteam {
public static void main(String[] args) throws IOException {
// File file = new File("D:/shuju/新建文字文件.txt");
// FileInputStream fis=new FileInputStream(file);
//// int tmp;
//// while ((tmp=fis.read()) > 0) {
//// System.out.print((char)tmp);
//// }讀單個位元組
// byte[] b = new byte[1024];
// fis.read(b);
// byte[] rst=null;
// for (int i = 0; i < b.length; i++) {
// if (b[i] == 0) {
// rst = Arrays.copyOf(b, i);
// break;
// }
// }
// String str = new String(rst);
// System.out.println(str);//讀陣列
String s = readByone("D:/shuju/新建文字文件.txt");
System.out.println(s);
}
public static String readFile(String path) {
File f = new File(path);
FileInputStream fis=null;
String str=null;
try {
fis=new FileInputStream(f);
byte[] b = new byte[fis.available()];
fis.read(b);
// byte[] rst=null;
// for (int i = 0; i < b.length; i++) {
// if (b[i] == 0) {
// rst = Arrays.copyOf(b, i);
// }
// }
str = new String(b);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}return str;
}
public static String readByone(String path) {
FileInputStream fis=null;//賦值,爲了下面 下麪能看的到,資源關閉
String str=null;//爲了被後面看到
try {
fis=new FileInputStream(path);
StringBuffer sb = new StringBuffer();//String型別不可變
int tmp;//用於接收int型別的字元
while((tmp=fis.read())>0) {
char c = (char) tmp;//轉成char字元
sb.append(c);//拼接
}
str=sb.toString();//轉成字串的形式toString
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}return str;
}
}
輸出結果:
OutputStream類常用方法:
方法 | 說明 |
---|---|
void write(int c) | 將指定的位元組數據寫入此輸出流中 |
void write(byte[] buf) | 將陣列buf中的所有位元組寫入此輸出流中 |
void write(byte[] b,int off,int len) | 將位元組陣列中從偏移量off開始的長度爲len的位元組數據輸出到輸出流中 |
void close() | 關閉輸出流 |
void flush() | 強制把緩衝區的數據寫到輸出流中 |
OutputStream類的常用子類爲FileOutputStream,用於向檔案協數據。
子類FileOutputStream常用的構造方法:
FileOutputStream (File file);
FileOutputStream(String name);
FileOutputStream(String name,boolean append);
範例五:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class TestOutputStream {
public static void main(String[] args) throws IOException {
String str = "How do you do.\r\nFine,thank you,and you?\r\nThat's ok!";
// FileOutputStream fos = new FileOutputStream("def.txt",true);//加一個true,追加
// byte[] b = str.getBytes();
// fos.write(b);
// fos.close();
writeFile(str,"text/a/txt",true);
}
public static void writeFile(String str, String path, boolean isAppend) {
File f = new File(path);
if (!f.getParentFile().exists()) {
f.getParentFile().mkdirs();
}
FileOutputStream fos = null;
try {
fos=new FileOutputStream(f,isAppend);
byte[] b=str.getBytes();
fos.write(b);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
輸出結果:
範例六:
import java.io.*;
public class text3 {
public static void main(String[] args) throws IOException {
File file = new File("D:/abce.txt");
FileInputStream fis = null;
FileOutputStream fos = null;
if (!file.exists()) {
System.out.println("檔案不存在!");
}
try {
fis = new FileInputStream(file);
fos = new FileOutputStream("D:/shuju/abce.txt");
byte[] words = new byte[fis.available()];
fis.read(words);
fos.write(words);
System.out.println("複製成功!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
fis.close();
fos.close();
}
}
}
輸出結果:
注意:
(1)在操作上位元組流和字元流有一個區別,字元流在操作時使用了緩衝區(內部記憶體),而位元組流在操作時直接操作檔案,不會使用緩衝區。
(2)所有的這些方法在出現錯誤時都會拋出IOException異常。
絕對路徑和相對路徑:
絕對路徑從根目錄開始
相對路徑從當前目錄開始
FileInputStream讀檔案的流程:
1、FileInputStream物件和String結果物件宣告
2、建立FileInputStream物件(檔案路徑或File物件)
3、讀單位元組或整個讀到byte陣列中
4、轉成字串
5、關閉FileInputStream流
6、返回結果
FileOutputStream寫檔案的流程:
1、File物件裝載檔案路徑
2、判斷檔案父級目錄是否存在,不存在則建立
3、宣告FileOutputStream物件
4、建立FileOutputStream物件(File物件,是否追加)
5、把要寫的字串轉成byte陣列,並寫入輸出流
6、關閉FileOutputStream流