1、File類型
1.1.File類的理解
- File類是在java.io包下
- File可以理解成一個文件(.mp3 .mp4 .txt)或者一個目錄
- File沒向文件寫入數據的功能。只創建,刪除,文件大小等方法。
- File可以理解成流的終端。
- 我們經常將File的對象作爲實參傳入到流的構造器中
- File 能新建、刪除、重命名文件和目錄,但 File 不能訪問文件內容本身。如果需要訪問文件內容本身,則需要使用輸入/輸出流。
1.2. 如何實例化
File file = new File("H:\\aaa\\abc.txt");
File file = new File("H:/aaa/abc.txt");
new File("H:\\aaa", "abc.txt"); //H:\\aaa\\abc.txt
絕對路徑:包含盤符在內的完整路徑
相對路徑:相對於當前的項目的路徑。
1.3 File 類的常見構造器:
注意:File的靜態屬性String separator存儲了當前系統的路徑分隔符。
在UNIX中,此字段爲‘/’,在Windows中,爲‘\\’
1.4.常用方法
1.5 案例
2、IO流概述
2.1概念:
- I/O是Input/Output的縮寫, I/O技術是非常實用的技術,用於處理設備之間的數據傳輸。如讀/寫文件,網絡通訊等。
- Java程序中,對於數據的輸入/輸出操作以”流(stream)” 的方式進行。
- java.io包下提供了各種“流”類和接口,用以獲取不同種類的數據,並通過標準的方法輸入或輸出數據。
2.2 Java IO原理
2.3.流的分類
- 按操作數據單位不同分爲:字節流(8 bit),字符流(16 bit)
- 按數據流的流向不同分爲:輸入流,輸出流
- 按流的角色的不同分爲:節點流,處理流
- Java的IO流共涉及40多個類,實際上非常規則,都是從如下4個抽象基類派生的。
- 由這四個類派生出來的子類名稱都是以其父類名作爲子類名後綴。
圖示:
2.4.流的體系結構(藍色的部分是重點
2.5 輸入流、輸出流
- 節點流可以從一個特定的數據源讀寫數據
- 處理流是“連接”在已存在的流(節點流或處理流)之上,通過對數據的處理爲程序提供更爲強大的讀寫功能。
(1)InputStream & Reader
(2)OutputStream & Writer
3、節點流(文件流)
文件流(1)
FileReader fr = null;
try{
fr = new FileReader("c:\\test.txt");
char[] buf = new char[1024];
int len= 0;
while((len=fr.read(buf))!=-1){
System.out.println(new String(buf ,0,len));}
}catch (IOException e){
System.out.println("read-Exception :"+e.toString());}
finally{
if(fr!=null){
try{
fr.close();
}catch (IOException e){
System.out.println("close-Exception :"+e.toString());
} } }
文件流 (2)
FileWriter fw = null;
try{
fw = new FileWriter("Test.txt");
fw.write("text");
}
catch (IOException e){
System.out.println(e.toString());
}
finally{
If(fw!=null)
try{
fw.close();
}
catch (IOException e){
System.out.println(e.toString());
}
}
注意:
- 定義文件路徑時,注意:可以用“/”或者“\\”。
- 在寫入一個文件時,如果目錄下有同名文件將被覆蓋。
- 在讀取文件時,必須保證該文件已存在,否則出異常。
字節流:
FileInputStream fis = null;
FileOutputStream fos = null;
try {
//1.創建File對象
File file = new File("char8.txt");
File file2 = new File("char9.txt");
//2.創建流的對象
fis = new FileInputStream(file);
fos = new FileOutputStream(file2);
//3.讀內容和寫內容
byte[] b = new byte[1024];
int len = 0;
while ((len = fis.read(b)) != -1) {
//將數組中的內容寫到目標文件中
fos.write(b, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
//4.關流
try {
if(fos != null){
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(fis != null){
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
字符流:
/*
* FileWriter
*/
@Test
public void test3() throws Exception{
FileWriter writer = new FileWriter("jjj.txt");
writer.write("中國你好我愛你麼麼噠".toCharArray());
writer.close();
}
/*
* FileReader : 讀取中文不會發生亂碼的問題
*/
@Test
public void test() throws Exception{
FileReader reader = new FileReader("aaa.txt");
char[] c = new char[500];
int len = 0;
while((len = reader.read(c)) != -1){
// System.out.println(new String(c, 0, len));
for (int i = 0; i < len; i++) {
System.out.println(c[i]);
}
}
reader.close();
}
4、緩衝流的使用
爲了提高數據讀寫的速度,Java API提供了帶緩衝功能的流類,在使用這些流類時,會創建一個內部緩衝區數組
根據數據操作單位可以把緩衝流分爲:
- BufferedInputStream 和 BufferedOutputStream
- BufferedReader 和 BufferedWriter
緩衝流要“套接”在相應的節點流之上,對讀寫的數據提供了緩衝的功能,提高了讀寫的效率,同時增加了一些新的方法
對於輸出的緩衝流,寫出的數據會先在內存中緩存,使用flush()將會使內存中的數據立刻寫出
4.1 處理流之一:緩衝流
File descFile = new File(desc);
File srcFile = new File(src);
FileInputStream fis = new FileInputStream(srcFile);
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream(descFile);
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte[] b = new byte[1024];
int len = 0;
while((len = bis.read(b)) != -1){
bos.write(b, 0, len);
}
bos.close();
bis.close();
fis.close();
fos.close();
/*
* BufferedWriter
*/
@Test
public void test2() throws Exception{
FileWriter writer = new FileWriter("cdf.txt");
BufferedWriter bw = new BufferedWriter(writer);
bw.write("圓圓麼麼噠");
bw.close();
writer.close();
}
/*
* BufferedReader
*/
@Test
public void test() throws Exception{
FileReader reader = new FileReader("aaa.txt");
//創建緩衝字符流
BufferedReader br = new BufferedReader(reader);
/*
* 第一種讀取文件內容
*/
// char[] c = new char[100];
// int len = 0;
// while((len = br.read(c)) != -1){
// System.out.println(new String(c,0,len));
// }
/*
* 第二種讀取文件內容
* readLine() : 讀取一行
*/
String str="";
while((str = br.readLine()) != null){
System.out.println(str);
}
br.close();
reader.close();
}
5、轉換流的使用
作用:
- 將讀取文件的字節流轉換成字符流,將寫入文件內容的字符流轉成字節流
- 轉換編碼集 (讀入的文件比如是UTF-8,寫入的文件的可以變成GBK
- 注意:InputStreamReader設置的編碼集必須和讀取文件的編碼集是一致的。
代碼:
// 讀取的文件
File file = new File("demo.txt");
// 創建一個字節流,對接在demo.txt上
FileInputStream fis = new FileInputStream(file);
// 創建一個轉換流 - 字節轉字符
InputStreamReader isr = new InputStreamReader(fis);
// 寫入的文件
File file2 = new File("demo2.txt");
// 創建一個字節流,對接在demo2.txt上
FileOutputStream fos = new FileOutputStream(file2);
// 創建一個轉換流 - 字符轉字節
OutputStreamWriter osw = new OutputStreamWriter(fos);
char[] c = new char[1024];
int len = 0;
while ((len = isr.read(c)) != -1) {
osw.write(c, 0, len);
}
osw.close();
isr.close();
fos.close();
fis.close();
圖示:
6、字符編碼集
7、其他流的使用:標準輸入輸出流、打印流
7.1 標準輸入輸出流
- System.in和System.out分別代表了系統標準的輸入和輸出設備
- 默認輸入設備是鍵盤,輸出設備是顯示器
- System.in的類型是InputStream
- System.out的類型是PrintStream,其是OutputStream的子類FilterOutputStream 的子類
- 通過System類的setIn,setOut方法對默認設備進行改變。
public static void setIn(InputStream in)
public static void setOut(PrintStream out)
代碼示例:
/*
* 從鍵盤輸入字符串,要求將讀取到的整行字符串轉成大寫輸出。然後繼續進行輸入操作,
* 直至當輸入“e”或者“exit”時,退出程序。
*/
@Test
public void test2() throws Exception{
/*
* 1.從控制檯讀取數據
* 2.將字節流轉成字符流
* 3.使用緩衝流
*/
//將字節流轉換成字符流
InputStreamReader isr = new InputStreamReader(System.in);
//創建字符緩衝流
BufferedReader br = new BufferedReader(isr);
while(true){
//讀取控制檯上的數據
String str = br.readLine();
//判斷如果是"e"/"exit"那麼就退出程序,否則全部轉成大寫並輸出
if("e".equalsIgnoreCase(str) || "exit".equalsIgnoreCase(str)){
//關流
br.close();
isr.close();
return;
}else{
System.out.println(str.toUpperCase());
}
}
}
7.2 打印流
代碼:
@Test
public void test() {
/*
* 第一步 創建一個連接text.txt的管道
* 第二步 將輸入到控制檯的管道改成輸入到text.txt
* 第步 輸入內容
*/
FileOutputStream fos = null;
try {
//創建一個輸出流
fos = new FileOutputStream(new File("text.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// 創建打印輸出流,設置爲自動刷新模式(寫入換行符或字節 '\n' 時都會刷新輸出緩衝區)
PrintStream ps = new PrintStream(fos, true);
/*
* 第二步 將輸入到控制檯的管道改成輸入到text.txt
*/
// 把標準輸出流(控制檯輸出)改成文件
System.setOut(ps); //在程序運行時只能設置一次。
/*
* 第步 輸入內容
*/
for (int i = 0; i <= 10; i++) {
System.out.print("a");
}
ps.close();
}
7.3 數據流
代碼:
/*
* 輸入流
*
* 注意 : 寫入數據的格式 和 讀取數據的格式必須一致
*/
@Test
public void test() throws Exception{
FileInputStream fis = new FileInputStream("abc.txt");
DataInputStream dis = new DataInputStream(fis);
String readUTF = dis.readUTF();
int readInt = dis.readInt();
boolean boo = dis.readBoolean();
System.out.println(readUTF);
System.out.println(readInt);
System.out.println(boo);
dis.close();
fis.close();
}
/*
* 輸出流
*/
@Test
public void test2() throws Exception{
FileOutputStream out = new FileOutputStream("abc.txt");
DataOutputStream dos = new DataOutputStream(out);
dos.writeUTF("abcde");
dos.writeInt(10);
dos.writeBoolean(true);
dos.close();
out.close();
}
7.4 對象流的使用
序列化 :用ObjectOutputStream類保存基本類型數據或對象的機制 (保存對象,或者發送對象)
反序列化 :用ObjectInputStream類讀取基本類型數據或對象的機制(讀取對象,接收對象)
* 注意:
- 序列化對象的類必須實現Serializable接口
- 序列化對象的類的屬性除基本類型外,也必須全部實現Serializable接口
- 需要聲明一個 serialVersionUID (如果不顯示聲明系統會默認填加一個)
- 不能序列化static和transient修飾的成員變量
代碼:
/*
* ObjectInputStream
*/
@Test
public void test() throws Exception{
FileInputStream fis = new FileInputStream("aaa.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
Person p = (Person) ois.readObject();
p.show();
Person p2 = (Person) ois.readObject();
p2.show();
ois.close();
fis.close();
}
/*
* ObjectOutputStream
*/
@Test
public void test2() throws Exception{
FileOutputStream fos = new FileOutputStream("aaa.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
//寫數據
oos.writeObject(new Person("aa",18,new Address("aaaa",20)));
oos.writeObject(new Person("bb",18,new Address("bbbb",20)));
oos.close();
}
9、RandomAccessFile類的使用
需求:
文件中的內容 : abcdefg
需求: 在c的後面插入AAA
- 先將指針移動到c的後面
- 讀取c後面的所數據並保存到一個臨時變量中
- 指針回移,移動到c的後面
- 寫入需要插入的數據
- 寫入臨時變量中的數據
代碼:
@Test
public void test4() throws Exception{
RandomAccessFile accessFile = new RandomAccessFile("access.txt", "rw");
//移動指針到c後面
accessFile.seek(3);
//將c後面的數據讀出並保存到一個臨時變量中。
// String str = accessFile.readLine();
String str = "";
//讀取插入位置後面的所內容
byte[] b = new byte[1024];
int len = 0;
while((len = accessFile.read(b)) != -1){
str += new String(b,0,len);
}
//指針回移
accessFile.seek(3);
//插入數據
accessFile.write("AAA".getBytes());
accessFile.write(str.getBytes());
//關流
accessFile.close();
}