一、緩衝字節流
1.緩衝字節輸出流
BufferedOutputStream(OutputStream);
示例代碼:
public class Demo01BufferedOutputStream {
public static void main(String[] args) throws IOException {
//2.創建BufferedOutputStream對象,構造方法中傳遞FileOutputStream對象,提高FileOutputStream對象效率
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("10_IO\\a.txt"));
//3.使用BufferedOutputStream對象中的方法write,把數據寫入到內部緩衝區中
bos.write("我把數據寫入到內部緩衝區中".getBytes());
//4.使用BufferedOutputStream對象中的方法flush,把內部緩衝區中的數據,刷新到文件中
bos.flush();
//5.釋放資源(會先調用flush方法刷新數據,第4部可以省略)
bos.close();
}
}
注意事項:
1.BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("F:\\Test\\out.txt")); ("...",true)
FileOutputStream fos = new FileOutputStream("f:\\Test\\4.txt"); ("...",true)
創建字節輸出流或者緩衝字節輸出流,不指定文件續寫那麼會創建一個新的文件直接覆蓋原文件,(也就是清空文件)
2.在使用字節流或者字符流讀取的時候,創建數組,將內容讀取到數組中的時候,最後在輸出或者寫入文件(文件的複製)
的時候要注意
fos.write(bytes,0,index);
sout(new String(bytes,0,index)) //將字符數組轉換爲字符串 1
sout(String.valueOf(bytes,0,,index)) //.... 2
2.緩衝字節輸入流
BufferedInputStream(InputStream);
示例代碼:
public class Demo02BufferedInputStream {
public static void main(String[] args) throws IOException {
//1.創建FileInputStream對象,構造方法中綁定要讀取的數據源
FileInputStream fis = new FileInputStream("10_IO\\a.txt");
//2.創建BufferedInputStream對象,構造方法中傳遞FileInputStream對象,提高FileInputStream對象的讀取效率
BufferedInputStream bis = new BufferedInputStream(fis);
//3.使用BufferedInputStream對象中的方法read,讀取文件
//int read()從輸入流中讀取數據的下一個字節。
/*int len = 0;//記錄每次讀取到的字節
while((len = bis.read())!=-1){
System.out.println(len);
}*/
//int read(byte[] b) 從輸入流中讀取一定數量的字節,並將其存儲在緩衝區數組 b 中。
byte[] bytes =new byte[1024];//存儲每次讀取的數據
int len = 0; //記錄每次讀取的有效字節個數
while((len = bis.read(bytes))!=-1){
System.out.println(new String(bytes,0,len));
}
//4.釋放資源
bis.close();
}
}
3.測試一下字節流複製文件的效率
通過測試,緩衝流配合小數組的形式速度最快
//第四種:緩衝字節流一次讀寫一個字節數組
private static void demo04() throws IOException{
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("c:\\視頻\\頸椎操.flv"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:\\dest\\頸椎操.flv"));
byte[] arr = new byte[1024];
int len;
while((len = bis.read(arr)) != -1) {
bos.write(arr,0,len);
}
bis.close();
bos.close();
}
二、緩衝字符流
1.緩衝字符輸出流
BufferedWriter(Writer);
特殊方法:
newLine(); 寫入一個和系統匹配的換行符
示例代碼:
public class Demo03BufferedWriter {
public static void main(String[] args) throws IOException {
//System.out.println();
//1.創建字符緩衝輸出流對象,構造方法中傳遞字符輸出流
BufferedWriter bw = new BufferedWriter(new FileWriter("10_IO\\c.txt"));
//2.調用字符緩衝輸出流中的方法write,把數據寫入到內存緩衝區中
for (int i = 0; i <10 ; i++) {
bw.write("傳智播客");
//bw.write("\r\n");
bw.newLine();
}
//3.調用字符緩衝輸出流中的方法flush,把內存緩衝區中的數據,刷新到文件中
bw.flush();
//4.釋放資源
bw.close();
}
}
2.緩衝字符輸入流
BufferedReader(Reader);
特殊方法:
String readLine(); 一次讀取一整行
示例代碼:
public class Demo04BufferedReader {
public static void main(String[] args) throws IOException {
//1.創建字符緩衝輸入流對象,構造方法中傳遞字符輸入流
BufferedReader br = new BufferedReader(new FileReader("10_IO\\c.txt"));
//2.使用字符緩衝輸入流對象中的方法read/readLine讀取文本
/*
發下以上讀取是一個重複的過程,所以可以使用循環優化
不知道文件中有多少行數據,所以使用while循環
while的結束條件,讀取到null結束
*/
String line;
while((line = br.readLine())!=null){
System.out.println(line);
}
//3.釋放資源
br.close();
}
}
3.緩衝字符流練習
/*
一、根據需求、完成代碼
1.項目根目錄下建立文件: user.txt,文件中存放用戶名和登錄密碼,格式:用戶名,密碼,如:aaa,123;
2. user.txt文件中初始存放的用戶信息有如下:
jack,123
rose,123
tom,123
3.要求完成如下功能:
程序運行時:控制檯提示用戶輸入註冊的用戶名和密碼;
驗證鍵盤錄入的用戶名跟user.txt中已註冊的用戶名是否重複:
是:控制檯提示:用戶名已存在
否:將鍵盤錄入的用戶名及密碼寫入user.txt文件,並在控制檯提示:註冊成功
*/
public class Day09_HomeWork01 {
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
System.out.println("請輸入用戶名:");
String username = sc.nextLine();
System.out.println("請輸入密碼:");
String password = sc.nextLine();
boolean flag = false;
BufferedReader br = new BufferedReader(new FileReader("my01-code\\user.txt"));
String line;
while((line = br.readLine()) != null) {
String[] arr = line.split(",");
if(arr[0].equals(username)) {
flag = true;
}
}
//對標識做判斷
if(flag) {
System.out.println("用戶名已存在");
}else {
//將鍵盤錄入的用戶名及密碼寫入user.txt文件,並在控制檯提示:註冊成功
BufferedWriter bw = new BufferedWriter(new FileWriter("my01-code\\user.txt",true));
bw.write(username + "," + password);
bw.newLine();
bw.close();
System.out.println("註冊成功");
}
br.close();
}
}
//方法二
public class work {
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new FileReader("user.txt"));
String line = null;
LinkedHashSet<String> hash = new LinkedHashSet<>();
while ((line = bf.readLine()) != null) {
String[] split = line.split(","); //通過正則表達式根據 , 規則切割
hash.add(split[0]); //切割後的split[0]是用戶名,存入set集合中
}
Scanner sc = new Scanner(System.in);
String inputStr = sc.next(); //用戶輸入的字符串
String spiltInputStr[]=inputStr.split(",");
if (hash.add(spiltInputStr[0]) == false) //根據HashSet集合不能存儲元素,當存入重複的元素時返回false,此種情況爲存入了重複元素
{
System.out.println("用戶名存在");
} else { //當集合裏面有沒此用戶名時,創建字符輸入流並且設爲續寫
BufferedWriter bw = new BufferedWriter(new FileWriter("user.txt",true));
bw.newLine(); //換行
bw.write(inputStr);
System.out.println("註冊成功");
bw.close();
}
bf.close();
}
}
1注意事項: 因爲字符流在讀寫文件的編碼格式不一致的時候就會出現亂碼問題,那麼我們就可以通過
轉換輸入流InputStreamReader和轉換輸出流OutputStreamReader去指定讀或者寫文件的編碼格式
三、轉換流
1.編碼表
ASCII碼錶:美國的碼錶,支持一些字母、數字等等
ISO-8859-1碼錶:支持歐洲各國家的碼錶
GB2312:早先的中文的碼錶
GBK碼錶:目前廣泛使用的碼錶
GB18030碼錶:最新的中文碼錶
Unicode碼錶:萬國碼,各個國家的碼錶都包含在內
2.轉換輸出流
OutputStreamWriter(OutputStream os,String chasetName) 字符流通向字節流的橋樑
使用轉換輸出流對象寫出指定格式的文件
public class Demo02OutputStreamWriter {
public static void main(String[] args) throws IOException {
//write_utf_8();
write_gbk();
}
/*
使用轉換流OutputStreamWriter寫GBK格式的文件
*/
private static void write_gbk() throws IOException {
//1.創建OutputStreamWriter對象,構造方法中傳遞字節輸出流和指定的編碼表名稱
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("10_IO\\gbk.txt"),"GBK");
//2.使用OutputStreamWriter對象中的方法write,把字符轉換爲字節存儲緩衝區中(編碼)
osw.write("你好");
//3.使用OutputStreamWriter對象中的方法flush,把內存緩衝區中的字節刷新到文件中(使用字節流寫字節的過程)
osw.flush();
//4.釋放資源
osw.close();
}
/*
使用轉換流OutputStreamWriter寫UTF-8格式的文件
*/
private static void write_utf_8() throws IOException {
//1.創建OutputStreamWriter對象,構造方法中傳遞字節輸出流和指定的編碼表名稱
//OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("10_IO\\utf_8.txt"),"utf-8");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("10_IO\\utf_8.txt"));//不指定默認使用UTF-8
//2.使用OutputStreamWriter對象中的方法write,把字符轉換爲字節存儲緩衝區中(編碼)
osw.write("你好");
//3.使用OutputStreamWriter對象中的方法flush,把內存緩衝區中的字節刷新到文件中(使用字節流寫字節的過程)
osw.flush();
//4.釋放資源
osw.close();
}
}
3.轉換輸入流
InputStreamReader(InputStream is,String chasetName); 字節流通向字符流的橋樑
使用轉換入流讀取指定編碼格式的文件
public class Demo03InputStreamReader {
public static void main(String[] args) throws IOException {
//read_utf_8();
read_gbk();
}
/*
使用InputStreamReader讀取GBK格式的文件
*/
private static void read_gbk() throws IOException {
//1.創建InputStreamReader對象,構造方法中傳遞字節輸入流和指定的編碼表名稱
//InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\gbk.txt"),"UTF-8");//???
InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\gbk.txt"),"GBK");//你好
//2.使用InputStreamReader對象中的方法read讀取文件
int len = 0;
while((len = isr.read())!=-1){
System.out.println((char)len);
}
//3.釋放資源
isr.close();
}
/*
使用InputStreamReader讀取UTF-8格式的文件
*/
private static void read_utf_8() throws IOException {
//1.創建InputStreamReader對象,構造方法中傳遞字節輸入流和指定的編碼表名稱
//InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\utf_8.txt"),"UTF-8");
InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\utf_8.txt"));//不指定默認使用UTF-8
//2.使用InputStreamReader對象中的方法read讀取文件
int len = 0;
while((len = isr.read())!=-1){
System.out.println((char)len);
}
//3.釋放資源
isr.close();
}
}
4.使用轉換流讀取gbk格式文件,並以utf-8格式寫出到另外一個文件中
public class Demo04Test {
public static void main(String[] args) throws IOException {
//1.創建InputStreamReader對象,構造方法中傳遞字節輸入流和指定的編碼表名稱GBK
InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\我是GBK格式的文本.txt"),"GBK");
//2.創建OutputStreamWriter對象,構造方法中傳遞字節輸出流和指定的編碼表名稱UTF-8
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("10_IO\\我是utf_8格式的文件.txt"),"UTF-8");
//3.使用InputStreamReader對象中的方法read讀取文件
int len = 0;
while((len = isr.read())!=-1){
//4.使用OutputStreamWriter對象中的方法write,把讀取的數據寫入到文件中
osw.write(len);
}
//5.釋放資源
osw.close();
isr.close();
}
}
四、序列化流
1.什麼是序列化和反序列化
序列化:將對象寫出
反序列化:將對象讀回來
2.序列化流,寫出對象的流
構造方法:
ObjectOutputStream(OutputStream);
成員方法:
writeObject(Object obj);
示例代碼:
//要求被寫出的對象必須實現 Serializable接口
public class Demo01ObjectOutputStream {
public static void main(String[] args) throws IOException {
//1.創建ObjectOutputStream對象,構造方法中傳遞字節輸出流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("10_IO\\person.txt"));
//2.使用ObjectOutputStream對象中的方法writeObject,把對象寫入到文件中
oos.writeObject(new Person("小美女",18));
//3.釋放資源
oos.close();
}
}
3.反序列化流,讀取對象的流
構造方法:
ObjectInputStream(InputStream in);
成員方法:
Object readObject();
示例代碼:
public class Demo02ObjectInputStream {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//1.創建ObjectInputStream對象,構造方法中傳遞字節輸入流
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("10_IO\\person.txt"));
//2.使用ObjectInputStream對象中的方法readObject讀取保存對象的文件
Object o = ois.readObject();
//3.釋放資源
ois.close();
//4.使用讀取出來的對象(打印)
System.out.println(o);
Person p = (Person)o;
System.out.println(p.getName()+p.getAge());
}
}
4.瞬態關鍵字:transient
作用:被該關鍵字修飾的變量,不參與序列化和反序列化
5.使用序列化流的常見的異常和解決方式
A: NotSerializableException
出現的原因:被序列化的類沒有實現 Serializable 接口
解決的方案:讓該類實現 Serializable 接口
B: InvalidClassException
出現的原因:序列化的id不匹配
解決的方案:生成一個固定的序列化id號即可
C: EOFException
出現的原因:讀取到序列化文件末尾的時候,因爲這裏面的讀取方法和字節流字符流裏面的不一樣,
不是返回null或者-1,而是拋出異常
解決的方案:將要寫出的多個對象,保存到一個容器中。將整個容器對象進行寫出。那麼在讀取的時候,
只需要讀一次即可
6.序列化練習-一次寫出和讀取多個對象
public class Demo03Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//1.定義一個存儲Person對象的ArrayList集合
ArrayList<Person> list = new ArrayList<>();
//2.往ArrayList集合中存儲Person對象
list.add(new Person("張三",18));
list.add(new Person("李四",19));
list.add(new Person("王五",20));
//3.創建一個序列化流ObjectOutputStream對象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("10_IO\\list.txt"));
//4.使用ObjectOutputStream對象中的方法writeObject,對集合進行序列化
oos.writeObject(list);
oos.close();
//5.創建一個反序列化ObjectInputStream對象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("10_IO\\list.txt"));
//6.使用ObjectInputStream對象中的方法readObject讀取文件中保存的集合
Object o = ois.readObject();
//7.把Object類型的集合轉換爲ArrayList類型
ArrayList<Person> list2 = (ArrayList<Person>)o;
//8.遍歷ArrayList集合
for (Person p : list2) {
System.out.println(p);
}
//9.釋放資源
ois.close();
}
}
五、打印流
1.PrintStream類
示例代碼:直接寫出數據到文件中
public class Demo01PrintStream {
public static void main(String[] args) throws FileNotFoundException {
//System.out.println("HelloWorld");
//創建打印流PrintStream對象,構造方法中綁定要輸出的目的地
PrintStream ps = new PrintStream("10_IO\\print.txt");
//如果使用繼承自父類的write方法寫數據,那麼查看數據的時候會查詢編碼表 97->a
ps.write(97);
//如果使用自己特有的方法print/println方法寫數據,寫的數據原樣輸出 97->97
ps.println(97);
ps.println(8.8);
ps.println('a');
ps.println("HelloWorld");
ps.println(true);
//釋放資源
ps.close();
}
}
示例代碼:改變輸出語句,將內容輸出到文件中
public class Demo02PrintStream {
public static void main(String[] args) throws FileNotFoundException {
System.out.println("我是在控制檯輸出");
PrintStream ps = new PrintStream("10_IO\\目的地是打印流.txt");
System.setOut(ps);//把輸出語句的目的地改變爲打印流的目的地
System.out.println("我在打印流的目的地中輸出");
ps.close();
}
}
IO流、緩衝字節流、緩衝字符流、轉換流、序列化和反序列化【總結】
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.