java 位元組流與字元流的區別

来源:http://www.cnblogs.com/chuangege/archive/2016/10/26/6001175.html
-Advertisement-
Play Games

位元組流與和字元流的使用非常相似,兩者除了操作代碼上的不同之外,是否還有其他的不同呢?實際上位元組流在操作時本身不會用到緩衝區(記憶體),是文件本身直接操作的,而字元流在操作時使用了緩衝區,通過緩衝區再操作文件,如圖12-6所示。下麵以兩個寫文件的操作為主進行比較,但是在操作時位元組流和字元流的操作完成之後 ...


位元組流與和字元流的使用非常相似,兩者除了操作代碼上的不同之外,是否還有其他的不同呢?

實際上位元組流在操作時本身不會用到緩衝區(記憶體),是文件本身直接操作的,而字元流在操作時使用了緩衝區,通過緩衝區再操作文件,如圖12-6所示。

下麵以兩個寫文件的操作為主進行比較,但是在操作時位元組流和字元流的操作完成之後都不關閉輸出流。

範例:使用位元組流不關閉執行

package org.lxh.demo12.byteiodemo;    
import java.io.File;    
import java.io.FileOutputStream;    
import java.io.OutputStream;    
public class OutputStreamDemo05 {    
public static void main(String[] args) throws Exception {   // 異常拋出,  不處理    
// 第1步:使用File類找到一個文件    
     File f = new File("d:" + File.separator + "test.txt"); // 聲明File  對象    
// 第2步:通過子類實例化父類對象    
     OutputStream out = null;            
// 準備好一個輸出的對象    
     out = new FileOutputStream(f);      
// 通過對象多態性進行實例化    
// 第3步:進行寫操作    
     String str = "Hello World!!!";      
// 準備一個字元串    
     byte b[] = str.getBytes();          
// 字元串轉byte數組    
     out.write(b);                      
// 將內容輸出    
 // 第4步:關閉輸出流    
    // out.close();                  
// 此時沒有關閉    
        }    
    }   

程式運行結果:

此時沒有關閉位元組流操作,但是文件中也依然存在了輸出的內容,證明位元組流是直接操作文件本身的。而下麵繼續使用字元流完成,再觀察效果。

範例:使用字元流不關閉執行

package org.lxh.demo12.chariodemo;    
import java.io.File;    
import java.io.FileWriter;    
import java.io.Writer;    
public class WriterDemo03 {    
    public static void main(String[] args) throws Exception { // 異常拋出,  不處理    
        // 第1步:使用File類找到一個文件    
        File f = new File("d:" + File.separator + "test.txt");// 聲明File 對象    
        // 第2步:通過子類實例化父類對象    
        Writer out = null;                 
// 準備好一個輸出的對象    
        out = new FileWriter(f);            
// 通過對象多態性進行實例化    
        // 第3步:進行寫操作    
        String str = "Hello World!!!";      
// 準備一個字元串    
        out.write(str);                    
// 將內容輸出    
        // 第4步:關閉輸出流    
        // out.close();                   
// 此時沒有關閉    
    }    
}   

程式運行結果:

程式運行後會發現文件中沒有任何內容,這是因為字元流操作時使用了緩衝區,而   在關閉字元流時會強制性地將緩衝區中的內容進行輸出,但是如果程式沒有關閉,則緩衝區中的內容是無法輸出的,所以得出結論:字元流使用了緩衝區,而位元組流沒有使用緩衝區。

提問:什麼叫緩衝區?

在很多地方都碰到緩衝區這個名詞,那麼到底什麼是緩衝區?又有什麼作用呢?

回答:緩衝區可以簡單地理解為一段記憶體區域。

可以簡單地把緩衝區理解為一段特殊的記憶體。

某些情況下,如果一個程式頻繁地操作一個資源(如文件或資料庫),則性能會很低,此時為了提升性能,就可以將一部分數據暫時讀入到記憶體的一塊區域之中,以後直接從此區域中讀取數據即可,因為讀取記憶體速度會比較快,這樣可以提升程式的性能。

在字元流的操作中,所有的字元都是在記憶體中形成的,在輸出前會將所有的內容暫時保存在記憶體之中,所以使用了緩衝區暫存數據。

如果想在不關閉時也可以將字元流的內容全部輸出,則可以使用Writer類中的flush()方法完成。

範例:強制性清空緩衝區

package org.lxh.demo12.chariodemo;    
import java.io.File;    
import java.io.FileWriter;    
import java.io.Writer;    
public class WriterDemo04 {    
    public static void main(String[] args) throws Exception { // 異常拋出不處理    
        // 第1步:使用File類找到一個文件    
        File f = new File("d:" + File.separator + "test.txt");// 聲明File    
對象    
        // 第2步:通過子類實例化父類對象    
        Writer out = null;                   
// 準備好一個輸出的對象    
        out = new FileWriter(f);             
// 通過對象多態性進行實例化    
        // 第3步:進行寫操作    
        String str = "Hello World!!!";      
// 準備一個字元串    
        out.write(str);                    
// 將內容輸出    
        out.flush();                       
// 強制性清空緩衝區中的內容    
        // 第4步:關閉輸出流    
        // out.close();                
// 此時沒有關閉    
    }    
}   

程式運行結果:

此時,文件中已經存在了內容,更進一步證明內容是保存在緩衝區的。這一點在讀者日後的開發中要特別引起註意。

提問:使用位元組流好還是字元流好?

學習完位元組流和字元流的基本操作後,已經大概地明白了操作流程的各個區別,那麼在開發中是使用位元組流好還是字元流好呢?

回答:使用位元組流更好。

在回答之前,先為讀者講解這樣的一個概念,所有的文件在硬碟或在傳輸時都是以位元組的方式進行的,包括圖片等都是按位元組的方式存儲的,而字元是只有在記憶體中才會形成,所以在開發中,位元組流使用較為廣泛。


位元組流與字元流主要的區別是他們的的處理方式

流分類:
1.Java的位元組流
   InputStream是所有位元組輸入流的祖先,而OutputStream是所有位元組輸出流的祖先。
2.Java的字元流
  Reader是所有讀取字元串輸入流的祖先,而writer是所有輸出字元串的祖先。
InputStream,OutputStream,Reader,writer都是抽象類。所以不能直接new 



位元組流是最基本的,所有的InputStream和OutputStream的子類都是,主要用在處理二進位數據,它是按位元組來處理的
但實際中很多的數據是文本,又提出了字元流的概念,它是按虛擬機的encode來處理,也就是要進行字元集的轉化
這兩個之間通過 InputStreamReader,OutputStreamWriter來關聯,實際上是通過byte[]和String來關聯
在實際開發中出現的漢字問題實際上都是在字元流和位元組流之間轉化不統一而造成的

在從位元組流轉化為字元流時,實際上就是byte[]轉化為String時,
public String(byte bytes[], String charsetName)
有一個關鍵的參數字元集編碼,通常我們都省略了,那系統就用操作系統的lang
而在字元流轉化為位元組流時,實際上是String轉化為byte[]時,
byte[]    String.getBytes(String charsetName)
也是一樣的道理

至於java.io中還出現了許多其他的流,按主要是為了提高性能和使用方便,
如BufferedInputStream,PipedInputStream等


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • querystring處理參數的小利器。 下麵是querystring的四個方法。 ①stringify:將一個參數對象序列化為一個字元串 eg: querystring.stringify({name:'jenny',course:['js','node'],from:''}); 輸出:'name ...
  • 一。開發的準備 1.jdk的安裝(window) (1)根據自己的電腦下載對應的jdk,並安裝 (推薦安裝在沒有中文的目錄中)。 網站 http://www.oracle.com/technetwork/cn/java/javase/downloads/jdk7-downloads-1880260. ...
  • 一、AbstractCollection 提供了集合的最大實現 繼承該類,必須實現size()和iterator(),因為該類操作集合都是通過iterator 二、fail-fast策略 該策略在集合框架中多次被應用 一種多線程對同一集合操作的保護措施,確保操作目標沒有被其他線程操作過,與cas思想 ...
  • macOS Sierra 已經幫我們預裝了 Ruby、PHP(5.6)、Perl、Python 等常用的腳本語言,以及 Apache HTTP 伺服器。由於 nginx 既能作為 HTTP 伺服器也能作為反向代理伺服器,且配置簡單,這裡我們用 nginx 代替 Apache 作為我們預設的 HTTP ...
  • 最近自學了一下NodeJS,然後做了一個小demo,實現歌曲的添加、修改、播放和刪除的功能,其中自然要實現音樂和圖片的上傳功能。於是上網查找資料,找到了一個formidable插件,該插件可以很好的實現文件的上傳功能。該小demo用到了MySQL資料庫,所有的數據都存放到了資料庫中。下麵簡單說一些如... ...
  • 可以在Index.php文件下 <?php 之前添加<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> ...
  • REST是一種架構風格,其核心是面向資源,REST專門針對網路應用設計和開發方式,以降低開發的複雜性,提高系統的可伸縮性。REST提出設計概念和準則為: REST是一種架構風格,其核心是面向資源,REST專門針對網路應用設計和開發方式,以降低開發的複雜性,提高系統的可伸縮性。REST提出設計概念和準 ...
  • 監聽器的原理: 被監聽對象→對象擁有的事件→捕獲到事件變化→監聽器捕捉事件→監聽器處理該事件 Web伺服器上有4個範圍,拋開page範圍,還有request範圍,session範圍,application範圍。這些範圍的對象什麼時候創建,什麼時候銷毀,什麼時候往範圍中存放了數據,什麼時候替換了存放的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...