File類的特點?如何創建File類對象?Java中如何操作文件內容,什麼是Io流Io流如何讀取和寫入文件?位元組緩衝流使用原則?
- 2021 年 1 月 1 日
- 筆記
- JAVA, Java進階基礎學習筆記
重難點提示
學習目標
1、能夠了解File類的特點(存在的意義,構造方法,常見方法)
2、能夠了解什麼是IO流以及分類(IO流的概述以及分類)
3、能夠掌握位元組輸出流的使用(繼承體系結構介紹以及常見的位元組輸出流)
4、能夠掌握位元組輸入流的使用(繼承體系結構介紹以及常見的位元組輸入流)
5、能夠掌握位元組緩衝流(了解)的使用(拷貝文件,傳輸原理)
-
File
-
IO流
-
位元組流
1.File類
Java中用哪個類表示文件或文件夾?
JavaAPI :java.io.File 類 :創建、刪除、重命名等操作
1.2File類構造方法【重點】(視頻02) (6『』)
1.如何創建File對象?
方法名 | 說明 |
---|---|
File(String pathname) | 通過指定的路徑字符串創建File對象 |
File(String parent, String child) | 通過File表示的文件夾和子路徑創建的File對象 |
File(File parent, String child) | 通過File表示的文件夾和子路徑創建的File對象 |
2.File類的特點
只是表示路徑名稱而已,可以表示存在的,也可以表示不存在的
da示例代碼
package com.itheima.filedemo;
import java.io.File;
public class FileDemo1 {
public static void main(String[] args) {
//method1();
//method2();
//method3();
}
private static void method3() {
//File•(File parent, String child) 從父抽象路徑名和子路徑名字符串創建新的File實例
File file1 = new File("C:\\itheima");
String path = "a.txt";
File file = new File(file1,path);
System.out.println(file);//C:\itheima\a.txt
}
private static void method2() {
//File•(String parent, String child) 從父路徑名字符串和子路徑名字符串創建新的File實例
String path1 = "C:\\itheima";
String path2 = "a.txt";
File file = new File(path1,path2);//把兩個路徑拼接.
System.out.println(file);//C:\itheima\a.txt
}
private static void method1() {
//File•(String pathname) 通過將給定的路徑名字符串轉換為抽象路徑名來創建新的File實例
String path = "C:\\itheima\\a.txt";
File file = new File(path);
//問題:為什麼要把字符串表示形式的路徑變成File對象?
//就是為了使用File類裏面的方法.
}
}
1.3 絕對路徑和相對路徑【了解】(視頻03)(5『』)
1.絕對路徑
是一個完整的路徑,從盤符開始
//(對比)
2.相對路徑
是一個簡化的路徑,默認是相對當前項目下的路徑
示例代碼
package com.itheima.filedemo;
import java.io.File;
public class FileDemo2 {
public static void main(String[] args) {
//這個路徑固定不變了.
File file = new File("D:\\itheima\\a.txt");
System.out.println(file);
//當前項目下的a.txt
File file2 = new File("a.txt");
System.out.println(file2);
//當前項目下 --- 指定模塊下的 a.txt
File file3 = new File("filemodule\\a.txt");
System.out.println(file3.getAbsolutePath());
}
}
1.4File類創建功能【重點】(視頻04) (9『』)
1.方法
方法名 | 說明 | 注意事項 |
---|---|---|
public boolean createNewFile() | 創建一個新的空文件 | 如果路徑上的文件夾不存的話,就拋異常 :java.io.IOException: 系統找不到指定的路徑。 |
public boolean mkdir() | 創建一個單級文件夾 | 1.只能創建單級文件夾,不能創建多級文件夾 2.如果文件夾已經存在,創建失敗 |
public boolean mkdirs() | 創建多級文件夾 | 1,可以創建單級文件夾,也可以創建多級文件夾 2.文件夾已經存在,創建失敗 |
示例代碼
package com.itheima.filedemo;
import java.io.File;
import java.io.IOException;
public class FileDemo3 {
public static void main(String[] args) throws IOException {
//public boolean createNewFile() 創建一個新的空的文件
//注意點:
//1.如果文件存在,那麼創建失敗,返回false
//2.如果文件不存在,那麼創建成功,返回true
//3.createNewFile方法不管調用者有沒有後綴名,只能創建文件.
//public boolean mkdir() 創建一個單級文件夾
//注意點:
//1.只能創建單級文件夾,不能創建多級文件夾
//2.不管調用者有沒有後綴名,只能創建單級文件夾
//public boolean mkdirs() 創建一個多級文件夾
//注意點:
//1,可以創建單級文件夾,也可以創建多級文件夾
//2.不管調用者有沒有後綴名,只能創建文件夾
//疑問:
//既然mkdirs能創建單級,也能創建多級.那麼mkdir還有什麼用啊? 是的
//method1();
//method2();
File file = new File("C:\\itheima\\aaa.txt");
boolean result = file.mkdirs();
System.out.println(result);
}
//1.mkdir:創建文件夾
//2.只要我們起的文件夾名稱符合操作系統的要求
private static void method2() {
File file = new File("C:\\itheima\\aaa.txt");
boolean result = file.mkdir();
System.out.println(result);
}
//1.createNewFile:創建文件
//2.文件路徑字符串中最後\\之前的路徑必須存在
//3. 文件名只要符合操作系統對文件名的規定就可以創建成功
//4. 如果文件不存在,ture,如果存在false
private static void method1() throws IOException {
File file1 = new File("C:\\itheima\\aaa");
boolean result1 = file1.createNewFile();
System.out.println(result1);
}
}
1.5File類刪除功能【重點】(視頻05) (4”)
方法分類
方法名 | 說明 | 注意事項 |
---|---|---|
public boolean delete() | 刪除File表示的文件或目錄 | 1.不走回收站的 2.只能刪除文件和空文件夾 3.有權限問題的話,無法刪除,並且無提示 |
示例代碼
package com.itheima.filedemo;
import java.io.File;
public class FileDemo4 {
//注意點:
//1.不走回收站的.
//2.如果刪除的是文件,那麼直接刪除.如果刪除的是文件夾,那麼能刪除空文件夾
//3.如果要刪除一個有內容的文件夾,只能先進入到這個文件夾,把裏面的內容全部刪除完畢,才能再次刪除這個文件夾
//簡單來說:
//只能刪除文件和空文件夾.
public static void main(String[] args) {
//method1();
File file = new File("C:\\itheima");
boolean result = file.delete();
System.out.println(result);
}
private static void method1() {
File file = new File("C:\\itheima\\a.txt");
boolean result = file.delete();
System.out.println(result);
}
}
1.6File類判斷和獲取功能【重點】(視頻06) (6”)
1.判斷方法
方法名 | 說明 |
---|---|
public boolean isDirectory() | 測試File是否為目錄(文件夾) |
public boolean isFile() | 測試File是否為文件 |
public boolean exists() | 測試File是否存在 |
2.獲取方法
方法名 | 說明 |
---|---|
public String getName() | 只返回File表示的文件名稱或文件夾的名稱 |
示例代碼
package com.itheima.filedemo;
import java.io.File;
public class FileDemo5 {
//public boolean isDirectory() 測試此抽象路徑名表示的File是否為目錄
//public boolean isFile() 測試此抽象路徑名表示的File是否為文件
//public boolean exists() 測試此抽象路徑名表示的File是否存在
//public String getName() 返回由此抽象路徑名表示的文件或目錄的名稱
//注意點:
//1.如果調用者是文件,那麼獲取的是文件名和後綴名
//2.如果調用者是一個文件夾,那麼獲取的是文件夾的名字
public static void main(String[] args) {
//method1();
//method2();
//method3();
File file = new File("a.txt");
String name = file.getName();
System.out.println(name);
File file1 = new File("C:\\itheima");
String name2 = file1.getName();
System.out.println(name2);
}
private static void method3() {
File file = new File("a.txt");
boolean result = file.exists();
System.out.println(result);
}
private static void method2() {
File file = new File("C:\\itheima");
boolean result1 = file.isFile();
boolean result2 = file.isDirectory();
System.out.println(result1);
System.out.println(result2);
}
private static void method1() {
File file = new File("C:\\itheima\\a.txt");
boolean result1 = file.isFile();
boolean result2 = file.isDirectory();
System.out.println(result1);
System.out.println(result2);
}
}
1.7 File的listFile方法 【重點】(視頻07) (7『』)
方法名 | 說明 | 注意事項 |
---|---|---|
File[] listFiles() | 獲取文件夾下的所有文件和文件夾對象,封裝到File數組中返回 | 1.File指向不存在,返回null 2.存在 2.1存在的是文件:返回null 2.2 存在的是文件夾:正常輸出,如果是空文件夾,返回長度為0的Fils數組 3.權限問題,沒有訪問權限,返回null |
示例代碼:
package com.itheima.filedemo;
import java.io.File;
public class FileDemo6 {
public static void main(String[] args) {
File file = new File("D:\\aaa");
//1.file可以表存在可以不存在,如果file不存,listFiles,返回null
//2.如果file表示的是存在的文件時,listFiles,返回null
//3.如果文件夾有權限的時,listFiles,返回null
File[] files = file.listFiles();//返回值是一個File類型的數組
System.out.println(files.length);
for (File path : files) {
System.out.println(path);
}
//進入文件夾,獲取這個文件夾裏面所有的文件和文件夾的File對象,並把這些File對象都放在一個數組中返回.
//包括隱藏文件和隱藏文件夾都可以獲取.
//注意事項:
//1.當調用者是一個文件時
//2,當調用者是一個空文件夾時
//3.當調用者是一個有內容的文件夾時
//4.當調用者是一個有權限才能進入的文件夾時
}
}
1.8File類練習一【重點】(視頻08) (5『』)
1.案例需求
在當前模塊下的aaa文件夾中創建一個a.txt文件
2.實現步驟
-
創建File對象,指向aaa文件夾
-
判斷aaa文件夾是否存在,如果不存在則創建
-
創建File對象,指向aaa文件夾下的a.txt文件
-
創建這個文件
代碼實現
public class Test1 {
public static void main(String[] args) throws IOException {
//練習一:在當前模塊下的aaa文件夾中創建一個a.txt文件
/* File file = new File("filemodule\\aaa\\a.txt");
file.createNewFile();*/
//注意點:文件所在的文件夾必須要存在.
//1.創建File對象,指向aaa文件夾
File file = new File("filemodule\\aaa");
//2.判斷aaa文件夾是否存在,如果不存在則創建
if(!file.exists()){
//如果文件夾不存在,就創建出來
file.mkdirs();
}
//3.創建File對象,指向aaa文件夾下的a.txt文件
File newFile = new File(file,"a.txt");
//4.創建這個文件
newFile.createNewFile();
}
}
1.9File類練習二【重點】(視頻09)(7『』)
1.案例需求
刪除一個多級文件夾
2.實現步驟
-
定義一個方法,接收一個File對象
-
遍歷這個File對象,獲取它下邊的每個文件和文件夾對象
-
判斷當前遍歷到的File對象是文件還是文件夾
-
如果是文件,直接刪除
-
如果是文件夾,遞歸調用自己,將當前遍歷到的File對象當做參數傳遞
-
參數傳遞過來的文件夾File對象已經處理完成,最後直接刪除這個空文件夾
代碼實現
package com.itheima.filetest;
import java.io.File;
public class Test2 {
public static void main(String[] args) {
//練習二:刪除一個多級文件夾
//delete方法
//只能刪除文件和空文件夾.
//如果現在要刪除一個有內容的文件夾?
//先刪掉這個文件夾裏面所有的內容.
//最後再刪除這個文件夾
File src = new File("C:\\Users\\apple\\Desktop\\src");
deleteDir(src);
}
private static void deleteDir(File src) {
//先刪掉這個文件夾裏面所有的內容.
//遞歸 方法在方法體中自己調用自己.
//注意: 可以解決所有文件夾和遞歸相結合的題目
//1.進入 --- 得到src文件夾裏面所有內容的File對象.
File[] files = src.listFiles();
//2.遍歷 --- 因為我想得到src文件夾裏面每一個文件和文件夾的File對象.
for (File file : files) {
if(file.isFile()){
//3.判斷 --- 如果遍歷到的File對象是一個文件,那麼直接刪除
file.delete();
}else{
//4.判斷
//遞歸
deleteDir(file);//參數一定要是src文件夾裏面的文件夾File對象
}
}
//最後再刪除這個文件夾
src.delete();
}
}
1.10 File類練習的遞歸分析(難點) (視頻10)(6”)
1.11File類練習三【難點】(視頻11) (8”)
(共3點)
1.案例需求
統計一個文件夾中每種文件的個數並打印
打印格式如下:
txt:3個 doc:4個 jpg:6個 …
2.實現步驟
-
定義一個方法,參數是HashMap集合用來統計次數和File對象要統計的文件夾
-
遍歷File對象,獲取它下邊的每一個文件和文件夾對象
-
判斷當前File對象是文件還是文件夾
-
如果是文件,判斷這種類型文件後綴名在HashMap集合中是否出現過
-
沒出現過,將這種類型文件的後綴名存入集合中,次數存1
-
出現過,獲取這種類型文件的後綴名出現的次數,對其+1,在存回集合中
-
-
如果是文件夾,遞歸調用自己,HashMap集合就是參數集合,File對象是當前文件夾對象
代碼實現
package com.itheima.filetest;
import java.io.File;
import java.util.HashMap;
public class Test3 {
public static void main(String[] args) {
//統計一個文件夾中,每種文件出現的次數.
//統計 --- 定義一個變量用來統計. ---- 弊端:同時只能統計一種文件
//利用map集合進行數據統計,鍵 --- 文件後綴名 值 ---- 次數
File file = new File("filemodule");
HashMap<String, Integer> hm = new HashMap<>();
getCount(hm, file);
System.out.println(hm);
}
/***
* 獲取文件夾下的每種文件出現的次數
* @param hm 存儲每種文件出現的次數
* 每種文件與出現的個數之間,是一一對應的關係
* 因此文件類型作為key,出現的個數作為value
* @param file 被統計的文件夾
*/
private static void getCount(HashMap<String, Integer> hm, File file) {
//1.第一步,遍歷獲取文件夾下所有的文件和文件夾
File[] files = file.listFiles();
//2.遍歷
for (File f : files) {
//3.判斷是不是文件
if(f.isFile()){
//3.1 如果是文件,獲取文件的後綴名
String fileName = f.getName();
String[] fileNameArr = fileName.split("\\.");
if(fileNameArr.length == 2){
String fileEndName = fileNameArr[1];
//3.2 判斷map集合中有沒有文件後綴的key
if(hm.containsKey(fileEndName)){
//3.2.1 如果有表示存在,將已經出現的次數獲取出來
Integer count = hm.get(fileEndName);
//3.2.2 將出現的次數加1
count++;
//3.2.3 將新的次數賦值給對應的後綴名
hm.put(fileEndName,count);
}else{
//3.3 如果不存在,直接放入map集合中,次數為1
hm.put(fileEndName,1);
}
}
}else{
//4.不是文件,繼續調用方法自己獲取文件夾下每種文件出現的次數
getCount(hm,f);
}
}
}
}
3.代碼分析
小結
1.什麼是File類
2.如何創建File對象?
3.相對路徑和絕對路徑
4.File對象中常見的方法
2.IO
2.1 IO 的概述【了解】(視頻12) (4『』)
1.什麼IO流(輸入和輸出站在內存方來說的)
I表示intput,是數據從硬盤進內存的過程,稱之為讀
O表示output,是數據從內存到硬盤的過程,稱之為寫
流是一種抽象概念,數據在設備間的傳輸稱為流,流的本質是數據傳輸
2.2 IO流分類【重點】(視頻13) (5『』)
1.IO流的體系
3.位元組流
3.1 位元組流-位元組輸出流快速入門【重點】(視頻14) (4『』)
1.位元組流的抽象基類
-
InputStream:這個抽象類是表示位元組輸入流的所有類的超類
-
OutputStream:這個抽象類是表示位元組輸出流的所有類的超類
-
子類名特點:子類名稱都是以其父類名作為子類名的後綴
2.如何讀寫文件?
使用FileInputStream和FileOutputStream讀寫文件
3.使用位元組輸出流寫數據的步驟
package com.itheima.output;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class OutputDemo1 {
public static void main(String[] args) throws IOException {
//1.創建位元組輸出流的對象 --- 告訴虛擬機我要往哪個文件中寫數據了
FileOutputStream fos = new FileOutputStream("D:\\a.txt");
//FileOutputStream fos = new FileOutputStream(new File("D:\\a.txt"));
//2,寫數據
fos.write(97);
//3,釋放資源
fos.close();
}
}
3.2 位元組流-注意事項 (了解) (視頻15)(5”)
public class OutputDemo2 {
public static void main(String[] args) throws IOException {
//1.創建位元組輸出流的對象
//注意點:如果文件不存在,會幫我們自動創建出來.
// 如果文件存在,會把文件清空.
FileOutputStream fos = new FileOutputStream("C:\\itheima\\a.txt");
//2,寫數據 傳遞一個整數時,那麼實際上寫到文件中的,是這個整數在碼錶中對應的那個字符.
fos.write(98);
//3,釋放資源
fos.close(); //告訴操作系統,我現在已經不再用這個文件了.
}
}
3.3位元組流-一次寫多個數據【重點】(視頻16)(5”)
-
寫數據的方法分類
方法名 說明 void write(int b) 將指定的位元組寫入此文件輸出流 一次寫一個位元組數據 void write(byte[] b) 將 b.length位元組從指定的位元組數組寫入此文件輸出流 一次寫一個位元組數組數據 void write(byte[] b, int off, int len) 將 len位元組從指定的位元組數組開始,從偏移量off開始寫入此文件輸出流 一次寫一個位元組數組的部分數據 -
示例代碼
package com.itheima.output;
import java.io.FileOutputStream;
import java.io.IOException;
public class OutputDemo4 {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("bytestream\\a.txt");
/*byte [] bys = {97,98,99};
fos.write(bys);*/
byte [] bys = {97,98,99,100,101,102,103};
fos.write(bys,1,2);
fos.close();
}
}
3.4位元組流寫數據的兩個小問題【重點】(視頻17) (6『』)
(共2點)
1.位元組流寫數據如何實現換行
-
windows:\r\n
-
linux:\n
-
mac:\r
//System.getProperty("line.separator")
package com.itheima.output;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class OutputDemo5 {
public static void main(String[] args) throws IOException {
//第二個參數就是續寫開關,如果沒有傳遞,默認就是false,
//表示不打開續寫功能,那麼創建對象的這行代碼會清空文件.
//如果第二個參數為true,表示打開續寫功能
//那麼創建對象的這行代碼不會清空文件.
FileOutputStream fos = new FileOutputStream("bytestream\\a.txt");
fos.write(97);
//能加一個換行
fos.write("\r\n".getBytes());
fos.write(98);
//能加一個換行
fos.write("\r\n".getBytes());
fos.write(99);
//能加一個換行
fos.write("\r\n".getBytes());
fos.write(100);
//能加一個換行
fos.write("\r\n".getBytes());
fos.write(101);
//能加一個換行
fos.write("\r\n".getBytes());
fos.close();
}
}
2.位元組流寫數據如何實現追加寫入
-
public FileOutputStream(String name,boolean append)
-
創建文件輸出流以指定的名稱寫入文件。如果第二個參數為true ,則位元組將寫入文件的末尾而不是開頭
示例代碼
package com.itheima.output;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class OutputDemo5 {
public static void main(String[] args) throws IOException {
//第二個參數就是續寫開關,如果沒有傳遞,默認就是false,
//表示不打開續寫功能,那麼創建對象的這行代碼會清空文件.
//如果第二個參數為true,表示打開續寫功能
//那麼創建對象的這行代碼不會清空文件.
FileOutputStream fos = new FileOutputStream("bytestream\\a.txt",true);
fos.write(97);
//能加一個換行
//System.getProperty("line.separator")
fos.write("\r\n".getBytes());
fos.write(98);
//能加一個換行
fos.write("\r\n".getBytes());
fos.write(99);
//能加一個換行
fos.write("\r\n".getBytes());
fos.write(100);
//能加一個換行
fos.write("\r\n".getBytes());
fos.write(101);
//能加一個換行
fos.write("\r\n".getBytes());
fos.close();
}
}
3.5位元組流寫數據加異常處理【重點】(視頻18) (6『』)
1.如何捕獲異常呢?
try-catch-finally
2.異常處理格式
try{
可能出現異常的代碼;
}catch(異常類名 變量名){
異常的處理代碼;
}finally{
執行所有清除操作;
}
3.為什麼要使用finally
被finally控制的語句一定會執行 不管有沒有異常,也不管異常有沒有被捕獲,除非JVM退出
示例代碼
package com.itheima.output;
import java.io.FileOutputStream;
import java.io.IOException;
public class OutputDemo6 {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
//System.out.println(2/0);
fos = new FileOutputStream("D:\\a.txt");
fos.write(97);
}catch(IOException e){
e.printStackTrace();
}finally {
//finally語句裏面的代碼,一定會被執行.
if(fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3.6 位元組流-寫文本數據小結【重點】 (視頻19)(1”)
3.7位元組流-位元組輸入流基本學習(一次讀一個位元組數據)【重點】(視頻20) (5『』)
1.如何讀文件?
import java.io.FileInputStream類
2.構造方法
方法 | 說明 |
---|---|
FileInputStream(File file) |
通過打開與實際文件的連接來創建一個 FileInputStream ,該文件由文件系統中的 File 對象 file 命名。 |
FileInputStream(String name) |
通過打開與實際文件的連接來創建一個 FileInputStream ,該文件由文件系統中的路徑名 name 命名 |
3.位元組輸入流讀取文件數據的步驟
-
創建位元組輸入流對象
-
調用位元組輸入流對象的讀數據方法
-
釋放資源
示例代碼
package com.itheima.output; import java.io.FileInputStream; import java.io.IOException; public class OutputDemo7 { public static void main(String[] args) throws IOException { //如果文件存在,那麼就不會報錯. //如果文件不存在,那麼就直接報錯. FileInputStream fis = new FileInputStream("bytestream\\a.txt"); int read = fis.read(); //一次讀取一個位元組,返回值就是本次讀到的那個位元組數據. //也就是字符在碼錶中對應的那個數字. //如果我們想要看到的是字符數據,那麼一定要強轉成char System.out.println((char)read); //釋放資源 fis.close(); } }
3.8 位元組流讀取多個位元組 (重點) (視頻21) (4”)
package com.itheima.output; import java.io.FileInputStream; import java.io.IOException; public class OutputDemo8 { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("bytestream\\a.txt"); //1,文件中多個位元組我怎麼辦? /*while(true){ int i1 = fis.read(); System.out.println(i1); }*/ int b; while ((b = fis.read())!=-1){ System.out.println((char) b); } fis.close(); } }
3.9位元組流複製文件【重點】(視頻22) (6『』)
案例需求
把「E:\itcast\窗里窗外.txt」複製到模塊目錄下的「窗里窗外.txt」 (文件可以是任意文件)
實現步驟
-
複製文本文件,其實就把文本文件的內容從一個文件中讀取出來(數據源),然後寫入到另一個文件中(目的地)
-
數據源:
E:\itcast\窗里窗外.txt — 讀數據 — InputStream — FileInputStream
-
目的地:
myByteStream\窗里窗外.txt — 寫數據 — OutputStream — FileOutputStream
代碼實現
package com.itheima.output; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class OutputDemo9 { public static void main(String[] args) throws IOException { //創建了位元組輸入流,準備讀數據. FileInputStream fis = new FileInputStream("C:\\itheima\\a.avi"); //創建了位元組輸出流,準備寫數據. FileOutputStream fos = new FileOutputStream("bytestream\\a.avi"); int b; while((b = fis.read())!=-1){ fos.write(b); } fis.close(); fos.close(); } }
3.10位元組流-定義小數組拷貝【重點】(視頻23)(8『』)
1.如何提高文件拷貝的速度?
一次性讀寫多個位元組
2.方法
方法 | 說明 |
---|---|
public int read(byte[] b) throws IOException | 從輸入流讀取最多b.length 個位元組的數據放入數組中 |
public void write(byte b[], int off, int len) throws IOException | 從位元組數組下標off開始,將其中len個數據寫入到文件的輸出流中 |
示例代碼
package com.itheima.output; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class OutputDemo10 { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("C:\\1.mp4"); FileOutputStream fos = new FileOutputStream("bytestream\\1.mp4"); byte [] bytes = new byte[1024]; int len;//本次讀到的有效位元組個數 --- 這次讀了幾個位元組 while((len = fis.read(bytes))!=-1){ System.out.println(bytes); fos.write(bytes,0,len); } fis.close(); fos.close(); } }
3.11 位元組流-小數組拷貝的原理【難點】 (視頻24) (5『』) 填數據
小結
1.什麼是IO流?
2.IO流的分類?
3.位元組輸入流?
4.位元組輸出流?
5.如何提高讀寫效率?
4.位元組緩衝流
4.1位元組緩衝流-一次讀寫一個位元組代碼實現【重點】(視頻25) (7『』)
1.位元組緩衝流介紹
-
BufferedOutputStream:位元組緩衝輸出流
-
BufferedInputStream: 位元組緩衝輸入流
2.如何使用?(共兩點)
2.1 構造方法:
方法名 | 說明 |
---|---|
BufferedOutputStream(OutputStream out) | 創建位元組緩衝輸出流對象 |
BufferedInputStream(InputStream in) | 創建位元組緩衝輸入流對象 |
為什麼構造方法需要的是位元組流,而不是具體的文件或者路徑?
2.2 常用方法
方法 | 說明 |
---|---|
public int read() throws IOException | 從輸入流中讀出8192個位元組到緩衝數組中,再從緩衝數組中取出一個位元組 |
public void write(int b) throws IOException | 將位元組b寫入到緩衝數組中,當緩衝數組滿時,一次性寫入目標文件 |
示例代碼
package com.itheima.output; import java.io.*; public class OutputDemo11 { public static void main(String[] args) throws IOException { //就要利用緩衝流去拷貝文件 //創建一個位元組緩衝輸入流 //在底層創建了一個默認長度為8192的位元組數組。 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bytestream\\a.avi")); //創建一個位元組緩衝輸出流 //在底層也創建了一個默認長度為8192的位元組數組。 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bytestream\\copy.avi")); int b; while((b = bis.read()) != -1){ bos.write(b); } //方法的底層會把位元組流給關閉。 bis.close(); bos.close(); } }
4.2位元組緩衝流一次讀寫一個位元組代碼原理【難點 】(視頻26)(7『』)
1.位元組緩衝輸入流每次讀取buffer長度個位元組
2.位元組緩衝輸出流寫數據時先將緩衝位元組輸入流緩衝數組中的數據每次轉移1個位元組到自己的緩衝數組中,當緩衝數組滿時,位元組流一次性寫出緩衝數組長度個位元組
3.如果緩衝數組不滿時,當調用緩衝流的close()方法時會將緩衝數組中數據寫出
4.3位元組緩衝流一次讀寫一個位元組數組【重點 】(視頻27)(6『』)
(共3點)
1.方法
方法 | 說明 |
---|---|
public int read(byte b[]) throws IOException | 從輸入流中讀出8192個位元組到緩衝數組中,再從緩衝數組中取出數組b.length個位元組到數組b中 |
public void write(byte b[], int off, int len) throws IOException | 將數組b中的元素,從下標0開始,向緩衝數組中寫入len個位元組,當緩衝數組滿時,一次性寫入目的地 |
2.代碼實現
package com.itheima.output; import java.io.*; public class OutputDemo12 { public static void main(String[] args) throws IOException { //緩衝流結合數組,進行文件拷貝 //創建一個位元組緩衝輸入流 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bytestream\\a.avi")); //創建一個位元組緩衝輸出流 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bytestream\\copy.avi")); byte [] bytes = new byte[1024]; int len; while((len = bis.read(bytes)) != -1){ bos.write(bytes,0,len); } bis.close(); bos.close(); } }
3.原理
1.位元組緩衝輸入流每次讀取buffer長度個位元組
2.位元組緩衝輸出流寫數據時先將緩衝位元組輸入流緩衝數組中的數據每次轉移bytes長度個位元組到自己的緩衝數組中,當緩衝數組滿時,位元組流一次性寫出緩衝數組長度個位元組
3.如果緩衝數組不滿時,當調用緩衝流的close()方法時會將緩衝數組中數據寫出
4.4 小結 【重點】(視頻28)(2『』)
如果不自定義數組,使用緩衝流的效率比位元組流要高
擴展練習
題目1[File]
請在D盤根目錄下創建一個文件:test1.txt(隨意錄入一些內容),再創建一個目錄:測試目錄
要求:
-
獲取、打印file1和file2的絕對路徑;
-
獲取、打印file1和file2的文件名和目錄名;
-
獲取、打印file1和file2的文件大小;
-
分別判斷file1和file2是否存在;
-
分別判斷file1和file2是否是文件?是否是目錄?
效果:
參考代碼:
package day11.No_1;
import java.io.File;
public class Demo {
public static void main(String[] args) {
File file1=new File("E:\\test1.txt");
File file2=new File("E:\\測試目錄");
System.out.println("文件1的絕對路徑是:"+file1);
System.out.println("文件夾2的絕對路徑是:"+file2);
String name1 = file1.getName();
String name2 = file2.getName();
System.out.println("文件1長度:"+file1.length());
System.out.println("文件夾2長度:"+file2.length());
System.out.println("文件1的名稱是:"+name1);
System.out.println("文件夾2的名稱是:"+name2);
System.out.println("file1文件夾存在嗎?"+file1.exists());
System.out.println("file2文件夾存在嗎"+file2.exists());
System.out.println("file1是文件嗎"+file1.isFile());
System.out.println("file2是文件嗎"+file2.isFile());
}
}
運行效果:
題目2[File]
請編寫main()方法,創建以下File對象:
File file1 = new File(「test.txt」);//相對路徑
File file2 = new File(「一級目錄」);
File file3 = new File(「目錄A/目錄B/目錄C」);
要求:
(相對路徑,可以相對於項目也可以相對於模塊)
-
判斷file1是否存在?如果不存在,創建這個文件。
-
判斷file2是否存在?如果不存在,創建這個目錄。
-
判斷file3是否存在?如果不存在,創建這個多級目錄。
-
效果:
參考代碼:
package day11.No_2;
import java.io.File;
import java.io.IOException;
public class Demo {
public static void main(String[] args) throws IOException {
File file1 = new File("test.txt");//相對路徑
File file2 = new File("mrlx\\ccc");
File file3=new File("aaa\\aa\\aa");
if (!file1.exists()){
System.out.println(file1.createNewFile());
}
if (!file2.exists()){
System.out.println(file2.mkdir());
}
if (!file3.exists()){
System.out.println(file3.mkdirs());
}
}
}
題目3[File]
請在D盤下創建一個目錄「多級目錄」,下面隨意創建一些文件和目錄。
請編寫main()方法,創建以下File對象:
File file = new File(「D:\多級目錄」);
要求:
遍歷這個多級文件夾下的所有內容(包含子文件夾的內容),判斷每個File對象是否文件
如果是文件,打印:【文件】+ 絕對路徑
如果是目錄,打印:【目錄】+ 絕對路徑
效果
參考代碼:
package day11.No_3;
import java.io.File;
public class Demo3 {
public static void main(String[] args) {
File file=new File("E:\\itheima");
getMulu(file);
}
private static void getMulu(File file) {
File[] files = file.listFiles();
for (File f : files) {
if (f.isFile()){
System.out.println("文件"+f.getAbsolutePath());
}else{
System.out.println("文件夾"+f.getAbsolutePath());
getMulu(f);
}
}
}
}
運行效果:
題目4[File綜合題有難度]
請使用代碼計算出你電腦上的任意一個文件夾中的大小。
必須是一個多層文件夾;
效果
(每個人的具體數據都不一樣,以實際情況為準)
參考代碼:
package day11.No_4;
import java.io.File;
public class Demo {
public static void main(String[] args) {
File file=new File("E:\\臨時文件");
long len=getLeng(file);
System.out.println(len);
}
private static long getLeng(File file) {
File[] files = file.listFiles();
long len=0;
for (File f : files) {
if (f.isFile()){
len += f.length();
}else {
getLeng(f);
}
}
return len;
}
}
運行效果:

題目5[IO]
使用鍵盤輸入多個學生的信息,並將這些學生的信息保存到模塊的1.txt文件中;
要求:
1:學生信息包含姓名、年齡(用一行字符串表示即可,無需創建學生對象);
2:每個學生信息佔一行,學生信息之間使用逗號分隔;
3:至少輸入3個學生信息;
效果
參考代碼:
package day11.No_5;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;
public class Demo {
public static void main(String[] args) throws IOException {
FileOutputStream f=new FileOutputStream("1.txt");
Scanner sc=new Scanner(System.in);
int i=1;
while (true){
System.out.println("請輸入第"+i+"個學生的信息,用逗號分隔");
String s = sc.next();
if (s.equals("ok")){
System.out.println("拜拜!");
break;
}
f.write((s+"\r\n").getBytes());
i++;
}
f.close();
}
}
題目6[IO-綜合題2有難度-明天做會更簡單]
將上一題產生的文件中的學生按照年齡升序排序後重新寫回原文件;
效果
1.txt文件排序前:
1.txt文件排序後:
public static void main(String[] args) throws Exception {
File f = new File("1.txt");
//創建文件對象,準備讀數據
FileInputStream fin = new FileInputStream(f);
byte[] arr = new byte[(int)f.length()];//文件中有多少位元組,就創建多大的數組,一次性讀完
fin.read(arr);//讀到的數據都保存到了arr中
//把數組轉成字符串
String s = new String(arr);
//使用換行符切分字符串
String[] split = s.split("\r\n");
//再使用逗號切分數組中的每一個元素,可以得到學生的姓名和年齡
//創建set集合併指定排序規則
TreeSet<Student> set = new TreeSet<>((s1,s2)->s1.getAge()-s2.getAge()==0?s1.getName().compareTo(s2.getName()):s1.getAge()-s2.getAge());
for (String s1 : split) {
String[] split1 = s1.split(",");
//把按照切分出來的數組的第1個值作為name,第二個值作為age創建學生對象,並按照年齡排序
Student stu = new Student(split1[0],Integer.parseInt(split1[1]));
set.add(stu);
}
//創建輸出流,並把set集合中的學生信息重新寫入1.txt文件中;(重寫Student的toString方法了)
FileOutputStream fout = new FileOutputStream("1.txt");
for (Student stu : set) {
fout.write((stu.toString()+"\r\n").getBytes());
}
fin.close();
fout.close();
System.out.println("排序已完成");
}