問題背景
如果我們要存數(shù)據(jù),我們可以存在數(shù)組里集合里,但是他們都有一個(gè)共性,那就是存在內(nèi)存當(dāng)中。優(yōu)點(diǎn)就是我們讀取的比較快。缺點(diǎn)就是當(dāng)我們重新啟動(dòng)項(xiàng)目的時(shí)候,這些數(shù)據(jù)就會(huì)消失。 為了對數(shù)據(jù)進(jìn)行持久化的保存,就可以把數(shù)據(jù)存在文件當(dāng)中,為了解決這個(gè),java為我們提供了IO流。
流(數(shù)據(jù)流動(dòng))
數(shù)據(jù)流動(dòng)的方向分為
- 讀數(shù)據(jù)(輸入Input)
- 寫數(shù)據(jù)(輸出Output)
什么叫文件
一種電腦的存儲形式
File是一個(gè)java.io包中的類
File是在內(nèi)存中的一個(gè)對象<---映射--->硬盤上的文件或文件夾
路徑是看創(chuàng)建的對象能否與硬盤中的一個(gè)真實(shí)的文件產(chǎn)生對應(yīng)映射關(guān)系,編譯不會(huì)報(bào)錯(cuò),只有當(dāng)通過文件流去讀取文件的內(nèi)容時(shí)才會(huì)報(bào)錯(cuò)。
系統(tǒng)內(nèi)硬盤上文件的名字是不區(qū)分大小寫的。
File類常用API
File file = new File("D:"+ File.separator + "testFile.txt");
System.out.println(file.canRead());
System.out.println(file.canWrite());
System.out.println(file.isDirectory());
System.out.println(file.isHidden());
System.out.println(file.isFile());
什么是文件流
顧名思義 讀取文件的信息(in) 將信息寫入文件中(out)
按照讀取或?qū)懭氲膯挝唬ㄗ止?jié)數(shù))大小來區(qū)分
字節(jié)型文件流(1字節(jié))
? FileInputStream/FileOutputStream
字符型文件流(2字節(jié)--1字符)
? FileReader/FileWriter
/*
測試FileInputStream
read():從管道一個(gè)字節(jié)一個(gè)字節(jié)的讀,返回值是Unicode碼,其中要注意的是\r\n的字節(jié)碼是13和10
read(byte[] b):每次從流管道中讀取若干個(gè)字節(jié),存入數(shù)組中,返回值為有效元素個(gè)數(shù)
available():返回值顯示流管道中緩存的字節(jié)數(shù)
skip(long n):跳過幾個(gè)字節(jié),再讀取(多線程讀文件可以利用)
*/
FileInputStream fileInputStream = null;
try {
File file = new File("D:" + File.separator + "testFile.txt");
fileInputStream = new FileInputStream(file);
int available = fileInputStream.available();//顯示流管道中有多少緩存字節(jié)
System.out.println(available);
byte[] b = new byte[5];
int read = fileInputStream.read(b);
while (read != -1) {
String string = new String(b, 0, read);
System.out.println(string);
read = fileInputStream.read(b);
}
/*int i = fileInputStream.read();//讀不到則返回值為-1
while (i != -1) {
System.out.println(i);
i = fileInputStream.read();
}*/
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fileInputStream != null) {
//將流通道關(guān)閉
fileInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
測試FileOutputStream
將String轉(zhuǎn)成byte,調(diào)用getBytes()方法
*/
FileOutputStream fos = null;
try {
fos = new FileOutputStream(new File("D:" + File.separator + "lili.txt"), true);
String str = "dgergdfgdfgdfg";
byte[] bytes = str.getBytes();
fos.write(bytes);
//fos.write(97);//將b寫入到管道中
fos.flush();//刷新,將管道中的字節(jié)推送到File中
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
/*
文件的復(fù)制
*/
public void copyFile(File file, String path) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(file);
fos = new FileOutputStream(new File(path + File.separator + file.getName()));
byte[] b = new byte[1024];
int read = fis.read(b);
while (read != -1) {
fos.write(b, 0, read);//將文件的有效字節(jié)寫入
fos.flush();
read = fis.read(b);
}
System.out.println("復(fù)制完成");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new OperationFile().copyFile(new File("D:" + File.separator + "lili.txt"), "G:");
}
/*
加強(qiáng)版
*/
public void copyPlusFile(File file, String newPath) {
//獲取當(dāng)前File的絕對路徑,用拼串的方式獲取新的路徑的名字
String oldFilePath = file.getAbsolutePath();
String newFilePath = newPath + oldFilePath.split(":")[1];
//創(chuàng)建一個(gè)新的文件夾
File newFile = new File(newFilePath);
File[] files = file.listFiles();
if (files != null) {//是一個(gè)文件夾
newFile.mkdir();
if (files.length != 0) {
for (File file1 : files) {
this.copyFile(file1, newPath);
}
}
} else {//是一個(gè)文件
//讀取舊的文件和寫入新的文件
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(oldFilePath);
fos = new FileOutputStream(newFilePath);
byte[] b = new byte[1024];
int count = fis.read(b);//讀取的有效字節(jié)
while (count != -1) {
fos.write(b, 0, count);
fos.flush();//將流管道元素清空出去
fis.read(b);
}
System.out.println(newFile.getName() + "文件復(fù)制完畢");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
字符型文件流
只能操作純文本文件(文件右鍵,記事本能打開)
//read(char[] c)
FileWriter fr = new FileReader(file);
String srt = "abc";
char[] c = srt.toCharArray();
FileWriter fw = new FileWriter(file);
fw.write(c);
fw.write(srt);
存儲信息的方式(為什么要操作File)
變量 只能存一份
數(shù)組 存儲好多個(gè) 數(shù)據(jù)類型統(tǒng)一
-
集合 存儲好多個(gè) 存儲后個(gè)數(shù)還能改變 泛型----數(shù)據(jù)類型統(tǒng)一
以上三個(gè)都是Java中的類型==(對象存儲在內(nèi)存中)==
都存儲在內(nèi)存中,程序執(zhí)行完畢,Java虛擬機(jī)停止的時(shí)候,內(nèi)存空間就被回收了。所以存儲的數(shù)據(jù)都是臨時(shí)性存儲的。
-
文件 ==存儲好多信息==
文件是存儲在硬盤上的----》永久性保存。數(shù)據(jù)雖然安全,但是文件畢竟不在內(nèi)存中,需要通過IO操作文件。
字符集
字母:數(shù)字 符號------1字節(jié) 8bit
需要將除了字母以外的其他語言進(jìn)行字符編碼--->拆分和組合
拆分和組合的規(guī)則--所謂的字符編碼
常見的字符編碼
- ASCII
- ISO-8859-1
- GB2312 GB18030 GBK BIG(繁體字)
- Unicode
- UTF-8
緩沖流
在管道內(nèi)增加緩沖的數(shù)據(jù)
讓我們使用流讀取的文字更加的流暢
BufferedInputStream/BufferOutputStream
BufferedReader/BufferedWriter
BufferedReader
//每次讀取一行
String value = readLine();
BufferedWriter
write(String)
//光標(biāo)移到下一行
newLine()
對象流
ObjectInputStream/ObjectOutputStream
對象序列化/反序列化
對象的序列化:將一個(gè)完整的對象拆分成字節(jié)碎片,記錄在文件中
對象的反序列化:將文件記錄的對象,反過來組合成一個(gè)完整的對象
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
/*oos = new ObjectOutputStream(new FileOutputStream(new File("D:"+ File.separator + "lili.txt"), true));
oos.writeObject(new Person("zhangsan", 80));
oos.flush();*/
ois = new ObjectInputStream(new FileInputStream("D:" + File.separator + "lili.txt"));
Person o = (Person) ois.readObject();
System.out.println(o.toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (oos != null) {
oos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (ois != null) {
ois.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}