重難點提示
學習目標
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("排序已完成");
}