Java I/O操作
Java I/O的內(nèi)容比較多, 類庫里提供了各種各樣的流. 很多使用起來類似, 這里只列舉了幾種常用的I/O流操作.
1. I/O簡介
I/O就是輸入和輸出,核心是I/O流,流用于讀寫設(shè)備上的數(shù)據(jù)灯蝴,包括硬盤文件驱富、內(nèi)存、鍵盤碗降、網(wǎng)絡(luò)...
- 根據(jù)數(shù)據(jù)的走向分為:輸入流政恍、輸出流
- 根據(jù)處理的數(shù)據(jù)類型分為:字節(jié)流、字符流
字節(jié)流能處理所有類型數(shù)據(jù)家破,對應(yīng)的類以Stream
結(jié)尾颜说。
字符流只能處理文本數(shù)據(jù),對應(yīng)的類以Reader
或Writer
結(jié)尾汰聋。
- 根據(jù)功能不同可分為:節(jié)點(diǎn)流门粪、處理流
(圖中橙色部分是節(jié)點(diǎn)流, 藍(lán)色是處理流, 處理流需要封裝節(jié)點(diǎn)流使用)
各種流的繼承關(guān)系:
2. 使用字節(jié)流讀寫數(shù)據(jù)
- 使用字節(jié)流讀數(shù)據(jù):
import java.io.FileInputStream;
import java.io.IOException;
public class ReadByteStream {
public static void main(String[] args) {
FileInputStream fis = null; // 聲明文件輸入流對象
try {
fis = new FileInputStream("test.txt"); // test.txt文件在當(dāng)前工程目錄下事先創(chuàng)建好
byte input[] = new byte[30];
fis.read(input); // 讀入到一個(gè)字節(jié)數(shù)組
String str = new String(input, "UTF-8"); // 字符編碼要與讀入的文件對應(yīng)
System.out.println(str);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close(); // 關(guān)閉輸入流
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
- 使用字節(jié)流寫數(shù)據(jù):
import java.io.FileOutputStream;
import java.io.IOException;
public class WriteByteStream {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream("test2.txt");
String str = "1234567";
byte[] outStr = str.getBytes("UTF-8"); // 讀入字節(jié)數(shù)組,并指定編碼方式
fos.write(outStr); // 使用文件輸出流寫出到文件
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
- 使用字節(jié)流拷貝文件
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyFile {
public static void main(String[] args) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("test.png");
fos = new FileOutputStream("test_new.png");
byte input[] = new byte[50]; // 每次讀取50 bytes
while (fis.read(input) != -1) { // read返回讀入的數(shù)據(jù)大小烹困,如果沒有數(shù)據(jù)返回-1
fos.write(input); // 每次寫入50 bytes
}
System.out.println("done");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3. 使用帶緩沖的字節(jié)流讀寫數(shù)據(jù)
帶緩沖的流和不帶緩沖的流區(qū)別:
- 不帶緩沖的操作, 每讀一個(gè)字節(jié)就要寫入一個(gè)字節(jié), 由于涉及磁盤的IO操作相比內(nèi)存的操作要慢很多, 所以不帶緩沖的流效率很低
- 帶緩沖的流, 可以一次讀很多字節(jié), 但不向磁盤中寫入, 只是先放到內(nèi)存里. 等湊夠了緩沖區(qū)大小的時(shí)候一次性寫入磁盤, 這種方式可以減少磁盤操作次數(shù), 速度就會提高很多!
- 帶緩沖的流適合讀寫比較大的文件.
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class ReadByBufferedByteStream {
public static void main(String[] args) {
try {
FileInputStream fis = new FileInputStream("movie.mp4");
BufferedInputStream bis = new BufferedInputStream(fis,1000000); // 緩沖區(qū)大小1000000字節(jié)
FileOutputStream fos = new FileOutputStream("moive_new.mp4");
BufferedOutputStream bos = new BufferedOutputStream(fos,1000000); // 緩沖區(qū)大小1000000字節(jié)
//大型文件對應(yīng)的數(shù)組可以大一些玄妈,小文件對應(yīng)的數(shù)組小一些
byte input[] = new byte[100000]; // 每次讀寫字節(jié)大寫
int count = 0;
long before = System.currentTimeMillis(); // 開始計(jì)時(shí)
while (bis.read(input) != -1) {
bos.write(input);
count++;
}
bos.flush();
bis.close();
fis.close();
bos.close();
fos.close();
System.out.println(System.currentTimeMillis()-before+"ms"); // 總時(shí)長
System.out.println("讀取了:"+count+"次");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
4. 使用字符流讀寫數(shù)據(jù)
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class RWByCharStream {
public static void main(String[] args) {
try {
FileInputStream fis = new FileInputStream("java.txt");
FileOutputStream fos = new FileOutputStream("java_new.txt");
InputStreamReader reader = new InputStreamReader(fis, "UTF-8"); // 字符流的使用要傳入字節(jié)流作為參數(shù)
OutputStreamWriter writer = new OutputStreamWriter(fos, "UTF-8");
char input[] = new char[100]; // 每次讀取的數(shù)據(jù)大小
int l = 0;
while ((l = reader.read(input)) != -1) {
// void write(char cbuf[], int off, int len)
// 文件末尾的長度不一定是100,所以需要設(shè)置寫入數(shù)據(jù)長度
writer.write(input, 0, l);
}
reader.close(); // 先關(guān)閉字符流
fis.close(); // 再關(guān)閉字節(jié)流
writer.close();
fos.close();
System.out.println("done");
} catch (IOException e) {
e.printStackTrace();
}
}
}
5. 使用帶緩沖的字符流讀寫數(shù)據(jù)
使用字符流讀取數(shù)據(jù)時(shí)不能按行讀取髓梅,這時(shí)候就需要使用帶有緩沖區(qū)的字符流拟蜻。
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
public class RWByBufferedCharStream {
public static void main(String[] args) {
try {
FileInputStream fis = new FileInputStream("java.txt");
FileOutputStream fos = new FileOutputStream("java_new_buff.txt");
InputStreamReader reader = new InputStreamReader(fis, "UTF-8");
OutputStreamWriter writer = new OutputStreamWriter(fos, "UTF-8");
BufferedReader br = new BufferedReader(reader);
// BufferedWriter bw = new BufferedWriter(writer);
// PrintWriter和BufferedWriter用法類似
// PrintWriter可以輸出換行符
// 構(gòu)造方法PrintWriter(Writer out,boolean autoFlush) 里可以設(shè)置緩沖區(qū)自動輸出,這樣就不需要手動調(diào)用flush方法了枯饿。
PrintWriter pw = new PrintWriter(writer, true);
String input;
while ((input = br.readLine()) != null) { // BufferedReader可以按行讀取
// bw.write(input); //
// BufferedWriter的writer方法是帶有緩沖區(qū)的酝锅,此時(shí)打印的文本是不帶換行符的
pw.println(input);// PrintWriter的println方法支持不同平臺的換行符輸出
}
// bw.flush(); // 強(qiáng)制輸出緩沖區(qū)內(nèi)容。如果不加上flush奢方,最后的緩沖區(qū)未讀滿將不輸出內(nèi)容
// bw.close();
pw.close();// 按順序關(guān)閉流
writer.close();
fos.close();
br.close();
reader.close();
fis.close();
System.out.println("done");
} catch (IOException e) {
e.printStackTrace();
}
}
}
6. FileReader 和FileWriter
FileReader 和FileWriter 專門用于操作文本文件. 用法與FileInputStream 類似.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FileRW {
public static void main(String[] args) {
FileReader fr = null;
BufferedReader br = null;
FileWriter fw = null;
BufferedWriter bw = null;
try {
fr = new FileReader("java.txt");
br = new BufferedReader(fr);
fw = new FileWriter("java_new.txt");
bw = new BufferedWriter(fw);
String line;
while ((line = br.readLine()) != null) {
bw.write(line + "\n");
}
bw.flush();
System.out.println("done");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bw.close();
fw.close();
br.close();
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}