IO流概述

- IO流介紹
- IO:輸入/輸出(Input/Output)
- 流:是一種抽象概念,是對(duì)數(shù)據(jù)傳輸?shù)目偡Q.也就是說數(shù)據(jù)在設(shè)備間的傳輸稱為流,流的本質(zhì)是數(shù)據(jù)傳輸
- IO流就是用來處理設(shè)備間數(shù)據(jù)傳輸問題的.常見的應(yīng)用: 文件復(fù)制; 文件上傳; 文件下載
- IO流的分類
- 按照數(shù)據(jù)的流向
- 輸入流:讀數(shù)據(jù)
- 輸出流:寫數(shù)據(jù)
- 按照數(shù)據(jù)類型來分
- 字節(jié)流
- 字節(jié)輸入流
- 字節(jié)輸出流
- 字符流
- 字符輸入流
- 字符輸出流
- 字節(jié)流
- 按照數(shù)據(jù)的流向
- IO流的使用場(chǎng)景
- 如果操作的是純文本文件,優(yōu)先使用字符流
- 如果操作的是圖片、視頻、音頻等二進(jìn)制文件,優(yōu)先使用字節(jié)流
- 如果不確定文件類型,優(yōu)先使用字節(jié)流.字節(jié)流是萬能的流
一.File類
1.File類介紹
- 它是文件和目錄路徑名的抽象表示
- 文件和目錄是可以通過File封裝成對(duì)象的
- 對(duì)于File而言,其封裝的并不是一個(gè)真正存在的文件,僅僅是一個(gè)路徑名而已.它可以是存在的,也可以是不存在的.將來是要通過具體的操作把這個(gè)路徑的內(nèi)容轉(zhuǎn)換為具體存在的
2.File類的構(gòu)造方法
| 方法名 | 說明 |
|---|---|
| File(String pathname) | 通過將給定的路徑名字符串轉(zhuǎn)換為抽象路徑名來創(chuàng)建新的 File實(shí)例 |
| File(String parent, String child) | 從父路徑名字符串和子路徑名字符串創(chuàng)建新的 File實(shí)例 |
| File(File parent, String child) | 從父抽象路徑名和子路徑名字符串創(chuàng)建新的 File實(shí)例 |
//File(String pathname): 通過將給定的路徑名字符串轉(zhuǎn)換為抽象路徑名來創(chuàng)建新的 File實(shí)例
File f1 = new File("/Users/Downloads/File");
System.out.println(f1);
//File(String parent, String child): 從父路徑名字符串和子路徑名字符串創(chuàng)建新的 File實(shí)例
File f2 = new File("/Users/Downloads/File","java.txt");
System.out.println(f2);
//File(File parent, String child): 從父抽象路徑名和子路徑名字符串創(chuàng)建新的 File實(shí)例
File f3 = new File("/Users/Downloads/File");
File f4 = new File(f3,"java.txt");
System.out.println(f4);
3.File類創(chuàng)建和刪除
-
方法分類
方法名 說明 public boolean createNewFile() 當(dāng)具有該名稱的文件不存在時(shí),創(chuàng)建一個(gè)由該抽象路徑名命名的新空文件 public boolean mkdir() 創(chuàng)建由此抽象路徑名命名的目錄 public boolean mkdirs() 創(chuàng)建由此抽象路徑名命名的目錄,包括任何必需但不存在的父目錄 public boolean delete() 刪除由此抽象路徑名表示的文件或目錄
//1.創(chuàng)建文件
File f1 = new File("/Users/Downloads/File/java.txt");
System.out.println(f1.createNewFile());
System.out.println("--------");
//2.創(chuàng)建一個(gè)目錄JavaSE
File f2 = new File("/Users/Downloads/File/JavaSE");
System.out.println(f2.mkdir());
System.out.println("--------");
//3.創(chuàng)建一個(gè)多級(jí)目錄JavaWEB\\HTML
File f3 = new File("/Users/Downloads/File/HTML/1");
System.out.println(f3.mkdirs());
System.out.println("--------");
//4:刪除目錄下的文件或文件夾
File f4 = new File("/Users/Downloads/File/JavaSE");
System.out.println(f2.delete());
4.File類判斷和獲取
-
判斷功能
方法名 說明 public boolean isDirectory() 測(cè)試此抽象路徑名表示的File是否為目錄 public boolean isFile() 測(cè)試此抽象路徑名表示的File是否為文件 public boolean exists() 測(cè)試此抽象路徑名表示的File是否存在 -
獲取功能
方法名 說明 public String getAbsolutePath() 返回此抽象路徑名的絕對(duì)路徑名字符串 public String getPath() 將此抽象路徑名轉(zhuǎn)換為路徑名字符串 public String getName() 返回由此抽象路徑名表示的文件或目錄的名稱 public File[] listFiles() 返回此抽象路徑名表示的目錄中的文件和目錄的File對(duì)象數(shù)組
//創(chuàng)建一個(gè)File對(duì)象
File f = new File("filepro");
// public boolean isDirectory():測(cè)試此抽象路徑名表示的File是否為目錄
// public boolean isFile():測(cè)試此抽象路徑名表示的File是否為文件
// public boolean exists():測(cè)試此抽象路徑名表示的File是否存在
System.out.println(f.isDirectory());
System.out.println(f.isFile());
System.out.println(f.exists());
//public String getAbsolutePath():返回此抽象路徑名的絕對(duì)路徑名字符串
//public String getPath():將此抽象路徑名轉(zhuǎn)換為路徑名字符串
//public String getName():返回由此抽象路徑名表示的文件或目錄的名稱
System.out.println(f.getAbsolutePath());
System.out.println(f.getPath());
System.out.println(f.getName());
System.out.println("--------");
// public File[] listFiles():返回此抽象路徑名表示的目錄中的文件和目錄的File對(duì)象數(shù)組
File f2 = new File("filepro");
File[] fileArray = f2.listFiles();
for(File file : fileArray) {
System.out.println(file);
}
5.實(shí)例
刪除一個(gè)多級(jí)文件夾
public static void main(String[] args) {
//delete方法,只能刪除文件和空文件夾.
//如果現(xiàn)在要?jiǎng)h除一個(gè)有內(nèi)容的文件夾?
//先刪掉這個(gè)文件夾里面所有的內(nèi)容.最后再刪除這個(gè)文件夾
File src = new File("filepro");
deleteDir(src);
}
//1.定義一個(gè)方法,接收一個(gè)File對(duì)象
private static void deleteDir(File src) {
//先刪掉這個(gè)文件夾里面所有的內(nèi)容.
//遞歸 方法在方法體中自己調(diào)用自己.
//注意: 可以解決所有文件夾和遞歸相結(jié)合的題目
//2.遍歷這個(gè)File對(duì)象,獲取它下邊的每個(gè)文件和文件夾對(duì)象
File[] files = src.listFiles();
//3.判斷當(dāng)前遍歷到的File對(duì)象是文件還是文件夾
for (File file : files) {
//4.如果是文件,直接刪除
if(file.isFile()){
file.delete();
}else{
//5.如果是文件夾,遞歸調(diào)用自己,將當(dāng)前遍歷到的File對(duì)象當(dāng)做參數(shù)傳遞
deleteDir(file);//參數(shù)一定要是src文件夾里面的文件夾File對(duì)象
}
}
//6.參數(shù)傳遞過來的文件夾File對(duì)象已經(jīng)處理完成,最后直接刪除這個(gè)空文件夾
src.delete();
}
統(tǒng)計(jì)一個(gè)文件夾中每種文件的個(gè)數(shù)并打印
public static void main(String[] args) {
//統(tǒng)計(jì)一個(gè)文件夾中,每種文件出現(xiàn)的次數(shù).
//統(tǒng)計(jì) --- 定義一個(gè)變量用來統(tǒng)計(jì). ---- 弊端:同時(shí)只能統(tǒng)計(jì)一種文件
//利用map集合進(jìn)行數(shù)據(jù)統(tǒng)計(jì),鍵 --- 文件后綴名 值 ---- 次數(shù)
File file = new File("/File項(xiàng)目");
HashMap<String, Integer> hm = new HashMap<>();
getCount(hm, file);
System.out.println(hm);
}
//1.定義一個(gè)方法,參數(shù)是HashMap集合用來統(tǒng)計(jì)次數(shù)和File對(duì)象要統(tǒng)計(jì)的文件夾
private static void getCount(HashMap<String, Integer> hm, File file) {
//2.遍歷File對(duì)象,獲取它下邊的每一個(gè)文件和文件夾對(duì)象
File[] files = file.listFiles();
for (File f : files) {
//3.判斷當(dāng)前File對(duì)象是文件還是文件夾
if(f.isFile()){
//如果是文件,判斷這種類型文件后綴名在HashMap集合中是否出現(xiàn)過
String fileName = f.getName();
String[] fileNameArr = fileName.split("\\.");
if(fileNameArr.length == 2){
String fileEndName = fileNameArr[1];
if(hm.containsKey(fileEndName)){
//出現(xiàn)過,獲取這種類型文件的后綴名出現(xiàn)的次數(shù),對(duì)其+1,在存回集合中
Integer count = hm.get(fileEndName);
//這種文件又出現(xiàn)了一次.
count++;
//把已經(jīng)出現(xiàn)的次數(shù)給覆蓋掉.
hm.put(fileEndName,count);
}else{
// 沒出現(xiàn)過,將這種類型文件的后綴名存入集合中,次數(shù)存1
hm.put(fileEndName,1);
}
}
}else{
//如果是文件夾,遞歸調(diào)用自己,HashMap集合就是參數(shù)集合,File對(duì)象是當(dāng)前文件夾對(duì)象代碼實(shí)現(xiàn)
getCount(hm,f);
}
}
}
二.字節(jié)流
-
字節(jié)流抽象基類
- InputStream:這個(gè)抽象類是表示字節(jié)輸入流的所有類的超類
- OutputStream:這個(gè)抽象類是表示字節(jié)輸出流的所有類的超類
- 子類名特點(diǎn):子類名稱都是以其父類名作為子類名的后綴
1.字節(jié)輸出流
FileOutputStream(String name):創(chuàng)建文件輸出流以指定的名稱寫入文件
-
使用字節(jié)輸出流寫數(shù)據(jù)的步驟
- 1.創(chuàng)建字節(jié)輸出流對(duì)象(調(diào)用系統(tǒng)功能創(chuàng)建了文件,創(chuàng)建字節(jié)輸出流對(duì)象,讓字節(jié)輸出流對(duì)象指向文件)
- 調(diào)用字節(jié)輸出流對(duì)象的寫數(shù)據(jù)方法
- 釋放資源(關(guān)閉此文件輸出流并釋放與此流相關(guān)聯(lián)的任何系統(tǒng)資源)
-
字節(jié)流寫數(shù)據(jù)如何實(shí)現(xiàn)換行
- windows:\r\n
- linux:\n
- mac:\r
-
字節(jié)流寫數(shù)據(jù)如何實(shí)現(xiàn)追加寫入
- public FileOutputStream(String name,boolean append)
- 創(chuàng)建文件輸出流以指定的名稱寫入文件。如果第二個(gè)參數(shù)為true ,則字節(jié)將寫入文件的末尾而不是開頭
-
寫數(shù)據(jù)的方法分類
方法名 說明 void write(int b) 將指定的字節(jié)寫入此文件輸出流 一次寫一個(gè)字節(jié)數(shù)據(jù) void write(byte[] b) 將 b.length字節(jié)從指定的字節(jié)數(shù)組寫入此文件輸出流 一次寫一個(gè)字節(jié)數(shù)組數(shù)據(jù) void write(byte[] b, int off, int len) 將 len字節(jié)從指定的字節(jié)數(shù)組開始,從偏移量off開始寫入此文件輸出流 一次寫一個(gè)字節(jié)數(shù)組的部分?jǐn)?shù)據(jù)
static void test() throws IOException {
//1.創(chuàng)建字節(jié)輸出流的對(duì)象
// 注意點(diǎn):如果文件不存在,會(huì)幫我們自動(dòng)創(chuàng)建出來.
// 如果文件存在,會(huì)把文件清空.
FileOutputStream fos = new FileOutputStream("a.txt");
//2,寫數(shù)據(jù)
// 傳遞一個(gè)整數(shù)時(shí),那么實(shí)際上寫到文件中的,是這個(gè)整數(shù)在碼表中對(duì)應(yīng)的那個(gè)字符.
fos.write(98);
//添加換行符一個(gè)換行
fos.write("\r\n".getBytes());
// 添加中文,需要進(jìn)行轉(zhuǎn)碼
fos.write("哈哈".getBytes());
// 添加數(shù)組
byte [] bys = {97,98,99,100,101,102,103};
fos.write(bys,0,4);
//3,釋放資源
fos.close(); //告訴操作系統(tǒng),我現(xiàn)在已經(jīng)不要再用這個(gè)文件了.
}
-
字節(jié)流寫數(shù)據(jù)加異常處理
try-catch-finally
static void test1(){
FileOutputStream fos = null;
try {
//System.out.println(2/0);
fos = new FileOutputStream("a.txt");
fos.write(97);
}catch(IOException e){
e.printStackTrace();
}finally {
//finally語句里面的代碼,一定會(huì)被執(zhí)行.
if(fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.字節(jié)輸入流
-
字節(jié)輸入流
- FileInputStream(String name):通過打開與實(shí)際文件的連接來創(chuàng)建一個(gè)FileInputStream,該文件由文件系統(tǒng)中的路徑名name命名
-
字節(jié)輸入流讀取數(shù)據(jù)的步驟
- 1.創(chuàng)建字節(jié)輸入流對(duì)象
- 2.調(diào)用字節(jié)輸入流對(duì)象的讀數(shù)據(jù)方法
- 3.釋放資源
static void test2() throws IOException {
//如果文件存在,那么就不會(huì)報(bào)錯(cuò).
//如果文件不存在,那么就直接報(bào)錯(cuò).
FileInputStream fis = new FileInputStream("a.txt");
//一次讀取一個(gè)字節(jié),返回值就是本次讀到的那個(gè)字節(jié)數(shù)據(jù).
//也就是字符在碼表中對(duì)應(yīng)的那個(gè)數(shù)字.
//如果我們想要看到的是字符數(shù)據(jù),那么一定要強(qiáng)轉(zhuǎn)成char
int read = fis.read();
System.out.println((char)read);
//讀多個(gè)字節(jié),每調(diào)用一次就讀取一個(gè)字節(jié)
int b;
while ((b = fis.read())!=-1){
System.out.println((char) b);
}
//釋放資源
fis.close();
}
3.字節(jié)讀寫數(shù)據(jù)
- 單個(gè)字節(jié)讀寫
static void test3() throws IOException {
//1 創(chuàng)建了字節(jié)輸入流,準(zhǔn)備讀數(shù)據(jù).
FileInputStream fis = new FileInputStream("a.avi");
//創(chuàng)建了字節(jié)輸出流,準(zhǔn)備寫數(shù)據(jù).
FileOutputStream fos = new FileOutputStream("b.avi");
//一次讀寫一個(gè)字節(jié)
int b;
while((b = fis.read())!=-1){
fos.write(b);
}
// 3.釋放資源
fis.close();
fos.close();
}
- 字節(jié)數(shù)組讀寫
static void test4() throws IOException {
FileInputStream fis = new FileInputStream("a.avi");
FileOutputStream fos = new FileOutputStream("c.avi");
// //一次讀寫一個(gè)字節(jié)數(shù)組
byte [] bytes = new byte[1024];
int len; //本次讀到的有效字節(jié)個(gè)數(shù) -- 這次讀了幾個(gè)字節(jié).
while((len = fis.read(bytes))!=-1){
fos.write(bytes,0,len);
}
fis.close();
fos.close();
}
4.字節(jié)緩沖流讀寫
-
字節(jié)緩沖流介紹
- BufferOutputStream:該類實(shí)現(xiàn)緩沖輸出流.通過設(shè)置這樣的輸出流,應(yīng)用程序可以向底層輸出流寫入字節(jié),而不必為寫入的每個(gè)字節(jié)導(dǎo)致底層系統(tǒng)的調(diào)用
- BufferedInputStream:創(chuàng)建BufferedInputStream將創(chuàng)建一個(gè)內(nèi)部緩沖區(qū)數(shù)組.當(dāng)從流中讀取或跳過字節(jié)時(shí),內(nèi)部緩沖區(qū)將根據(jù)需要從所包含的輸入流中重新填充,一次很多字節(jié)
-
構(gòu)造方法:
方法名 說明 BufferedOutputStream(OutputStream out) 創(chuàng)建字節(jié)緩沖輸出流對(duì)象 BufferedInputStream(InputStream in) 創(chuàng)建字節(jié)緩沖輸入流對(duì)象 字節(jié)緩沖流讀寫一個(gè)字節(jié)
public static void method6() throws IOException {
//字節(jié)緩沖流一次讀寫一個(gè)字節(jié)
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.avi"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("b.avi"));
int by;
while ((by=bis.read())!=-1) {
bos.write(by);
}
bos.close();
bis.close();
}
- 字節(jié)緩沖流數(shù)組讀寫
static void test5() throws IOException{
//字節(jié)緩沖流一次讀寫一個(gè)字節(jié)數(shù)組
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.avi"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("b.avi"));
byte[] bys = new byte[1024];
int len;
while ((len=bis.read(bys))!=-1) {
bos.write(bys,0,len);
}
bos.close();
bis.close();
}
三.字符流
1為什么會(huì)出現(xiàn)字符流
-
字符流的介紹
由于字節(jié)流操作中文不是特別的方便,所以Java就提供字符流
字符流 = 字節(jié)流 + 編碼表
-
中文的字節(jié)存儲(chǔ)方式
用字節(jié)流復(fù)制文本文件時(shí),文本文件也會(huì)有中文,但是沒有問題,原因是最終底層操作會(huì)自動(dòng)進(jìn)行字節(jié)拼接成中文,如何識(shí)別是中文的呢?
漢字在存儲(chǔ)的時(shí)候,無論選擇哪種編碼存儲(chǔ),第一個(gè)字節(jié)都是負(fù)數(shù)
2.編碼表
-
什么是字符集
是一個(gè)系統(tǒng)支持的所有字符的集合,包括各國家文字、標(biāo)點(diǎn)符號(hào)、圖形符號(hào)、數(shù)字等
l計(jì)算機(jī)要準(zhǔn)確的存儲(chǔ)和識(shí)別各種字符集符號(hào),就需要進(jìn)行字符編碼,一套字符集必然至少有一套字符編碼。常見字符集有ASCII字符集、GBXXX字符集、Unicode字符集等
-
常見的字符集
-
ASCII字符集:
lASCII:是基于拉丁字母的一套電腦編碼系統(tǒng),用于顯示現(xiàn)代英語,主要包括控制字符(回車鍵、退格、換行鍵等)和可顯示字符(英文大小寫字符、阿拉伯?dāng)?shù)字和西文符號(hào))
基本的ASCII字符集,使用7位表示一個(gè)字符,共128字符。ASCII的擴(kuò)展字符集使用8位表示一個(gè)字符,共256字符,方便支持歐洲常用字符。是一個(gè)系統(tǒng)支持的所有字符的集合,包括各國家文字、標(biāo)點(diǎn)符號(hào)、圖形符號(hào)、數(shù)字等
-
GBXXX字符集:
GBK:最常用的中文碼表。是在GB2312標(biāo)準(zhǔn)基礎(chǔ)上的擴(kuò)展規(guī)范,使用了雙字節(jié)編碼方案,共收錄了21003個(gè)漢字,完全兼容GB2312標(biāo)準(zhǔn),同時(shí)支持繁體漢字以及日韓漢字等
-
Unicode字符集:
UTF-8編碼:可以用來表示Unicode標(biāo)準(zhǔn)中任意字符,它是電子郵件、網(wǎng)頁及其他存儲(chǔ)或傳送文字的應(yīng)用 中,優(yōu)先采用的編碼。互聯(lián)網(wǎng)工程工作小組(IETF)要求所有互聯(lián)網(wǎng)協(xié)議都必須支持UTF-8編碼。它使用一至四個(gè)字節(jié)為每個(gè)字符編碼
編碼規(guī)則:
128個(gè)US-ASCII字符,只需一個(gè)字節(jié)編碼
拉丁文等字符,需要二個(gè)字節(jié)編碼
大部分常用字(含中文),使用三個(gè)字節(jié)編碼
其他極少使用的Unicode輔助字符,使用四字節(jié)編碼
-
3.字符串中的編碼解碼
| 方法名 | 說明 |
|---|---|
| byte[] getBytes() | 使用平臺(tái)的默認(rèn)字符集將該 String編碼為一系列字節(jié) |
| byte[] getBytes(String charsetName) | 使用指定的字符集將該 String編碼為一系列字節(jié) |
| String(byte[] bytes) | 使用平臺(tái)的默認(rèn)字符集解碼指定的字節(jié)數(shù)組來創(chuàng)建字符串 |
| String(byte[] bytes, String charsetName) | 通過指定的字符集解碼指定的字節(jié)數(shù)組來創(chuàng)建字符串 |
- 中文解碼編碼
static void method1() throws UnsupportedEncodingException {
String str = "中文編碼";
//利用idea默認(rèn)的UTF-8將中文編碼為一系列的字節(jié)
byte[] bytes1 = str.getBytes();
System.out.println(Arrays.toString(bytes1));
//利用默認(rèn)的UTF-8進(jìn)行解碼
String s1 = new String(bytes1);
System.out.println(s1);
// 指定編碼類型:GBK
byte[] bytes2 = str.getBytes("GBK");
System.out.println(Arrays.toString(bytes2));
//利用指定的GBK進(jìn)行解碼
String s2 = new String(bytes2,"GBK");
System.out.println(s2);
}
- 控制臺(tái)打印
[-28, -72, -83, -26, -106, -121, -25, -68, -106, -25, -96, -127]
中文編碼
[-42, -48, -50, -60, -79, -32, -62, -21]
中文編碼
4.字符流寫數(shù)據(jù)
Writer: 用于寫入字符流的抽象父類FileWriter: 用于寫入字符流的常用子類-
構(gòu)造方法
方法名 說明 FileWriter(File file) 根據(jù)給定的 File 對(duì)象構(gòu)造一個(gè) FileWriter 對(duì)象 FileWriter(File file, boolean append) 根據(jù)給定的 File 對(duì)象構(gòu)造一個(gè) FileWriter 對(duì)象 FileWriter(String fileName) 根據(jù)給定的文件名構(gòu)造一個(gè) FileWriter 對(duì)象 FileWriter(String fileName, boolean append) 根據(jù)給定的文件名以及指示是否附加寫入數(shù)據(jù)的 boolean 值來構(gòu)造 FileWriter 對(duì)象 -
成員方法
方法名 說明 void write(int c) 寫一個(gè)字符 void write(char[] cbuf) 寫入一個(gè)字符數(shù)組 void write(char[] cbuf, int off, int len) 寫入字符數(shù)組的一部分 void write(String str) 寫一個(gè)字符串 void write(String str, int off, int len) 寫一個(gè)字符串的一部分 -
刷新和關(guān)閉的方法
方法名 說明 flush() 刷新流,之后還可以繼續(xù)寫數(shù)據(jù) close() 關(guān)閉流,釋放資源,但是在關(guān)閉之前會(huì)先刷新流。一旦關(guān)閉,就不能再寫數(shù)據(jù)
static void test1() throws IOException {
//創(chuàng)建字符輸出流的對(duì)象
FileWriter fw = new FileWriter("a.txt");
// 寫一個(gè)字符
fw.write(97);
fw.write("\n\r");
// 寫出一個(gè)字符數(shù)組
char [] chars = {97,98,99,100,101};
fw.write(chars);
// 寫出字符數(shù)組的一部分
fw.write(chars,0,3);
// 寫一個(gè)字符串
String line = "輸出流的對(duì)象123-abc";
fw.write(line);
fw.write(line,0,2);
//釋放資源
fw.close();
}
5.字符流讀數(shù)據(jù)
-
Reader: 用于讀取字符流的抽象父類 -
FileReader: 用于讀取字符流的常用子類
-
構(gòu)造方法
方法名 說明 FileReader(File file) 在給定從中讀取數(shù)據(jù)的 File 的情況下創(chuàng)建一個(gè)新 FileReader FileReader(String fileName) 在給定從中讀取數(shù)據(jù)的文件名的情況下創(chuàng)建一個(gè)新 FileReader
-
成員方法
方法名 說明 int read() 一次讀一個(gè)字符數(shù)據(jù) int read(char[] cbuf) 一次讀一個(gè)字符數(shù)組數(shù)據(jù) 一次讀取一個(gè)字符
static void test2() throws IOException {
//創(chuàng)建字符輸入流的對(duì)象
FileReader fr = new FileReader("a.txt");
//一次讀取一個(gè)字符
int ch;
while((ch = fr.read()) != -1){
System.out.println((char) ch);
}
//釋放資源
fr.close();
}
- 一次讀取多個(gè)字符
static void test3() throws IOException {
FileReader fr = new FileReader("a.txt");
char [] chars = new char[1024];
int len;
//read方法還是讀取,但是一次讀取多個(gè)字符
//他把讀到的字符都存入到chars數(shù)組。
//返回值:表示本次讀到了多少個(gè)字符。
while((len = fr.read(chars))!=-1){
System.out.println(new String(chars,0,len));
}
fr.close();
}
6.緩沖字符流
BufferedWriter:將文本寫入字符輸出流,緩沖字符,以提供單個(gè)字符,數(shù)組和字符串的高效寫入,可以指定緩沖區(qū)大小,或者可以接受默認(rèn)大小。默認(rèn)值足夠大,可用于大多數(shù)用途BufferedReader:從字符輸入流讀取文本,緩沖字符,以提供字符,數(shù)組和行的高效讀取,可以指定緩沖區(qū)大小,或者可以使用默認(rèn)大小。 默認(rèn)值足夠大,可用于大多數(shù)用途構(gòu)造方法
| 方法名 | 說明 |
|---|---|
| BufferedWriter(Writer out) | 創(chuàng)建字符緩沖輸出流對(duì)象 |
| BufferedReader(Reader in) | 創(chuàng)建字符緩沖輸入流對(duì)象 |
| void newLine() | 寫一行行分隔符,行分隔符字符串由系統(tǒng)屬性定義 |
| String readLine() | 讀一行文字。 如果已經(jīng)到達(dá)結(jié)尾,則為null |
static void test4() throws IOException {
//字符緩沖輸入
BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));
//寫出數(shù)據(jù)
bw.write("字符緩沖");
//跨平臺(tái)的回車換行
bw.newLine();
//釋放資源
bw.close();
//字符緩沖輸出
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
//使用循環(huán)來進(jìn)行改進(jìn)
String line;
//可以讀取一整行數(shù)據(jù)。一直讀,讀到回車換行為止。
//但是他不會(huì)讀取回車換行符。
while((line = br.readLine()) != null){
System.out.println(line);
}
//釋放資源
br.close();
}
四.轉(zhuǎn)換流
1.概述
InputStreamReader:是從字節(jié)流到字符流的橋梁,父類是Reader
1.它讀取字節(jié),并使用指定的編碼將其解碼為字符
2.它使用的字符集可以由名稱指定,也可以被明確指定,或者可以接受平臺(tái)的默認(rèn)字符集OutputStreamWriter:是從字符流到字節(jié)流的橋梁,父類是Writer
1.是從字符流到字節(jié)流的橋梁,使用指定的編碼將寫入的字符編碼為字節(jié)
2.它使用的字符集可以由名稱指定,也可以被明確指定,或者可以接受平臺(tái)的默認(rèn)字符集
2. 構(gòu)造方法
| 方法名 | 說明 |
|---|---|
| InputStreamReader(InputStream in) | 使用默認(rèn)字符編碼創(chuàng)建InputStreamReader對(duì)象 |
| InputStreamReader(InputStream in,String chatset) | 使用指定的字符編碼創(chuàng)建InputStreamReader對(duì)象 |
| OutputStreamWriter(OutputStream out) | 使用默認(rèn)字符編碼創(chuàng)建OutputStreamWriter對(duì)象 |
| OutputStreamWriter(OutputStream out,String charset) | 使用指定的字符編碼創(chuàng)建OutputStreamWriter對(duì)象 |
static void test1() throws IOException {
//從字符流到字節(jié)流
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"),"GBK");
osw.write("中國");
osw.close();
//從字符流到字節(jié)流的橋梁
InputStreamReader isr = new InputStreamReader(new FileInputStream("osw.txt"),"GBK");
//一次讀取一個(gè)字符數(shù)據(jù)
int ch;
while ((ch=isr.read())!=-1) {
System.out.print((char)ch);
}
isr.close();
}