1. 程式人生 > 其它 >14、java——IO流

14、java——IO流

3、IO流

(1)前提需求: 讀寫檔案內部的內容,上傳,下載

(2)流: 管道 資料以先入先出的方式進行流動,資料來源--資料-->目的地

(3)io包: 一系列io相關類 File...

(4)流的分類:

①按照流向分:

輸入流,輸出流

(以大腦為中心,以程式為中心,明確資料來源和目的地,能夠確定輸入還是輸出)

②按照操作單元分;

位元組流 : 萬能流,任意內容都能轉為位元組,字元流 : 只能傳輸純文字的內容

③按照功能分:

節點流 : 真實做讀入寫出的流,功能流 : 增強節點流的功能,加強效能

分類之間是相輔相成的

(5)位元組流:

①位元組輸入流 InputStream

檔案位元組輸入流 FileInputStream

功能: 節點流 流向分:輸入流 操作單元:位元組流

功能: 讀入read() 關閉close

②位元組輸出流 OutputStream

public class Class001_IO {

public static void main(String[] args) throws IOException {

//FileInputStream(File file) 通過開啟與實際檔案的連線來建立 FileInputStream ,該檔案由檔案系統中的 File物件 file命名。

File src = new File("D://test2.txt"); //資料來源

//建立流

InputStream is = new FileInputStream(src);

//讀入資料 int read() 從此輸入流中讀取一個位元組的資料。 讀到檔案末尾返回-1

int num = is.read();

//處理資料

System.out.println((char)num);

System.out.println((char)(is.read()));

System.out.println((char)(is.read()));

System.out.println(is.read());

//關閉流

is.close();

}

}

③read() 從此輸入流中讀取一個位元組的資料。 讀到檔案末尾返回-1

每次讀取一個位元組,重複通過迴圈讀入,可以簡化程式碼結構

public class Class002_IO {

public static void main(String[] args) throws IOException {

//建立流

//FileInputStream (String name) 通過開啟與實際檔案的連線來建立 FileInputStream ,該檔案由檔案系統中的路徑名 name命名。

InputStream is = new FileInputStream("D://test2.txt");

//讀入資料

int num = -1;

while((num=is.read())!=-1){

//處理資料

System.out.println((char)num);

}

//關閉流

is.close();

}

}

④public byte[] readAllBytes() throws IOException

從輸入流中讀取所有剩餘位元組。 此方法將阻塞,直到讀取了所有剩餘位元組並檢測到流結束,或者丟擲異常。 此方法不會關閉輸入流。

當此流到達流的末尾時,此方法的進一步呼叫將返回空位元組陣列,請注意,此方法適用於方便將所有位元組讀入位元組陣列的簡單情況。 它不用於讀取包含大量資料的輸入流。起始版本: java9

public class Class004_IO {

public static void main(String[] args) throws IOException {

//1.構建流

InputStream is = new FileInputStream("D://test2.txt");



//2.讀入所有資料

byte[] arr = is.readAllBytes();

//3.處理資料

System.out.println(new String(arr));



//4.關閉

is.close();

}

}

(6)位元組輸出流

①OutputStream 此抽象類是表示輸出位元組流的所有類的超類。

②FileOutputStream : 檔案輸出流,將資料寫出到指定檔案中

③注意:如果目的地檔案不存在,系統會自動建立

輸出流如果目的地檔案存在,內容預設覆蓋,設定追加

(7)檔案拷貝,資料來源--> 讀入---> 程式 --> 寫出 --> 目的地

步驟:①建立流(輸入 輸出)②準備小汽車 位元組陣列③讀入-->寫出④刷出⑤關閉(後開啟的先關閉)

public class Class006_CopyFile {

public static void main(String[] args){

//1.建立流(輸入 輸出)

//作用域提升,為了能夠在finally中使用

InputStream is = null;

OutputStream os = null;

try {

is = new FileInputStream("D://test.txt");

os = new FileOutputStream("D://dest.txt");

//2.準備小汽車 位元組陣列

byte[] car = new byte[1024];

//3.讀入-->寫出

int len = -1; //記錄每次讀入到位元組陣列中資料的個數

while((len=is.read(car))!=-1){

//讀入多少位元組資料寫出多少位元組資料

os.write(car,0,len);

}

//4.刷出

os.flush();

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} finally {

//5.關閉(後開啟的先關閉)

//預防空指標異常出現

if(os!=null){

try {

os.close();

} catch (IOException e) {

e.printStackTrace();

}

}

if(is!=null){

try {

is.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

}

(8)字元輸入流 : 只能讀寫純文字資料

①輸入流 : Reader 字元輸入流的父類FileReader 檔案字元輸入流read(),read(char[]),close()

②輸出流 : Writer

public class Class001_IO {

public static void main(String[] args) throws IOException {

//1.建立流

//FileReader(String fileName)

//FileReader(File file)

Reader rd = new FileReader("D://test.txt");



//2.讀入

//char ch = (char)(rd.read());

//小汽車

char[] car = new char[1024];



//迴圈讀入

int len = -1;

while((len = rd.read(car))!=-1){

//3.處理資料

System.out.println(new String(car,0,len));

}



//4.關閉

rd.close();

}

}

③輸出流 : Writer 字元輸出流抽象父類,FileWriter 檔案字元輸出流write(),flush(),close()

public class Class002_IO {

public static void main(String[] args) throws IOException {

//1.建立流

/*

//FileWriter(File file)

//FileWriter(String fileName)

//FileWriter(File file, boolean append)

//FileWriter(String fileName, boolean append)

*/
 Writer rt = new FileWriter("D://test.txt",true);



//2.準備資料

String msg = "今天也要加油鴨!!!";



//3.寫出

rt.write(msg);



//4.刷出

rt.flush();



//5.關閉

rt.close();

}

}

④字元流實現檔案拷貝,注意: 只能為純文字檔案

1、拷貝資料夾 :

(1)判斷要拷貝的檔案是檔案還是資料夾

是檔案: 呼叫工具類實現檔案拷貝

是資料夾: 建立資料夾,遍歷資料來源資料夾,獲取到所有的子檔案然後重複

public static void main(String[] args) {
copyDir("D://DDD","D://haha");
}
//拷貝資料夾
public static void copyDir(String src,String dest){
copyDir(src!=null?new File(src):null,dest!=null?new File(dest):null);
}
public static void copyDir(File src, File dest){
if(src==null || dest==null){
throw new NullPointerException();
}
if(!src.exists()){
System.out.println("資料來源不存在!!!");
return;
}
//拷問資料夾|檔案
copyDetail(src,dest);
}
//實現拷貝細節
public static void copyDetail(File src,File dest){
//拼接完整目的地路徑
dest = new File(dest,src.getName()); //D:\haha\hehe\DDD
//檔案
if(src.isFile()){
//如果目的地路徑不存在
if(!dest.getParentFile().exists()){
dest.getParentFile().mkdirs();
}
//檔案拷貝
CopyFileUtils.copyFile(src,dest);

}else if (src.isDirectory()){
//資料夾
//建立不存在的目的地路徑
dest.mkdirs();
//遍歷資料來源
File[] arr = src.listFiles();
for(File file:arr){ //D:\DDD\a.txt
copyDetail(file,dest); ////D:\haha\hehe\DDD
}
}
}
}

(2)按照功能分:

①節點流 : 真實做讀入寫出②功能流 : 加強效能③功能流都要包裹節點流使用

④緩衝流 : 功能流⑤作用: 提高讀寫效率

⑥位元組節點流:

FileInputStream 檔案流 | ByteArrayInputStream 位元組陣列流

FileOutputStream | ByteArrayOutputStream

⑤位元組緩衝流 : 位元組流功能流的一種

BufferedInputStream 位元組輸入緩衝流

BufferedOutputStream 位元組輸出緩衝流

⑥無新增功能,可以發生多型

⑦字元節點流

FileReader,FileWriter

⑧字元緩衝流

BufferedReader,BufferedWriter

存在新增方法: 不能發生多型

readLine(),newLine()

public class Class001_Buffered {

public static void main(String[] args) throws IOException {

//1.建立流

InputStream is = new BufferedInputStream(new FileInputStream("D://test.txt"));

OutputStream os = new BufferedOutputStream(new FileOutputStream("D://heihei.txt"));

//2.拷貝

byte[] car = new byte[1024];

int len = -1;

while((len=is.read(car))!=-1){

os.write(car,0,len);

}

//3.刷出

os.flush();

//4.關閉

os.close();

is.close();

}

}

2、基本資料型別流|Data流

(1)功能: 功能流 操作單元: 位元組流

(2)作用: 保留資料已經資料型別(基本資料型別+String)

DataInputStream,新增功能: readXxx()

DataOutputStream,新增功能: writeXxx()

(3)注意:①讀入與寫出的順序要保持一致②java.io.EOFException : 讀入的檔案不是原始檔

public class Class001_Data {

public static void main(String[] args) throws IOException {

readFromFile("D:/d.txt");

}

//讀入

public static void readFromFile(String path) throws IOException {

//1.建立流

DataInputStream is = new DataInputStream(new BufferedInputStream(new FileInputStream(path)));

//2.讀入

int i = is.readInt();

boolean flag = is.readBoolean();

char ch = is.readChar();

String s = is.readUTF();

//3.處理資料

System.out.println(i);

System.out.println(flag);

System.out.println(ch);

System.out.println(s);

//4.關閉

is.close();

}

//寫出

public static void writeToFile(String path) throws IOException {

//1.建立輸出流

DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(path)));

//2.準備資料

int i = 1;

boolean flag = false;

char ch = 'c';

String str = "哈哈";

//3.寫出

out.writeInt(i);

out.writeBoolean(flag);

out.writeChar(ch);

out.writeUTF(str);

//4.刷出

out.flush();

//5.關閉

out.close();

}

}

3、Object 流| 物件流 | 引用資料型別流

(1)作用: 讀寫物件資料|引用資料型別的資料(包含基本資料型別)

ObjectInputStream 反序列化輸入流,新增功能: readObject()

ObjectOutputStream 序列化輸出流,新增功能: writeObject(Object obj)

(2)序列化: 將物件資料轉換一個可儲存或者可傳輸的狀態過程

(3)特性:

①先序列化後反序列化

②不能所有的型別都能序列化 java.io.Serializable

③不是所有的屬性都需要序列化

④靜態的內容不會序列化

⑤如果父類實現序列化,子類沒有實現,可以序列化所有的成員

⑥如果子類實現序列化,父類實現,只能序列化子類成員

(4)通過序列號控制版本不一致問題:

①實現Serializable介面的型別預設生成序列號,序列號會根據成員的修改做更新 serialVersionUID = -5204947308809070324

②控制版本的統一問題: 控制型別修改之前與之後序列不變

③通過工具生成序列號: a.實現Serializable介面 b.setting設定 c.選中類名->alt+enter->生成序列號

public class Class001_Object {

public static void main(String[] args) throws IOException, ClassNotFoundException {

//writeToFile("D://e.txt");

readFile("D://e.txt");

}

//反序列化

public static void readFile(String path) throws IOException, ClassNotFoundException {

//1.輸入流

ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(path)));

//2.讀入

User obj1 = (User) in.readObject();

int[] arr = (int[]) in.readObject();

//3.處理資料

System.out.println(obj1);

System.out.println(Arrays.toString(arr));

//4.關閉

in.close();

}

//序列化輸出

public static void writeToFile(String path) throws IOException {

//1.輸出流

ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(path)));

//2.資料

User user = new User("zhangsan",18,"123");

int[] arr = {1,2,3,4};

//3.寫出

out.writeObject(user);

out.writeObject(arr);

//4.刷出

out.flush();

//5.關閉

out.close();

//修飾user物件的成員,靜態

user.username = "lisi";

user.password = "4321";

}

}

class User implements Serializable{

private static final long serialVersionUID = -5204947308809070324L;

public String username;

//transient 修飾的欄位不會序列化

public transient int age;

public static String password;

//成員的修改: 新增的成員

public int vip;

public int id; //使用者編號

public User() {

}

public User(String username, int age, String password) {

this.username = username;

this.age = age;

this.password = password;

}

@Override

public String toString() {

return "User{" +

"username='" + username + '\'' +

", age=" + age +

", password='" + password + '\'' +

'}';

}

}

(1)CommonsIO 是apache的一個開源的工具包,封裝了IO操作的相關類,使用Commons IO可以很方便的讀寫檔案,url原始碼等。

(2)使用第三方元件的方式|步驟:

①下載原始碼資源,找到核心jar包

②專案下新建資料夾lib,放入jar包

③commons-IO 需要加入classpath 的第三方 jar 包內的 class 檔案才能在專案中使用,選中jar包右鍵->add as lib...

public class Class001_CommonsIO {

public static void main(String[] args) throws IOException {

//1.建立File物件

File src = new File("D://a.txt");

File dest = FileUtils.getFile("D://f.txt");

//FilenameUtils

//isExtension(String fileName, String text) // 判斷fileName是否是text字尾名

//FilenameUtils.getBaseName(String filename) // 去除目錄和字尾後的檔名 System.out.println(FilenameUtils.getBaseName("D://DDD/haha.txt"));; System.out.println(FilenameUtils.getName("D://DDD/haha.txt"));; System.out.println(FilenameUtils.isExtension("D://DDD/haha.txt","txt"));;

//FileUtils

//FileUtils.copyFile(File srcFile, File destFile)` // 複製檔案

FileUtils.copyFile(src,dest);

// **複製資料夾**

//FileUtils.copyDirectory(File srcDir, File destDir)` // 複製資料夾(資料夾裡面的檔案內容也會複製)

FileUtils.copyDirectory(new File("D://DDD"), new File("D://hehe/DDD"));

//FileUtils.copyDirectory(File srcDir, File destDir, FileFilter filter)` // 複製資料夾,帶有檔案過濾功能

FileUtils.copyDirectory(new File("D://DDD"), new File("D://houhou/DDD"), FileFilterUtils.fileFileFilter());

//**把字串寫入檔案**

//`FileUtils.writeStringToFile(File file, String data, String encoding)` // 字串以指定的編碼寫到檔案

//`FileUtils.writeStringToFile(File file, String data, String encoding, boolean append)`// 指定知否追加

FileUtils.writeStringToFile(src,"yyds!!!!","UTF-8",true);

}

}