JavaSE IO原理及流的引入(上)
-
IO流用來處理設備之間的數據傳輸。
-
Java中,對於數據的輸入/輸出操作以“流(Stream)”的方式進行。
-
java.io包下提供了各種“流”類和接口,用來獲取不同種類的數據,並通過標準的方法輸入或輸出數據。
Java IO原理
輸入input: 讀取外部數據(磁盤、光盤等存儲設備的數據)到程序內存中。
**輸出output:**將程序(內存)數據輸出到磁盤、光盤等存儲設備中
流的分類
按照操作數據單位不同分爲:字節流(8bit),字符流(16bit)
按照數據流的流向不同分爲:輸入流、輸出流
按照流的角色不同分爲:結點流、處理流
抽象基類 | 字節流 | 字符流 |
---|---|---|
輸入流 | InputStream | Reader |
輸出流 | OutputStream | Writer |
1 文件流
1.1 文件字節流
-
文件字節輸入流
FileInputStream in = new FileInputStream("file");
重點關注
int read(byte[] b)
的使用 -
文件字節輸出流
FileOutputStream out = new FileOutputStream("file")
重點關注
out.write(str.getBytes())
、out.flush()
的使用
注意:字節流使用完畢後一定要關閉。
文件輸入輸出流案例:
package com.io;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo02 {
public static void main(String[] args) {
testFileInputStream();
testFileOutputStream();
}
//文件字節輸入流
public static void testFileInputStream(){
try {
FileInputStream in = new FileInputStream("/Users/demut/Documents/File/aaa.txt");
byte[] b = new byte[100]; //設置一個byte數組接受讀取的文件內容
int len = 0;//設置一個讀取數據的長度
// in.read(b);//讀取字符到b數組,返回讀取到的字符個數,如果是文件結尾返回-1
while((len = in.read(b)) != -1){
System.out.println(new String(b,0,len));
//new String(b,0,len)表示從0開始讀取,總共轉換len個字節
}
in.close();//流在使用完畢之後一定要關閉
} catch (IOException e) {
e.printStackTrace();
}
}
//文件字節輸出流
public static void testFileOutputStream(){
try {
FileOutputStream out = new FileOutputStream("/Users/demut/Documents/File/aaa.txt");
String str = "aaaaaabbbbbbbccc";
out.write(str.getBytes());//把數據寫入內存
out.flush(); //將內存中的數據刷寫到硬盤上
out.close();//關閉流
} catch (IOException e) {
e.printStackTrace();
}
}
}
複製文件到指定文件/文件夾案例:
package com.io;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
//複製文件到指定文件夾下
public class Demo03 {
public static void main(String[] args) {
//將aaa.txt中內容寫入到tt1.txt文件中
copyFile("/Users/demut/Documents/File/aaa.txt","/Users/demut/Documents/File/tt1.txt");
}
public static void copyFile(String inPath, String outPath){
try {
FileInputStream in = new FileInputStream(inPath);
FileOutputStream out = new FileOutputStream(outPath);
byte[] b = new byte[100];
int len = 0;
while ((len = in.read(b)) != -1){
out.write(b, 0, len); //b表示緩衝數組,0表示從數組的位置開始寫,len表示獲取的數組總長度
}
out.flush();
out.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
結果展示:(寫入成功!)
運行前:
運行後:
注意: 文件字節流非常通用,可以用來操作字符的文檔,還可以操作任何的其他類型文件(圖片,壓縮包等),因爲字節流直接使用二進制。
1.2 文件字符流
-
文件字符輸入流
讀取文件操作步驟:
-
建立一個流對象,將已存在的一個文件加載進流。
FileReader fr = FileReader("Test.txt");
-
創建一個臨時存放數據的數組。
char[] ch = new char[1024];
-
調用流對象的讀取方法將流中的數據讀入到數組中。
fr.read(ch)
-
-
文件字符輸出流
數據寫入文件操作步驟:
-
建立一個流對象,將已存在/不存在的一個文件加載進流。
FileWriter fw = FileWriter("Test.txt");
-
將讀取到的字符數組/字符串/數字寫入內存中。
fw.write(text);
-
把內存中數據刷到硬盤中,即寫入文件。
fw.flush();
-
注意: 無論是輸入流/輸出流,使用完畢一定要關閉流。
文件字符輸入&&輸出流案例:
package com.io;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Test4 {
public static void main(String[] args) {
File file = new File("/Users/demut/Documents/File/ttt.txt");
testFileReader(file.toString()); //讀取原文件中字符串
testFileWriter("HelloWorld",file.toString()); //寫入新的字符串到文件中
testFileReader(file.toString()); //讀取更改後文件內部的字符串
}
/**
* 文件字符輸入流
* @param inPath 讀取的文件
*/
public static void testFileReader(String inPath){
try {
FileReader fr = new FileReader(inPath);//創建文件字符輸入流的對象
char[] c = new char[10]; //創建臨時存放數據的數組-->一次最多存放10個
int len = 0; //定義一個輸入流的讀取長度
while ((len = fr.read(c)) != -1){
System.out.println(new String(c, 0, len));
}
fr.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 文件字符輸出流FileWriter
* @param text 輸出的內容
* @param outPath 輸出的文件
*/
public static void testFileWriter(String text, String outPath){
try {
FileWriter fw = new FileWriter(outPath);
fw.write(text); //寫到內存中
fw.flush(); //把內存數據刷到硬盤中
fw.close(); //關閉流
} catch (IOException e) {
e.printStackTrace();
}
}
}
運行結果:
更改前:
更改後:
使用字符流拷貝文件到指定文件案例:
package com.io;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Test4 {
public static void main(String[] args) {
copyFile("/Users/demut/Documents/File/ttt.txt",
"/Users/demut/Documents/File/aaa/ttt1.txt");
}
/**
* 字符流完成拷貝文件,字符流只適合操作內容是字符的文件
* @param inPath
* @param outPath
*/
public static void copyFile(String inPath, String outPath){
try {
FileReader fr = new FileReader(inPath);
FileWriter fw = new FileWriter(outPath);
char[] c = new char[1024];
int len = 0;
while ((len = fr.read(c)) != -1){ //讀取數據
fw.write(c,0,len); //寫入數據到內存中
}
fw.flush(); //內存數據刷新到硬盤
fw.close();
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
運行結果:
運行前:
運行後:
注意:
- 字符流只適合操作內容是字符的文件!
- 在寫入一個文件時,如果目錄下有同名文件將被覆蓋。
- 在讀取文件時,必須保證文件存在,否則會異常。
2 緩衝流(基於內存的操作)
我們之前提到的文件流:FileInputStream, FileOutputStream,FileReader, FileWrite
這些都是計算機與硬盤之間發生的io操作,基於硬盤的讀寫相對不較慢,這個操作的速度收到硬盤的讀寫速度制約,爲了能夠提高讀寫速度,一定程度上繞過硬盤的限制,java提供了緩衝流來實現。
爲了提高數據讀寫的速度,JavaAPI提供了帶緩衝功能的流類,在使用這些流類時,會創建一個內部緩衝區數組。
緩衝流就是先把數據緩衝到內存中,在內存中去做io操作,基於內存的io操作比基於硬盤的io操作快75000多倍。
2.1 緩衝字節流
使用與文件字符流使用相像,但是聲明過程爲以下:
-
緩衝字節輸入流:
FileInputStream in = new FileInputStream("...");
BufferedInputStream br = new BufferedInputStream(in);
-
緩衝字節輸出流
FileOutputStream out = new FileOutputStream("...");
BufferedOutputStream bo = new BufferedOutputStream(out)
案例展示:(本案例展示緩衝字節輸入、輸出流及拷貝文件的操作)
package com.io;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class Test5 {
public static void main(String[] args) throws Exception {
testBufferedInputStream();
testBufferedOutputStream();
copyFile();
}
/**
* 緩衝字節輸入流
* @throws Exception
*/
public static void testBufferedInputStream() throws Exception{
//文件字節輸入流對象
FileInputStream in = new FileInputStream("/Users/demut/JAVASE Project" +
"/JavaSE/基礎語法/src/com/io/aaa.txt");
//把文件字節輸入流放到緩衝字節輸入流對象
BufferedInputStream br = new BufferedInputStream(in);
byte[] b = new byte[10];
int len = 0;
while ((len = br.read(b)) != -1){
System.out.println(new String(b,0,len));//將比特數組轉換爲字符串
}
//關閉流的時候順序要求:後開的流先關閉
br.close();
in.close();
}
/**
* 緩衝字節輸出流
* @throws Exception
*/
public static void testBufferedOutputStream() throws Exception{
//創建字節輸出流對象
FileOutputStream out = new FileOutputStream("/Users/demut/JAVASE Project" +
"/JavaSE/基礎語法/src/com/io/aaa.txt");
//把字節輸出流對象放到緩衝字節輸出流中
BufferedOutputStream bo = new BufferedOutputStream(out);
String str = "Hello World";
bo.write(str.getBytes()); //寫入內存中
bo.flush(); //內存中數據刷到硬盤上
bo.close(); //關閉流
out.close(); //關閉流
}
/**
* 拷貝文件
* @throws Exception
*/
public static void copyFile() throws Exception{
//緩衝輸入流
BufferedInputStream br = new BufferedInputStream(new FileInputStream("/Users/demut/JAVASE Project" +
"/JavaSE/基礎語法/src/com/io/aaa.txt"));
//緩衝輸出流
BufferedOutputStream bo = new BufferedOutputStream(new FileOutputStream("/Users/demut/JAVASE Project" +
"/JavaSE/基礎語法/src/com/io/bbb.txt"));
byte[] b = new byte[1024];
int len = 0; //len接受讀取到的數據的長度,直到讀取到最後(返回-1)
while ((len = br.read(b)) != -1){
bo.write(b,0,len); //數據寫入內存中
}
bo.flush(); //數據從內存刷新到硬盤中
bo.close();
br.close();
}
}
結果展示:(僅展示拷貝文件結果)
程序運行前:
程序運行後:
2.2 緩衝字符流
同樣與上述使用十分相似,注意聲明語句如下:
-
緩衝字符輸入流:
FileReader fr = new FileReader("...");
BufferedReader br = new BufferedReader(fr);
-
緩衝字節輸出流
FileWriter fw = new FileWriter("...");
BufferedWriter bw = new BufferedWriter(fw)
案例展示:(本案例展示緩衝字符輸入、輸出流及拷貝文件的操作)
package com.io;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
/**
* 緩衝字符流
*/
public class Test6 {
public static void main(String[] args) throws Exception{
//testBufferedReader();
//testBufferedWriter();
copyFile();
}
/**
* 緩衝字符輸入流
* BufferedReader
* @throws Exception
*/
public static void testBufferedReader() throws Exception{
FileReader fr = new FileReader("/Users/demut/JAVASE Project/JavaSE/基礎語法/src/com/io/aaa.txt");
BufferedReader br = new BufferedReader(fr);
char[] c = new char[100];
int len = 0;
while ((len = br.read(c))!=-1){
System.out.println(new String(c,0,len));
}
br.close();
fr.close();
}
/**
* 緩衝字符輸出流
* BufferedWriter
* @throws Exception
*/
public static void testBufferedWriter() throws Exception{
FileWriter fw = new FileWriter("/Users/demut/JAVASE Project/JavaSE/基礎語法/src/com/io/bbb.txt");
BufferedWriter bw = new BufferedWriter(fw);
String str = "JeverDemut";
bw.write(str); //寫入內存
bw.flush(); //刷入硬盤
bw.close();
fw.close();
}
/**
* 使用緩衝字符流拷貝文件
* @throws Exception
*/
public static void copyFile() throws Exception{
BufferedReader br = new BufferedReader(new FileReader("/Users/demut/JAVASE Project/JavaSE/基礎語法/src/com/io/bbb.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("/Users/demut/JAVASE Project/JavaSE/基礎語法/src/com/io/ccc.txt"));
char[] c = new char[100];
int len = 0;
while ((len = br.read(c))!=-1){
bw.write(c,0,len);
}
bw.flush();
bw.close();
br.close();
}
}
結果展示:(僅展示拷貝文件結果)
程序運行前:
程序運行後:
注意:緩衝流是把數據緩衝到內存中。
**JavaSE IO原理及流的引入(下)**重點介紹以下流:
轉換流、打印流(瞭解)、數據流(瞭解)、對象流 —涉及序列化、反序列化、隨機存取文件流
寫在最後
My darling,我和FF99FF時刻在想你!
To Dottie!