1.基本IO操作
有時候我們編寫的程序除了自身會定義一些數據信息外,還需要引用外界的數據,或是將自身的數據發送到外界,這時我們需要使用輸入與輸出。
1)輸入與輸出
- 輸入:是一個從外界進入到程序的方向,通常我們需要“讀取”外界的數據時,使用輸入。所以輸入是用來讀取數據的
- 輸出:是一個從程序發送到外界的方向,通常我們需要“寫出”數據到外界時,使用輸出。所以輸出是用來寫出數據的
2)節點流與處理流
按照流是否直接與特定的地方(如磁盤、內存、設備等)相連,分為節點流和處理流兩類。
- 節點流:可以從一個特定的地方(節點)讀寫數據,通常也稱為低級流
- 處理流:是對一個已存在的流的連接和封裝,通過所封裝的流的功能調用實現數據讀寫,通常也稱為高級流或過濾流
處理流的構造方法總是要帶一個其他的流對象做參數,一個流對象經過其他流的多次包裝,稱為流的鏈接。
3)IS和OS常用方法
InputStream是所有字節輸入流的父類,其定義了基礎的讀取方法,如下:
- int read():讀取一個字節,以int形式返回,該int值的“低8位”有效,若返回值為-1則表示EOF
- int read(byte[] d):嘗試最多讀取給定數組length個字節並存入該數組,返回值為實際讀取到的字節量
OutputStream是所有字節輸出流的父類,其定義了基礎的寫出方法,如下:
- void write(int d):寫出一個字節,寫的是給定的int的“低8位”
- void write(byte[] d):將給定的字節數組中的所有字節全部寫出
4)創建FOS對象(重寫模式)
FileOutputStream是文件的字節輸出流,使用該流可以以字節為單位將數據寫入文件。
- FileOutputStream(File file):創建一個指定File對象表示的文件中寫出數據的文件輸出流
- FileOutputStream(String filename):創建一個向具有指定名稱的文件中寫出數據的文件輸出流
注意點:若指定的文件已經包含內容,那么當使用FOS對其寫入數據時,會將該文件中原有的數據全部清楚。
案例1:FOS覆蓋方式寫文件
import java.io.FileOutputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("fos.txt");
String str = "Hello,World";
byte[] date = str.getBytes();
fos.write(date);
System.out.println("寫出完畢");
fos.close();
}
}
5)創建FOS對象(追加模式)
若想在文件的原有數據之后追加新數據,則需要以下構造方法創建FOS:
- FileOutputStream(File file,boolean append):創建一個向指定File對象表示的文件中寫出數據的文件輸出流
- FileOutputStream(String filename,boolean append):創建一個向具有指定名稱的文件中寫出數據的文件輸出流
以上兩個構造方法中,第二個參數若為true,那么通過該FOS寫出的數據都是在文件末尾追加的。
案例2:FOS追加模式寫文件
import java.io.FileOutputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("fos.txt",true);
String str = "Hello,World";
byte[] date = str.getBytes();
fos.write(date);
System.out.println("寫出完畢");
fos.close();
}
}
6)創建FIS對象
FileInputStream是文件的字節輸入流,我們使用該流可以以字節為單位從文件中讀取數據。FileInputStream有兩個常用的構造方法,如下:
- FileInputStream(File file):創建一個從指定file對象表示的文件中讀取數據的文件輸入流
- FileInputStream(String name):創建用於讀取給定的文件系統中的路徑名name所指定的文件的文件輸入流
案例3:FIS讀取文件數據
import java.io.FileInputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("fos.txt");
int d = -1;
while((d=fis.read())!=-1){
System.out.print((char)d);
}
fis.close();
}
}
/*
* 運行結果:
* Hello,WorldHello,World
*/
7)read()和write(int d)方法
FileInputStream繼承自InputStream,其提供了以字節為單位讀取文件數據的方法read。
- int read():從此輸入流中讀取一個數據字節,若返回-1則表示EOF(End Of File)
FileOutputStream繼承自OutputStream,其提供了以字節為單位向文件寫數據的方法write。
- void write(int d):將指定字節寫入此文件輸出流,這里只寫給定int值的“低8位”
8)read(byte[] d)和write(byte[] d)方法
FileInputStream也支持批量讀取字節數據的方法:
- int read(byte[] d):從此輸入流中將最多的d.length個字節的數據讀入到字節數組d中
FileOutputStream也支持批量寫出字節數據的方法:
- void write(byte[] d):將d.length個字節從指定byte數組寫入此文件輸出流中
- void write(byte[] d,int offset,int len):將指定byte數組中從偏移量off開始的len個字節寫入此文件輸出流
2.緩沖流
1)BOS基本工作原理
在向硬件設備做寫出操作時,增大寫出次數無疑會降低寫出效率,為此我們可以使用緩沖輸出流來一次性批量寫出若干數據減少寫出次數來提高寫出效率。BufferedOutputStream緩沖輸出流內部維護着一個緩沖區,每當我們向該流寫數據時,都會先將數據存入緩沖區,當緩沖區已滿時,緩沖流會將數據一次性全部寫出。
案例4:BOS演示
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
//創建緩沖字節輸出流
FileOutputStream fos = new FileOutputStream("fos.txt");
//所有字節被存入緩沖區,等待一次性寫出
BufferedOutputStream bos = new BufferedOutputStream(fos);
String str = "Hello Java";
byte[] date = str.getBytes();
bos.write(date);
//關閉流之前,緩沖輸出流會將緩沖區內容一次性寫出
bos.close();
System.out.println("寫出完畢");
}
}
2)BOS的flush方法
使用緩沖輸出流可以提高寫出效率,但是這也存在一個問題,就是寫出數據缺乏即時性。有時需要在執行完某些寫出操作后,就希望將這些數據確實寫出,而不是在緩沖區中保存知道緩沖區滿后才寫出。這就需要flush方法了。
- void flush():清空緩沖區,將緩沖區中的數據強制寫出
案例5:flush演示
import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; public class Test { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("fos.txt"); BufferedOutputStream bos = new BufferedOutputStream(fos); String str = "Hello Java"; byte[] date = str.getBytes(); bos.write(date); bos.flush(); //強制將緩沖區已緩存數據一次性寫出 System.out.println("寫出完畢"); bos.close(); } }
3)BIS基本工作原理
在讀取數據時若以字節為單位讀取數據,會導致讀取次數過於頻繁從而大大降低讀取效率。為此我們可以通過提高一次讀取的字節數量減少讀寫次數來提高讀取的效率。BufferedInputStream是緩沖字節輸入流。其內部維護着一個緩沖區(字節數組),使用該流在讀取一個字節時,該流會盡可能多的一次性讀取若干字節並存入緩沖區,然后逐一的將字節返回,直到緩沖區中的數據被全部讀取完畢,會再次讀取若干字節從而反復,這樣就減少了讀取的次數,提高了讀取效率。
BIS是一個處理流,該流為我們提供了緩沖功能。
案例6:BIS演示
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
//創建緩沖字節輸入流
FileInputStream fis = new FileInputStream("fos.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
int d = -1;
//緩沖讀入,實際上並非是一個字節一個字節從文件讀取
while((d=bis.read())!=-1){
System.out.println(d);
}
bis.close();
}
}
3.對象流
1)對象序列化
對象是存在於內存中的。有時候我們需要將對象保存到硬盤上或者將對象傳輸到另一台計算機上等,這時需要將對象轉換為一個字節序列,而這個過程就成為對象序列化。相反,這樣一個字節序列需要將其轉換為對應的對象,這個過程成為對象的反序列化。
2)OOS實現對象序列化
ObjectOutputStream是用來對對象進行序列化的輸出流,方法如下:
- void writeObject(Object b):將給定的對象轉換為一個字節序列后寫出
3)OIS實現對象反序列化
ObjectInputStream是用來對對象進行反序列化的輸入流,方法如下:
- Object readObject():從流中讀取字節並轉換為對應的對象
4)Serializable接口
ObjectOutputStream在對對象進行序列化時有一個要求,就是需要序列化的對象所屬的類必須實現Serializable接口。實現該接口不需要重寫任何方法,其只是作為可序列化的標志。通常實現該接口的類需要提供一個常量serialVersionUID,表明該類的版本。若不顯示的聲明,在對象序列化時也會根據當前類的各個方面計算該類的默認serialVersionUID,但不同平台編譯器實現有所不同,所以若想跨平台,都應顯示的聲明版本號。
如果聲明的類的對象序列化存到硬盤上面,之后隨着需求的變化更改了類的屬性(增加或減少或改名),那么當反序列化時,就會出現InvalidClassException,這樣會造成不兼容的問題。但當serialVersionUID相同時,它就會將不一樣的field以type的預設值反序列化,可避開不兼容性問題。
案例7:OOS序列化演示
//創建類Person import java.io.Serializable; import java.util.List; public class Person implements Serializable{ private static final long serialVersionUID = 1L; private String name; private int age; private char gender; private double salary; private List<String> otherInfo; @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", gender=" + gender + ", salary=" + salary + ", otherInfo=" + otherInfo + "]"; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public char getGender() { return gender; } public void setGender(char gender) { this.gender = gender; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } public List<String> getOtherInfo() { return otherInfo; } public void setOtherInfo(List<String> otherInfo) { this.otherInfo = otherInfo; } }
進行序列化
import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.List; /* * 對象流是一組高級流,作用是方便讀寫java中任何對象. * 對象輸出流,可以寫出java對象 * 工作原理:將給定java對象按照其結構轉化為一組字節然后寫出. */ public class OOSDemo { public static void main(String[] args) throws IOException { Person p = new Person(); //引用對象並設置相關信息 p.setName("暮"); p.setAge(20); p.setGender('男'); p.setSalary(5000); List<String> otherInfo = new ArrayList<String>(); otherInfo.add("是一位詩人"); otherInfo.add("也是一位程序猿"); p.setOtherInfo(otherInfo); System.out.println(p.toString()); //開始寫出對象 FileOutputStream fos = new FileOutputStream("mu.obj"); ObjectOutputStream oos = new ObjectOutputStream(fos); //當調用oos.writeObject時,實際上做了兩件事:將p對象按照結果轉換為了一組字節(對象序列化) //然后再將這組字節通過FOS寫入到文件中,將數據寫入硬盤的過程成為:持久化 oos.writeObject(p); //對象序列化 //可能會報錯: java.io.NotSerializableException,這是因為對象所屬的類沒有繼承Serializable接口,需要繼承接口並生成serialVersionUID System.out.println("序列化完成"); oos.close(); } } /* * 運行結果: * 反序列化完成 * Person [name=暮, age=20, gender=男, salary=5000.0, otherInfo=[是一位詩人, 也是一位程序猿]] */
案例8:反序列化演示
import java.io.FileInputStream; import java.io.IOException; import java.io.ObjectInputStream; public class OISDemo { public static void main(String[] args) throws ClassNotFoundException, IOException { FileInputStream fis = new FileInputStream("mu.obj"); ObjectInputStream ois = new ObjectInputStream(fis); Person p = (Person)ois.readObject(); System.out.println(p); System.out.println("反序列化完成"); ois.close(); } } /* * 運行結果: * Person [name=暮, age=20, gender=男, salary=5000.0, otherInfo=[是一位詩人, 也是一位程序猿]] * 反序列化完成 */
5)transient關鍵字
對象在序列化后得到的字節序列往往比較大,有時我們在對一個對象進行序列化時可以忽略某些不必要的屬性,從而對序列化后得到的字節序列“瘦身”。
- transient:被該關鍵字修飾的屬性在序列化時其值將被忽略。
案例9:transient演示
//修改類Person import java.io.Serializable; import java.util.List; public class Person implements Serializable{ private static final long serialVersionUID = 1L; private String name; private int age; private char gender; transient private double salary; //修改部分 transient private List<String> otherInfo; //修改部分 @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", gender=" + gender + ", salary=" + salary + ", otherInfo=" + otherInfo + "]"; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public char getGender() { return gender; } public void setGender(char gender) { this.gender = gender; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } public List<String> getOtherInfo() { return otherInfo; } public void setOtherInfo(List<String> otherInfo) { this.otherInfo = otherInfo; } }
序列化操作
import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.List; /* * 對象流是一組高級流,作用是方便讀寫java中任何對象. * 對象輸出流,可以寫出java對象 * 工作原理:將給定java對象按照其結構轉化為一組字節然后寫出. */ public class OOSDemo { public static void main(String[] args) throws IOException { Person p = new Person(); //引用對象並設置相關信息 p.setName("暮"); p.setAge(20); p.setGender('男'); p.setSalary(5000); List<String> otherInfo = new ArrayList<String>(); otherInfo.add("是一位詩人"); otherInfo.add("也是一位程序猿"); p.setOtherInfo(otherInfo); System.out.println(p.toString()); //開始寫出對象 FileOutputStream fos = new FileOutputStream("mu1.obj"); ObjectOutputStream oos = new ObjectOutputStream(fos); //當調用oos.writeObject時,實際上做了兩件事:將p對象按照結果轉換為了一組字節(對象序列化) //然后再將這組字節通過FOS寫入到文件中,將數據寫入硬盤的過程成為:持久化 oos.writeObject(p); //對象序列化 //可能會報錯: java.io.NotSerializableException,這是因為對象所屬的類沒有繼承Serializable接口,需要繼承接口並生成serialVersionUID System.out.println("序列化完成"); oos.close(); } } /* * 運行結果: * 反序列化完成 * Person [name=暮, age=20, gender=男, salary=5000.0, otherInfo=[是一位詩人, 也是一位程序猿]] */
反序列化,會發現加上transient關鍵字的部分輸出變成了默認值輸出。
import java.io.FileInputStream; import java.io.IOException; import java.io.ObjectInputStream; public class OISDemo { public static void main(String[] args) throws ClassNotFoundException, IOException { FileInputStream fis = new FileInputStream("mu1.obj"); ObjectInputStream ois = new ObjectInputStream(fis); Person p = (Person)ois.readObject(); System.out.println(p); System.out.println("反序列化完成"); ois.close(); } } /* * 運行結果: * Person [name=暮, age=20, gender=男, salary=0.0, otherInfo=null] * 反序列化完成 */
4.字符轉換流
1)Reader和Writer
字符流原理:
- Reader是字符輸入流的父類
- Writer是字符輸出流的父類
- 字符流是以字符(char)為單位讀寫數據的,一次處理一個unicode
- 字符流的底層仍然是基本的字節流
Reader常用方法:
- int read():讀取一個字符,返回的int值“低16位”有效
- int read(char[] chs):從該流中讀取一個字符數組的length個字符並存入該數組,返回值為實際讀取到的字符量
Writer的常用方法:
- void write(int c):寫出一個字符,寫出給定int值“低16位”表示的字符
- void write(char[] chs):將給定字符數組中所有字符寫出
- void write(String str):將給定的字符串寫出
- void write(char[] chs,int offset,int len):將給定的字符數組中從offset處開始連續的len個字符寫出
2)字符轉換流原理
- InputStreamReader:字符輸入流,使用該流可以設置字符集,並按照指定的字符集從流中按照該編碼將字節數據轉換為字符並讀取
- OutputStreamWriter:字符輸出流,使用該流可以設置字符集,並按照指定的字符集將字符轉換為對應字節后通過該流寫出
3)指定字符編碼
IntputStreamReader的構造方法允許我們設置字符集:
- InputStreamReader(InputStream in,String charsetName):基於給定的字節輸入流以及字符編碼創建ISR
- InputStreamReader(InputStream in):該構造方法會根據系統默認字符集創建ISR
OutputStreamWriter的構造方法:
- OutputStreamWriter(OutputStream out,String charsetName):基於給定的字節輸出流以及字符編碼創建OSW
- OutputStreamWriter(OutputStream out):該構造方法會根據系統默認字符集創建OSW
4)OSW
案例10:OSW演示
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class Test {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("demo.txt");
OutputStreamWriter writer = new OutputStreamWriter(fos,"UTF-8");
String str = "Java,你好!";
writer.write(str);
writer.close();
}
}
5)ISR
案例11:ISR演示
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class Test {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("demo.txt");
InputStreamReader reader = new InputStreamReader(fis,"utf-8");
int c = -1;
while((c=reader.read())!=-1){
System.out.print((char)c);
}
reader.close();
}
}
/*
運行結果:
Java,你好!
*/
5.緩沖字符流
1)PrintWriter
PrintWriter是具有自動行刷新的緩沖字符輸出流,提供了豐富的構造方法:
PrintWriter(File file) PrintWriter(String fileName) PrintWriter(OutputStream out) PrintWriter(OutputStream out,boolean autoFlush) PrintWriter(Writer writer) PrintWriter(Writer writer,boolean autoFlush)
其中OutputStream與Writer的構造方法提供了一個可傳入boolean值參數,該參數用於表示PrintWriter是否具有自動行刷新。
2)PrintWriter的重載print和println方法
使用PrintWriter寫出字符串時我們通常不使用Writer提供的writer()相關方法,而是使用print和println等方法,PrintWriter提供了若干重載的print和println方法,其中println方法是在寫出數據后自動追加一個系統支持的換行符。
重載方法:
void print(int i) //打印整數 void print(char c) //打印字符 void print(boolean b) //打印boolean值 void print(char[] c) //打印字符數組 void print(double d) //打印double值 void print(float t) //打印float值 void print(long l) //打印long值 void print(String str) //打印字符串
println的方法參數與上面相同。
3)使用PW輸出字符數據
import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; public class PW { public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException { FileOutputStream fos = new FileOutputStream("pw.txt"); OutputStreamWriter osw = new OutputStreamWriter(fos,"GBK"); //創建帶有自動行刷新的PW PrintWriter pw = new PrintWriter(osw,true); pw.println("或許青春根本就沒有明天"); pw.println("青春只有現在"); System.out.println("寫出完畢"); pw.close(); } }
4)BufferedReader
BufferedReader是緩沖字符輸入流,其內部提供了緩沖區,可以提高讀取效率。
常用構造方法:
BufferedReader(Reader reader)
創建一個BufferedRader緩沖字符輸入流:
FileInputStream fis = new FileInputStream("pw.txt"); InputStreamReader isr = new InputStreamReader(fis); BufferedReader br = new BufferedReader(isr);
因為BufferedReader在構造實例時需要傳入一個字符流,所以當我們想基於一個字節流進行讀取時,要先將字節流轉換為字符流后猜可以創建緩沖字符輸入流BufferedReader。
5)BR讀取字符串
BufferedReader讀取一行字符串:
String readLine()
該方法連續讀取一行字符串,直到讀取到換行符為止,返回的字符串中不包含該換行符,若EOF則返回null。
6)使用BR讀取一行字符串
import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; public class BR { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("pw.txt"); InputStreamReader isr = new InputStreamReader(fis); BufferedReader br = new BufferedReader(isr); String str = null; while((str=br.readLine())!=null){ System.out.println(str); } br.close(); } }
6.案例演示
案例1:FileOutputStream寫操作演示
import java.io.FileOutputStream; import java.io.IOException; public class FOS { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("fos.txt"); String str = "如果這注定是座荒蕪的墳墓,那么我將硬生生的變成一座美麗的花園!"; byte[] date = str.getBytes("GBK"); fos.write(date); System.out.println("寫出完畢"); fos.close(); } }
案例2:FileInputStream讀操作演示
import java.io.FileInputStream; import java.io.IOException; public class FIS { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("fos.txt"); byte[] date = new byte[100]; int len = fis.read(date); String str = new String(date,0,len,"GBK"); System.out.println(str); fis.close(); } } //運行結果:如果這注定是座荒蕪的墳墓,那么我將硬生生的變成一座美麗的花園!
案例3:緩沖輸出流寫操作演示
import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; public class BOSDemo { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("bos.txt"); BufferedOutputStream bos = new BufferedOutputStream(fos); String str = "東風吹落花滿路,一片相思卻似無."; byte[] date = str.getBytes("GBK"); bos.write(date); bos.flush(); System.out.println("寫出完畢"); bos.close(); } }
案例4:緩沖輸入流讀操作演示
import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; public class BOSDemo { public static void main(String[] args) throws IOException{ FileInputStream fis = new FileInputStream("bos.txt"); BufferedInputStream bis = new BufferedInputStream(fis); byte[] date = new byte[100]; int len = bis.read(date); String str = new String(date,0,len,"GBK"); System.out.println(str); bis.close(); } } /* 運行結果: 東風吹落花滿路,一片相思卻似無. */
案例5:使用文件流復制文件
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class CopyDemo { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("src.mp3"); FileOutputStream fos = new FileOutputStream("desc.mp3"); byte[] date = new byte[1024*10]; int len = -1; while((len = fis.read(date))!=-1){ fos.write(date,0,len); } System.out.println("復制完畢"); fis.close(); fos.close(); } }
案例6:緩沖流復制文件
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; /* * 緩沖流 緩沖流是一對高級流,作用是提高讀寫效率 */ public class CopyDemo02 { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("music.mp3"); BufferedInputStream bis = new BufferedInputStream(fis); FileOutputStream fos = new FileOutputStream("musiccopy.mp3"); BufferedOutputStream bos = new BufferedOutputStream(fos); int d = -1; while((d=bis.read())!=-1){ bos.write(d); } System.out.println("復制完畢"); bis.close(); bos.close(); } }
案例7:OSW轉換流寫出演示
import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; public class OSW { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("osw.txt"); OutputStreamWriter osw = new OutputStreamWriter(fos,"GBK"); osw.write("我從遠方來,帶着筆墨紙硯"); osw.write("我打江南走過,留下一紙舊約"); System.out.println("寫出完畢"); osw.close(); } }
案例8:ISR轉換流讀取演示
import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; public class ISR { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("osw.txt"); InputStreamReader isr = new InputStreamReader(fis,"GBK"); int d = -1; while((d=isr.read())!=-1){ System.out.print((char)d); } isr.close(); } } /* 運行結果: 我從遠方來,帶着筆墨紙硯我打江南走過,留下一紙舊約 */
案例9:PW緩沖字符輸入流直接對文件寫操作
import java.io.FileNotFoundException; import java.io.PrintWriter; /* * PW提供了直接針對文件寫操作的構造方法: * PrintWriter(String path) * PrintWriter(File file) * 按照指定字符集對文件寫操作: * PrintWriter(String path,String csn) * PrintWriter(File file,String csn) */ public class PWDemo { public static void main(String[] args) throws FileNotFoundException { PrintWriter pw = new PrintWriter("PW.txt"); pw.println("青春是一座墳墓"); pw.println("流年走過"); pw.println("留下不同的墓志銘"); System.out.println("寫出完畢"); pw.close(); } }
案例10:簡易記事本
要求:程序啟動后要求用戶輸入文件名,然后針對該文件寫入數據,每輸入一行字符串就按行寫入文件中,輸入"exit"時退出程序,最后將用戶寫出的數據讀取到控制台上。
import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.util.Scanner; public class Note { public static void main(String[] args) throws IOException { Scanner scan = new Scanner(System.in); System.out.println("請輸入文件名:"); String fileName = scan.nextLine(); PrintWriter pw = new PrintWriter(fileName,"GBK"); System.out.println("請輸入內容:"); while(true){ String line = scan.nextLine(); if(line.equals("exit")){ break; } pw.println(line); } System.out.println("寫出完畢,程序退出"); pw.close(); System.out.println("=====輸入內容展示====="); FileInputStream fis = new FileInputStream(fileName); InputStreamReader isr = new InputStreamReader(fis,"GBK"); BufferedReader br = new BufferedReader(isr); String line = null; while((line=br.readLine())!=null){ System.out.println(line); } br.close(); } } /* 運行結果: 請輸入文件名: note.txt 請輸入內容: 青春是一場盛宴 不繁華不罷休 exit 寫出完畢,程序退出 =====輸入內容展示===== 青春是一場盛宴 不繁華不罷休 */