1. 程式人生 > >【Java基礎】位元組流和字元流的區別

【Java基礎】位元組流和字元流的區別

原文連結:http://blog.csdn.net/zxman660/article/details/7875799

先來看一下流的概念:

在程式中所有的資料都是以流的方式進行傳輸或儲存的,程式需要資料的時候要使用輸入流讀取資料,而當程式需要將一些資料儲存起來的時候,就要使用輸出流完成。

程式中的輸入輸出都是以流的形式儲存的,流中儲存的實際上全都是位元組檔案。

位元組流與字元流

Java.io包中操作檔案內容的主要有兩大類:位元組流、字元流,兩類都分為輸入和輸出操作。在位元組流中輸出資料主要是使用OutputStream完成,輸入使的是InputStream,在字元流中輸出主要是使用Writer

類完成,輸入流主要使用Reader類完成。(這四個都是抽象類)

java中提供了專用於輸入輸出功能的包Java.io,其中包括:
     InputStream,OutputStream,Reader,Writer
     InputStream 和OutputStream,兩個是為位元組流設計的,主要用來處理位元組或二進位制物件,
     Reader和 Writer.兩個是為字元流(一個字元佔兩個位元組)設計的,主要用來處理字元或字串.


字元流處理的單元為2個位元組的Unicode字元,分別操作字元、字元陣列或字串,而位元組流處理單元為1個位元組,操作位元組和位元組陣列。所以字元流是由Java虛擬機器將位元組轉化為2個位元組的Unicode字元為單位的字元而成的,所以它對多國語言支援性比較好!如果是音訊檔案、圖片、歌曲,就用位元組流好點,如果是關係到中文(文字)的,用字元流好點
     所有檔案的儲存是都是位元組(byte)的儲存,在磁碟上保留的並不是檔案的字元而是先把字元編碼成位元組,再儲存這些位元組到磁碟。在讀取檔案(特別是文字檔案)時,也是一個位元組一個位元組地讀取以形成位元組序列

      位元組流可用於任何型別的物件,包括二進位制物件,而字元流只能處理字元或者字串; 2. 位元組流提供了處理任何型別的IO操作的功能,但它不能直接處理Unicode字元,而字元流就可以
       位元組流是最基本的,所有的InputStrem和OutputStream的子類都是,主要用在處理二進位制資料,它是按位元組來處理的 但實際中很多的資料是文字,又提出了字元流的概念,它是按虛擬機器的encode來處理,也就是要進行字符集的轉化 這兩個之間通過 InputStreamReader,OutputStreamWriter來關聯,實際上是通過byte[]和String來關聯 在實際開發中出現的漢字問題實際上都是在字元流和位元組流之間轉化不統一而造成的 

==================我們還可以看到:============
Reader類的read()方法返回型別為int :作為整數讀取的字元(佔兩個位元組共16位),範圍在 0 到 65535 

之間 (0x00-0xffff),如果已到達流的末尾,則返回 -1


inputStream的read()雖然也返回int,但由於此類是面向位元組流的,一個位元組佔8個位,所以返回 0 到 255 範圍內的 int 位元組值。如果因為已經到達流末尾而沒有可用的位元組,則返回值 -1。因此對於不能用0-255來表示的值就得用字元流來讀取!比如說漢字.


操作流程

JavaIO操作也是有相應步驟的,以檔案操作為例,主要的操作流程如下:

使用File類開啟一個檔案

通過位元組流或字元流的子類,指定輸出的位置

進行讀/寫操作

關閉輸入/輸出

IO操作屬於資源操作,一定要記得關閉

位元組流

位元組流主要是操作byte型別資料,以byte陣列為準,主要操作類就是OutputStreamInputStream

位元組輸出流:OutputStream

OutputStream是整個IO包中位元組輸出流的最大父類,此類的定義如下:

public abstract class OutputStream extends Object implements Closeable,Flushable

從以上的定義可以發現,此類是一個抽象類,如果想要使用此類的話,則首先必須通過子類例項化物件,那麼如果現在要操作的是一個檔案,則可以使用:FileOutputStream類。通過向上轉型之後,可以為OutputStream例項化

Closeable表示可以關閉的操作,因為程式執行到最後肯定要關閉

Flushable:表示重新整理,清空記憶體中的資料

FileOutputStream類的構造方法如下:

public FileOutputStream(File file)throws FileNotFoundException

寫資料:

1import java.io.File;2import java.io.FileOutputStream;3import java.io.IOException;4import java.io.OutputStream;56publicclass Test11 {7publicstaticvoid main(String[] args) throws IOException {8         File f = new File("d:" + File.separator+"test.txt");9         OutputStream out=new FileOutputStream(f);//如果檔案不存在會自動建立10         String str="Hello World";11byte[] b=str.getBytes();12         out.write(b);//因為是位元組流,所以要轉化成位元組陣列進行輸出13         out.close();14     }15 }

也可以一個位元組一個位元組進行輸出,如下:

1import java.io.File;2import java.io.FileOutputStream;3import java.io.IOException;4import java.io.OutputStream;56publicclass Test11 {7publicstaticvoid main(String[] args) throws IOException {8         File f = new File("d:" + File.separator+"test.txt");9         OutputStream out=new FileOutputStream(f);//如果檔案不存在會自動建立10         String str="Hello World";11byte[] b=str.getBytes();12for(int i=0;i<b.length;i++){13             out.write(b[i]);14         }15         out.close();16     }17 }

以上輸出只會進行覆蓋,如果要追加的話,請看FileOutputStream類的另一個構造方法:

public FileOutputStream(File file,boolean append)throws FileNotFoundException

在構造方法中,如果將append的值設定為true,則表示在檔案的末尾追加內容。

1import java.io.File;2import java.io.FileOutputStream;3import java.io.IOException;4import java.io.OutputStream;56publicclass Test11 {7publicstaticvoid main(String[] args) throws IOException {8         File f = new File("d:" + File.separator+"test.txt");9         OutputStream out=new FileOutputStream(f,true);//追加內容10         String str="\r\nHello World";11byte[] b=str.getBytes();12for(int i=0;i<b.length;i++){13             out.write(b[i]);14         }15         out.close();16     }17 }

檔案中換行為:\r\n

位元組輸入流:InputStream

既然程式可以向檔案中寫入內容,則就可以通過InputStream從檔案中把內容讀取進來,首先來看InputStream類的定義:

public abstract class InputStream extends Object implements Closeable

OutputStream類一樣,InputStream本身也是一個抽象類,必須依靠其子類,如果現在是從檔案中讀取,就用FileInputStream來實現。

觀察FileInputStream類的構造方法:

public FileInputStream(File file)throws FileNotFoundException

讀檔案:

1import java.io.File;2import java.io.FileInputStream;3import java.io.IOException;4import java.io.InputStream;56publicclass Test12 {7publicstaticvoid main(String[] args) throws IOException {8         File f = new File("d:" + File.separator+"test.txt");9         InputStream in=new FileInputStream(f);10byte[] b=newbyte[1024];11int len=in.read(b);12         in.close();13         System.out.println(new String(b,0,len));14     }15 }

但以上方法是有問題的,用不用開闢這麼大的一個位元組陣列,明顯是浪費嘛,我們可以根據檔案的大小來定義位元組陣列的大小,File類中的方法:public long length()

1import java.io.File;2import java.io.FileInputStream;3import java.io.IOException;4import java.io.InputStream;56publicclass Test13 {7publicstaticvoid main(String[] args) throws IOException {8         File f = new File("d:" + File.separator+"test.txt");9         InputStream in=new FileInputStream(f);10byte[] b=newbyte[(int) f.length()];11         in.read(b);12         in.close();13         System.out.println(new String(b));14     }15 }

我們換種方式,一個位元組一個位元組讀入~

1import java.io.File;2import java.io.FileInputStream;3import java.io.IOException;4import java.io.InputStream;56publicclass Test14 {7publicstaticvoid main(String[] args) throws IOException {8         File f = new File("d:" + File.separator+"test.txt");9         InputStream in=new FileInputStream(f);10byte[] b=newbyte[(int) f.length()];11for(int i=0;i<b.length;i++){12             b[i]=(byte) in.read();13         }14         in.close();15         System.out.println(new String(b));16     }17 }

但以上情況只適合知道輸入檔案的大小,不知道的話用如下方法:

1import java.io.File;2import java.io.FileInputStream;3import java.io.IOException;4import java.io.InputStream;56publicclass Test15 {7publicstaticvoid main(String[] args) throws IOException {8         File f = new File("d:" + File.separator+"test.txt");9         InputStream in=new FileInputStream(f);10byte[] b=newbyte[1024];11int temp=0;12int len=0;13while((temp=in.read())!=-1){//-1為檔案讀完的標誌14             b[len]=(byte) temp;15             len++;16         }17         in.close();18         System.out.println(new String(b,0,len));19     }20 }

字元流

在程式中一個字元等於兩個位元組,那麼java提供了ReaderWriter兩個專門操作字元流的類。

字元輸出流:Writer

Writer本身是一個字元流的輸出類,此類的定義如下:

public abstract class Writer extends Object implements AppendableCloseableFlushable

此類本身也是一個抽象類,如果要使用此類,則肯定要使用其子類,此時如果是向檔案中寫入內容,所以應該使用FileWriter的子類。

FileWriter類的構造方法定義如下:

public FileWriter(File file)throws IOException

字元流的操作比位元組流操作好在一點,就是可以直接輸出字串了,不用再像之前那樣進行轉換操作了。

寫檔案:

1import java.io.File;2import java.io.FileWriter;3import java.io.IOException;4import java.io.Writer;56publicclass Test16 {7publicstaticvoid main(String[] args) throws IOException {8         File f = new File("d:" + File.separator+"test.txt");9         Writer out=new FileWriter(f);10         String str="Hello World";11         out.write(str);12         out.close();13     }14 }

在預設情況下再次輸出會覆蓋,追加的方法也是在建構函式上加上追加標記

1import java.io.File;2import java.io.FileWriter;3import java.io.IOException;4import java.io.Writer;56publicclass Test17 {7publicstaticvoid main(String[] args) throws IOException {8         File f = new File("d:" + File.separator+"test.txt");9         Writer out=new FileWriter(f,true);//追加10         String str="\r\nHello World";11         out.write(str);12         out.close();13     }14 }

字元輸入流:Reader

Reader是使用字元的方式從檔案中取出資料,Reader類的定義如下:

public abstract class Reader extends Objects implements ReadableCloseable

Reader本身也是抽象類,如果現在要從檔案中讀取內容,則可以直接使用FileReader子類。

FileReader的構造方法定義如下:

public FileReader(File file)throws FileNotFoundException

以字元陣列的形式讀取出資料:

1import java.io.File;2import java.io.FileReader;3import java.io.IOException;4import java.io.Reader;56publicclass Test18 {7publicstaticvoid main(String[] args) throws IOException {8         File f = new File("d:" + File.separator+"test.txt");9         Reader input=new FileReader(f);10char[] c=newchar[1024];11int len=input.read(c);12         input.close();13         System.out.println(new String(c,0,len));14     }15 }

也可以用迴圈方式,判斷是否讀到底:

1import java.io.File;2import java.io.FileReader;3import java.io.IOException;4import java.io.Reader;56publicclass Test19 {7publicstaticvoid main(String[] args) throws IOException {8         File f = new File("d:" + File.separator+"test.txt");9         Reader input=new FileReader(f);10char[] c=newchar[1024];11int temp=0;12int len=0;13while((temp=input.read())!=-1){14             c[len]=(char) temp;15             len++;16         }17         input.close();18         System.out.println(new String(c,0,len));19     }20 }

位元組流與字元流的區別

位元組流和字元流使用是非常相似的,那麼除了操作程式碼的不同之外,還有哪些不同呢?

位元組流在操作的時候本身是不會用到緩衝區(記憶體)的,是與檔案本身直接操作的,而字元流在操作的時候是使用到緩衝區的

位元組流在操作檔案時,即使不關閉資源(close方法),檔案也能輸出,但是如果字元流不使用close方法的話,則不會輸出任何內容,說明字元流用的是緩衝區,並且可以使用flush方法強制進行重新整理緩衝區,這時才能在不close的情況下輸出內容

那開發中究竟用位元組流好還是用字元流好呢?

在所有的硬碟上儲存檔案或進行傳輸的時候都是以位元組的方法進行的,包括圖片也是按位元組完成,而字元是隻有在記憶體中才會形成的,所以使用位元組的操作是最多的。

如果要java程式實現一個拷貝功能,應該選用位元組流進行操作(可能拷貝的是圖片),並且採用邊讀邊寫的方式(節省記憶體)。

相關推薦

Java基礎位元組字元區別

原文連結:http://blog.csdn.net/zxman660/article/details/7875799 先來看一下流的概念: 在程式中所有的資料都是以流的方式進行傳輸或儲存的,程式需要資料的時候要使用輸入流讀取資料,而當程式需要將一些資料儲存起來的時候

Java基礎執行緒併發機制

前言 在Java中,執行緒是一個很關鍵的名詞,也是很高頻使用的一種資源。那麼它的概念是什麼呢,是如何定義的,用法又有哪些呢?為何說Android裡只有一個主執行緒呢,什麼是工作執行緒呢。執行緒又存在併發,併發機制的原理是什麼。這些內容有些瞭解,有些又不是很清楚,所以有必要通過一篇文章的梳理,弄清

轉載:Java基礎InputStream 、 InputStreamReaderBufferedReader

gen 結果 取字符 sys try eight string font buffer 來源:http://blog.csdn.net/zgljl2012/article/details/47267609 在Java中,上述三個類經常用於處理數據流,下面介紹一下三個類的

java讀取檔案寫入檔案的方式(位元組字元

java讀取檔案和寫入檔案的方式 以位元組為單位讀取檔案 一次讀一個位元組 一次讀多個位元組 以字元為單位讀取檔案 一次讀一個字元 一次讀多個字元 以位元組為單位讀取檔案 以位元

Java:IO之:探究位元組字元

前言---- 本來不想寫前言了,但是寫完,發現寫得太好了,遇到就好好看一看啊!!!! 注:歡迎轉載,轉載請註明來處 目錄 一. 簡單理解什麼是流? 二.位元組輸入流 三.位元組輸出流 四.流的正確關閉方式 五.字元輸入流 六.字元輸出流 七.位元組流和字元流的

Java位元組字元

  對於我們常用的GBK中,英文是佔用1個位元組,中文是2個 對於UTF-8,英文是1個,中文是3個 對於Unicode,英文中文都是2個 Java的流操作分為位元組流和字元流兩種。 1、位元組流 所有的讀操作都繼承自一個公共超類java.io.InputStrea

Java位元組字元

一.位元組流 流分為輸入流和輸出流。 用參照物(程式)來判斷是輸出流還是輸入流。 注意:在用流的時候,結束時要記得關掉流。 位元組流 將文字、圖片、音訊等轉成位元組,進行資料傳輸。 程式——>檔案 輸出流 寫檔案 檔案——>程式 輸入流

萌新學Java之初入門徑八----位元組字元

流 ## 位元組流 * 將文字圖片音訊等檔案 轉成位元組 進行資料傳輸 * * * 輸入流 * 輸出流 * * 參照物(程式) * * 程式 —-> 檔案 輸出流 寫檔案 * 檔案 —-> 程式 輸出

java基礎BufferedReader類(提高字元讀取文字檔案的效率)IO位元組/字元

String nstr=sb.toString().replace("{name}", “ok”).replace("{sex}", “男”).replace("{hobby}", “陶笛”);boolean exists( ) 判斷檔案或目錄是否存在 bool

搞定Java基礎之 i++ ++i 詳解

目  錄: 一、i++ 和 ++i 的基本概念 二、i++ 和 ++i 的實現原理 三、i++ 和 ++i 在使用時的一些坑 3.1、i = i++ 導致的結果“異常” 3.2、多執行緒併發引發的混亂 一、i++ 和 ++i 的基本概念 在幾乎所有的指令式程

Java:位元組字元(輸入輸出

什麼是流 如果想學習Java工程化、高效能及分散式、深入淺出。微服務、Spring,MyBatis,Netty原始碼分析的朋友可以加我的Java高階交流:854630135,群裡有阿里大牛直播講解技術,以及Java大型網際網路技術的視訊免費分享給大家。 流是個抽象的概念,是對輸入輸出裝置的抽象,輸

Java基礎intInteger

Java中存在8種基本資料型別:byte(8位)、short(16位)、int(32位)、long(64位)、float(32位)、double(64位)、char(16位,0x0000~0xffff)、boolean(true/false) java中不存在無符號數字型別,

Java基礎equalshashcode

一、equals equals是Object類的其中一個方法,預設的實現方法為 public boolean equals(Object obj) { return (this == obj); } 可以看到,預設方法僅僅是判斷是否為同一

位元組字元位元組字元的使用哪個多? java 讀寫操作大檔案 BufferedReaderRandomAccessFile

一 首先我們要知道 在程式中所有的資料都是以流的方式進行傳輸或儲存的   而流有兩種 位元組流用來處理位元組或二進位制物件 字元流主要用來處理字元或字串,一個字元佔兩個位元組 而上一篇的java 讀寫操作大檔案 BufferedReader和RandomAccessFile Buf

java位元組字元區別

 流分類: 1.Java的位元組流    InputStream是所有位元組輸入流的祖先,而OutputStream是所有位元組輸出流的祖先。 2.Java的字元流   Reader是所有讀取字串輸入流的祖先,而writer是所有輸出字串的祖先。  InputStrea

Java基礎Json字串轉物件轉List集合操作

to今天發現專案中需要拿到對接系統中傳值的Json,需要轉換成List集合。回顧下Json字串的操作,寫了個測試。 public class JsonToUtil {     private  static final  Logger log = LoggerFactor

Java:IO:探究位元組字元

前言---- 本來不想寫前言了,但是寫完,發現寫得太好了,遇到就好好看一看啊!!!! 注:歡迎轉載,轉載請註明來處 目錄 一. 簡單理解什麼是流? 我是把流理解成一個導管,這個導管連線了硬碟中的某個檔案和程式. 輸入流:輸入資料

java基礎多執行緒匿名內部類lambda建立方式,及多執行緒中的兩個面試題

一、可以用匿名類和lambda兩個種方式建立多執行緒。 1.利用匿名內部類建立多執行緒並開啟。 new Thread() {//建立方式1 public void run() { for(int x=0; x<50; x++) { System.out

Java基礎Jar包結構結構分析操作詳解

一 JAR包結構分析 JAR(Java Archive FIle)Java歸檔檔案,是Java標準的文件格式,是一個或多個Java位元組碼檔案的打包壓縮檔案,採用常見的ZIP壓縮演算法,和ZIP檔案十分類似,可以直接解壓。 JAR檔案主要用來壓縮和釋

java位元組字元操作檔案,指定編碼寫入讀取,遞迴建立上層目錄

java的IO流分兩種流 位元組流 InputStream OutputStream 字元流 Reader Writer 他們都是抽象類 具體實現 位元組流 FileInputStream FileOutputStream 字元流 FileReader FileWriter