一、IO流的基礎知識:
1、IO流的作用:是用來處理設備之間的數據傳輸。
Java對數據的操作是通過流的方式完成,而用於操作流的對象存在於Java的IO包中。
2、IO流的分類:
①、按操作的數據不同:字節流和字符流。
②、按流的方向不同:輸入流和輸出流。
注意:早期IO包裏面只有字節流,因爲計算機中(內存中或者硬盤中)的數據的體現形式都是字節,都是二進制數據。
3、字符流的由來:
由於文本數據比較常見,使用也比較頻繁,爲了方便處理文本數據,就從字節流中單獨分離出了字符流。
字符流基於字節流。
4、IO流常用基類:
①、字節流的抽象基類:
InputStream(輸入流--->讀取)、OutputStream(輸出流--->寫入)
②、字符流的抽象基類:
Reader(輸入流--->讀取)、Writer(輸出流--->寫入)
注意:由IO流的4個常用基類派生出來的子類名稱都是以其父類名稱做爲子類名的後綴。
例如:InputStream的子類:FileInputStream
Reader的子類:FileReader
5、IO流繼承體系圖
字符流繼承體系圖:
字節流繼承體系圖:
二、字符流(Writer & Reader)
1、字符輸出流(寫入)——Writer類
①、Writer類的定義:
public abstract class Writer
extends Object
implements Appendable,Closeable,Flushable
是一個抽象類,如果要使用Writer類則必須要使用其子類。
②、Writer類中的常用方法介紹:
abstract void flush():刷新流對象中的緩衝中的數據。將數據刷到目的地中。
abstract void close():關閉流。但是關閉之前會刷新一次內部的緩衝中的數據。
void write(String str):將字符串寫入到流中。
2、FileWriter類
①、概述:是Writer類的間接子類,用於文本輸出流的操作。
②、FileWriter類常用構造方法:
FileWriter(String fileName):在創建對象時就明確被操作的文件。如果文件不存在,就會在指定目錄下創建一個。如果指定目錄下已經存在一個同名文件,則該文件會被覆蓋。
代碼示例:
import java.io.*;
class FileWriterDemo
{
public static void main(String[] args) throws IOException
{
/*
創建一個FileWriter對象。該對象一被初始化就必須要明確被操作的文件。而且該文件會被創建到指定目錄下。如果該目錄下已有同名文件,將被覆蓋。其實就步驟就是在明確數據要存放的目的地。
*/
FileWriter fw = new FileWriter("demo.txt");
//調用write方法將字符串寫入到流中。
fw.write("abcde");
//刷新流對象中的緩衝中的數據。
//將數據刷到目的地中。
//fw.flush();
//關閉流資源,但是關閉之前會刷新一次內部的緩衝中的數據。
//將數據刷到目的地中。
//和flush的區別:flush刷新後,流可以繼續使用。close刷新後,會將流關閉。
fw.close();
fw.write("haha"); //會出現IOException異常,因爲流已經被關閉了,無法再寫入內容。
}
}
FileWriter(String fileName, boolean append):可以通過添加一個boolean類型的參數來對已有的文件進行續寫操作。
代碼示例:
import java.io.*;
class FileWriterDemo3
{
public static void main(String[] args) throws IOException
{
//傳遞一個true參數,代表不覆蓋已有的文件。並在已有文件的末尾處進行數據續寫。
FileWriter fw = new FileWriter("demo.txt",true);
fw.write("hellojava");
fw.close();
}
}
注意:Windows中換行是用兩個轉移字符進行表示的:\r\n。而Linux中的換行用的是一個字符\n。
3、IO異常處理方式
import java.io.*;
class FileWriterDemo2
{
public static void main(String[] args)
{
FileWriter fw = null; //因爲要操作的文件可能存在路徑不存在的緣故,所以可能在對象創建之前就發生了異常,所以要在異常處理語句外部創建流對象的引用。
try
{
fw = new FileWriter("demo.txt");
fw.write("abcdefg");
}
catch(IOException e)
{
System.out.println(e.toString());
}
finally
{
try
{
if(fw != null) //必須要對不爲null的流進行判斷,防止出現空指針異常。
fw.close(); //爲了節省資源,所以關閉流的動作一定要被執行,就放到異常處理語句的finally部分來執行。
}
catch(IOException e)
{
System.out.println(e.toString());
}
}
}
}
4、字符輸入流(讀取)——Reader類
①、Reader類聲明:也是一個抽象類,需要使用其子類實例化該類對象。
public abstract class Reader
extends Object
implements Readable, Closeable
②、Reader類中常用方法介紹:
int read():讀取單個字符。一次只讀一個字符,而且會自動往下讀。當沒有可讀內容的時候就返回-1。
int read(char[] cbuf):讀取一個字符數組。返回值是讀取到的字符個數。數組長度確定,一般長度定義爲1024的倍數。
abstract int read(char[] cbuf,int off,int len):讀取字符數組,並指定讀取的範圍。
abstract void close():關閉讀取流。
5、FileReader類
①、概述:是Reader的間接子類。用於文本讀取流的操作。
②、FileReader類常用構造方法:
FileReader(String fileName):在創建文件讀取流對象時就關聯一個指定名稱的文件。如果該文件不存在,則會發生FileNotFoundException異常。
文本文件讀取示例:第一種方式
import java.io.*;
class FileReaderDemo
{
public static void main(String[] args) throws IOException
{
//創建一個文件讀取流對象,和指定名稱的文件相關聯。
//要保證該文件是已經存在的,如果不存在,會發生異常:FileNotFoundException
FileReader fr = new FileReader("demo.txt");
//調用讀取流對象的方法。
//read():一次讀一個字符,而且會自動往下讀。
int ch = 0;
while((ch = fr.read()) != -1)
{
System.out.println((char)ch);
}
fr.close();
}
}
文本文件讀取示例:第二種方式
import java.io.*;
class FileReaderDemo2
{
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("demo.txt");
//定義一個字符數組,用於存儲讀到的字符。
//該read(char[])方法返回的是讀到的字符個數。
char[] buf = new char[1024]; //字符數組的長度一般定義成1024的倍數。
int num = 0; //定義表示讀取到的字符個數的變量。
while((num = fr.read(buf)) != -1)
{
System.out.println(new String(buf,0,num));
}
fr.close();
}
}
6、文件複製綜合案例:
①、文件複製原理:其實就是將一個文件數據複製到另一個文件中存儲。
②、實現步驟:
1) 先通過字符輸出流創建一個目的文件,用於存放從源文件中拷貝過來的數據。
2) 定義一個字符讀取流和源文件相關聯。
3) 通過不斷的讀寫操作完成數據的複製存儲。
4) 關閉流資源。
③、實現方式:兩種(一次讀一個字符的方式:read()方法。一次讀多個字符用臨時容器存儲的方式:read(char[] buf))
④、文件複製實現圖例:
第一種方式:
實現代碼:
import java.io.*;
class CopyText
{
public static void main(String[] args) throws IOException
{
copy_1();
}
public static voidcopy_1() throws IOException
{
//創建目的地文件。
FileWriter fw = new FileWriter("RuntimeDemo_copy.txt");
//與已有文件關聯。
FileReader fr = new FileReader("FileReaderDemo.java");
int ch = 0;
while((ch = fr.read()) != -1)
{
fw.write(ch);
}
fw.close();
fr.close();
}
}
第二種方式:
實現代碼:
import java.io.*;
class CopyText
{
public static void main(String[] args)
{
copy_2();
}
public static void copy_2()
{
FileWriter fw = null;
FileReader fr = null;
try
{
fw = new FileWriter("RuntimeDemo_copy2.txt");
fr = new FileReader("FileReaderDemo2.java");
char[] buf = new char[1024];
int len = 0;
while((len = fr.read(buf)) != -1)
{
fw.write(buf,0,len);
}
}
catch(IOException e)
{
throw new RuntimeException("讀寫失敗");
}
finally
{
if(fr != null)
try
{
fr.close();
}
catch(IOException e)
{
e.printStackTrace();
}
if(fw!=null)
try
{
fw.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
}