Java——I/O(位元組流、字元流與轉換流 )
阿新 • • 發佈:2018-12-16
位元組流和字元流
位元組流(byte):InputStream、OutputStream
字元流(char):Reader、Writer
-
位元組流與字元流的區別:
位元組流是原生的操作,而字元流是經過處理後的操作。
- 一般使用位元組流——無論是網路傳輸還是磁碟的資料儲存均以位元組為單位,只有處理中文文字時才會用到字元流。
1. 流操作流程
- 輸入流:
- 準備檔案
- 例項化FileInputSream物件
- read()讀取資料
- 業務處理資料
- 關閉輸入流-finally
- 輸出流:
- 準備檔案,檔案不存在自動建立,但是目錄一定要存在
- 例項化FileOutputSream物件
- 業務處理資料
- write()輸出資料
- 關閉輸入流-finally
-
業務處理
讀取資料,while( ){ },讀到末尾返回-1
InputStream in= null; OutputStream out=null; try { in = new FileInputStream(file); out=new FileOutputStream(file); int value=-1; //輸入 while((value=in.read())!=-1){ //程式中進行資料的處理 value+=32; //輸出 out.write(value); } } catch (FileNotFoundException e) { e.printStackTrace(); }
- I/O操作屬於於資源處理,所有的資源處理操作(IO操作、資料庫操作、網路)使用後必須要進行關閉。
2. 位元組輸出流(OutputStream)
public abstract class OutputStream implements Closeable, Flushable
//Closeable介面:
public void close() throws IOException;
//Flushable介面:
public void flush() throws IOException;
-
2.1 輸出方法
//將給定的位元組陣列內容全部輸出 public void write(byte b[]) throws IOException //將部分位元組陣列內容輸出 public void write(byte b[], int off, int len) throws IOException //輸出單個位元組 public abstract void write(int b) throws IOException;
- 要進行檔案內容的輸出,使用FileOutputStream()
//檔案內容覆蓋
public FileOutputStream(File file) throws FileNotFoundException
//檔案內容追加
public FileOutputStream(File file,boolean append) throws FileNotFoundException
- 當使用FileOutputStream進行檔案內容輸出時,只要檔案父路徑存在,FileOutputStream會自動建立檔案
import java.io.*;
/**
* 位元組輸出流
* Author: qqy
*/
public class Test {
public static void main(String[] args) throws IOException {
//1.取得終端物件
File file = new File("E:"+File.separator+"JAVA"+File.separator+"Test.txt");
//只要檔案父路徑存在,FileOutputStream會自動建立檔案
//OutputStream為抽象方法,需要借用子類進行例項化
OutputStream out =null;
OutputStream out1 =null;
//2.取得終端物件的輸出流
try {
out = new FileOutputStream(file);
//允許內容的追加
out1 = new FileOutputStream(file,true);
//3.進行資料的輸出
String msg="你好世界!!!\r\n";
//當出現中文時,最好全部輸出,避免出現亂碼
out.write(msg.getBytes(),0,6); //你好
out1.write(97); //a
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}finally{
//4.關閉流
out.close();
out1.close();
}
}
}
3. 自動關閉支援AutoCloseable-JDK1.7
- 使用前提:結合try...catch...
/**
* 自動關閉
* Author: qqy
*/
public class Test1 {
public static void main(String[] args) {
//try-with-resources try(例項化物件的程式碼,例項化物件的類實現AutoCloseable介面)
//例項化多個物件時,用分號隔開,最後一個不用加分號
try(Msg msg=new Msg();
try(Msg msg1=new Msg()
){
msg.print(); //normal method... auto close...
}catch (Exception e){
}
}
}
class Msg implements AutoCloseable{
@Override
public void close() throws Exception {
System.out.println("auto close...");
}
public void print(){
System.out.println("normal method...");
}
}
4. 位元組輸入流(InputSream)
public abstract class InputStream implements Closeable
-
4.1 輸入方法
//讀取資料到位元組陣列b中
public int read(byte b[]) throws IOException
//讀取單個位元組
public int read() throws IOException
- 返回值:
返回b長度:讀取資料大小>位元組陣列大小,返回位元組陣列大小
返回大於0但是小於b長度:讀取資料大小<位元組陣列大小,返回真正讀取個數
返回-1:資料讀取完畢
import java.io.*;
/**
* 位元組輸入流
* Author: qqy
*/
public class Test2 {
public static void main(String[] args) throws IOException {
//1.取得File物件
File file = new File("E:"+File.separator+"JAVA"+File.separator+"Test.txt");
//2.取得輸入流
InputStream in= null;
try {
in = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//3.讀取檔案內容
byte[] data=new byte[1024];
int res= 0;
try {
res = in.read(data);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(res);
System.out.println(new String(data));
//4.關閉輸入流
in.close();
}
}
5. 字元流
-
5.1 字元輸出流(Writer)
除了引數為字元陣列外,多了一個傳入String物件的方法
public void write(String str) throws IOException
import java.io.*;
/**
* 字元輸出流
* Author: qqy
*/
public class Test3 {
public static void main(String[] args) throws IOException {
//1.取得File物件
File file = new File("E:"+File.separator+"JAVA"+File.separator+"Test.txt");
//2.取得輸出流
Writer writer=new FileWriter(file);
//3.寫入資料
String str="你好Bonjour";
writer.write(str);
//4.關閉流
writer.close();
}
}
-
5.2 字元輸入流(Reader)
Reader類中沒有方法可以直接讀取字串,只能通過字元陣列來讀取
import java.io.*;
/**
* 字元輸入流
* Author: qqy
*/
public class Test4 {
public static void main(String[] args) throws IOException {
//1.取得File物件
File file = new File("E:"+File.separator+"JAVA"+File.separator+"Test.txt");
//2.取得輸入流
Reader reader= new FileReader(file);
//3.讀取資料
char[] data=new char[1024];
int result=reader.read(data);
System.out.println(result);
System.out.println(new String(data,0,result));
//4.關閉流
reader.close();
}
}
6. 位元組流與字元流
- 開發中,優先考慮位元組流,只有處理中文時才考慮使用字元流。
- 所有字元流操作,無論是寫入還是輸出,資料都先儲存在快取中——字元輸出流不關閉,檔案中無內容;位元組輸出流不關閉,檔案中有內容。
- 想要將字元輸出流在檔案中顯示,要麼正常關閉—out.close(),要麼強制清空快取區—out.flush()
練習:檔案複製(位元組流)
import java.io.*;
import java.nio.file.Paths;
/**
* 檔案複製
* Author: qqy
*/
public class Test6 {
public static void main(String[] args) throws IOException {
String src="";
String dest="";
long start=System.currentTimeMillis(); //毫秒數
copy(src,dest);
long end=System.currentTimeMillis();
System.out.println(end-start/1000+"s"); //秒數
}
public static void copy(String srcFilePath,String destFilePath){
//引數校驗
if (srcFilePath==null||srcFilePath.isEmpty()) {
throw new IllegalArgumentException("srcFilePath not null/empty!");
}
if (destFilePath==null||destFilePath.isEmpty()) {
throw new IllegalArgumentException("destFilePath not null/empty!");
}
File srcFile =Paths.get(srcFilePath).toFile();
File destFile =Paths.get(destFilePath).toFile();
//檔案校驗以及準備工作
if(!srcFile.exists()||!srcFile.isFile()){
throw new IllegalArgumentException("srcFilePath not exists or not file!")
}
File parentFile= destFile.getParentFile();
if(!parentFile.exists()){
if(!parentFile.mkdirs()){
throw new RuntimeException("can't create"+parentFile.getAbsolutePath()+"directory");
}
}
//檔案複製
try(FileInputStream in=new FileInputStream(srcFile);
FileOutputStream out =new FileOutputStream(destFile)
){
//緩衝陣列
//引入緩衝區
byte[] buff = new byte[1024]; //1k,2k,4k,8k
int len=-1;
//一次只讀一個位元組,再輸出一個位元組
while((len=in.read(buff))!=-1){
//為了避免資料讀取不全,使用下列方式進行寫入
out.write(buff,0,len);
}
}catch(IOException e){
System.out.println(e.getMessage());
}
}
}
轉換流
位元組流—>字元流,用於將底層的位元組流轉為字元流供子類使用
OutputStreamWriter:位元組輸出流—>字元輸出流
InputStreamReader:位元組輸入流—>字元輸入流
import java.io.*;
/**
* 轉換流
* Author: qqy
*/
public class Test7 {
public static void main(String[] args) throws IOException {
//1.取得檔案物件
File file = new File ("E:"+File.separator+"JAVA"+File.separator+"Test.txt");
//2.取得輸出流
OutputStream outputStream=new FileOutputStream(file);
//3.位元組流變為字元流,注意編碼格式
OutputStreamWriter out=new OutputStreamWriter(outputStream);
out.write("你好 Bonjour");
//4.關閉流
out.close();
}
}