1. 程式人生 > >IO流詳解

IO流詳解

轉自:點選開啟連結http://www.2cto.com/kf/201312/262036.html

流的概念和作用

學習Java IO,不得不提到的就是JavaIO流。

流是一組有順序的,有起點和終點的位元組集合,是對資料傳輸的總稱或抽象。即資料在兩裝置間的傳輸稱為流,流的本質是資料傳輸,根據資料傳輸特性將流抽象為各種類,方便更直觀的進行資料操作。

IO流的分類

根據處理資料型別的不同分為:字元流和位元組流

根據資料流向不同分為:輸入流和輸出流

字元流和位元組流

字元流的由來: 因為資料編碼的不同,而有了對字元進行高效操作的流物件。本質其實就是基於位元組流讀取時,去查了指定的碼錶。位元組流和字元流的區別:

(1)讀寫單位不同:位元組流以位元組(8bit)為單位,字元流以字元為單位,根據碼錶對映字元,一次可能讀多個位元組。

(2)處理物件不同:位元組流能處理所有型別的資料(如圖片、avi等),而字元流只能處理字元型別的資料。

(3)位元組流在操作的時候本身是不會用到緩衝區的,是檔案本身的直接操作的;而字元流在操作的時候下後是會用到緩衝區的,是通過緩衝區來操作檔案,我們將在下面驗證這一點。

結論:優先選用位元組流。首先因為硬碟上的所有檔案都是以位元組的形式進行傳輸或者儲存的,包括圖片等內容。但是字元只是在記憶體中才會形成的,所以在開發中,位元組流使用廣泛。

輸入流和輸出流

對輸入流只能進行讀操作,對輸出流只能進行寫操作,程式中需要根據待傳輸資料的不同特性而使用不同的流。

Java流操作有關的類或介面:

\載入中...

Java流類圖結構:

<喎�"/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+IDxpbWcgc3JjPQ=="/uploadfile/Collfiles/20131204/20131203211221140.jpg" alt="\">

Java IO流物件

1. 輸入位元組流InputStream

定義和結構說明:

從輸入位元組流的繼承圖可以看出:

InputStream 是所有的輸入位元組流的父類,它是一個抽象類。

ByteArrayInputStream、StringBufferInputStream、FileInputStream 是三種基本的介質流,它們分別從Byte 陣列、StringBuffer、和本地檔案中讀取資料。PipedInputStream 是從與其它執行緒共用的管道中讀取資料,與Piped 相關的知識後續單獨介紹。

ObjectInputStream 和所有FilterInputStream的子類都是裝飾流(裝飾器模式的主角)。意思是FileInputStream類可以通過一個String路徑名建立一個物件,FileInputStream(String name)。而DataInputStream必須裝飾一個類才能返回一個物件,DataInputStream(InputStream in)。如下圖示:

\載入中...

例項操作演示:

【案例 】讀取檔案內容

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 /** * 位元組流 * 讀檔案內容 * */ import java.io.*; class hello{ public static void main(String[] args) throws IOException { String fileName="D:"+File.separator+"hello.txt"; File f=new File(fileName); InputStream in=new FileInputStream(f); byte[] b=new byte[1024]; in.read(b); in.close(); System.out.println(new String(b)); } }

注意:該示例中由於b位元組陣列長度為1024,如果檔案較小,則會有大量填充空格。我們可以利用in.read(b);的返回值來設計程式,如下案例:

【案例】讀取檔案內容

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 /** * 位元組流 * 讀檔案內容 * */ import java.io.*; class hello{ public static void main(String[] args) throws IOException { String fileName="D:"+File.separator+"hello.txt"; File f=new File(fileName); InputStream in=new FileInputStream(f); byte[] b=new byte[1024]; int len=in.read(b); in.close(); System.out.println("讀入長度為:"+len); System.out.println(new String(b,0,len)); } }

注意:觀察上面的例子可以看出,我們預先申請了一個指定大小的空間,但是有時候這個空間可能太小,有時候可能太大,我們需要準確的大小,這樣節省空間,那麼我們可以這樣做:

【案例】讀取檔案內容

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 /** * 位元組流 * 讀檔案內容,節省空間 * */ import java.io.*; class hello{ public static void main(String[] args) throws IOException { String fileName="D:"+File.separator+"hello.txt"; File f=new File(fileName); InputStream in=new FileInputStream(f); byte[] b=new byte[(int)f.length()]; in.read(b); System.out.println("檔案長度為:"+f.length()); in.close(); System.out.println(new String(b)); } }

【案例】逐位元組讀

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 /** * 位元組流 * 讀檔案內容,節省空間 * */ import java.io.*; class hello{ public static void main(String[] args) throws IOException { String fileName="D:"+File.separator+"hello.txt"; File f=new File(fileName); InputStream in=new FileInputStream(f); byte[] b=new byte[(int)f.length()]; for (int i = 0; i < b.length; i++) { b[i]=(byte)in.read(); } in.close(); System.out.println(new String(b)); } }

注意:上面的幾個例子都是在知道檔案的內容多大,然後才展開的,有時候我們不知道檔案有多大,這種情況下,我們需要判斷是否獨到檔案的末尾。

【案例】位元組流讀取檔案

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 /** * 位元組流 *讀檔案 * */ import java.io.*; class hello{ public static void main(String[] args) throws IOException { String fileName="D:"+File.separator+"hello.txt"; File f=new File(fileName); InputStream in=new FileInputStream(f); byte[] b=new byte[1024]; int count =0; int temp=0; while((temp=in.read())!=(-1)){ b[count++]=(byte)temp; } in.close(); System.out.println(new String(b)); } }

注意:當讀到檔案末尾的時候會返回-1.正常情況下是不會返回-1的。

【案例】DataInputStream類

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class DataOutputStreamDemo{ public static void main(String[] args) throws IOException{ File file = new File("d:" + File.separator +"hello.txt"); DataInputStream input = new DataInputStream(new FileInputStream(file)); char[] ch = new char[10]; int count = 0; char temp; while((temp = input.readChar()) != 'C'){ ch[count++] = temp; } System.out.println(ch); } }

【案例】PushBackInputStream回退流操作

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.PushbackInputStream; /** * 回退流操作 * */ public class PushBackInputStreamDemo{ public static void main(String[] args) throwsIOException{ String str = "hello,rollenholt"; PushbackInputStream push = null; ByteArrayInputStream bat = null; bat = new ByteArrayInputStream(str.getBytes()); push = new PushbackInputStream(bat); int temp = 0; while((temp = push.read()) != -1){ if(temp == ','){ push.unread(temp); temp = push.read(); System.out.print("(回退" +(char) temp + ") "); }else{ System.out.print((char) temp); } } } }

2. 輸出位元組流OutputStream

定義和結構說明:

IO 中輸出位元組流的繼承圖可見上圖,可以看出:

OutputStream 是所有的輸出位元組流的父類,它是一個抽象類。

ByteArrayOutputStream、FileOutputStream是兩種基本的介質流,它們分別向Byte 陣列、和本地檔案中寫入資料。PipedOutputStream 是向與其它執行緒共用的管道中寫入資料,

ObjectOutputStream 和所有FilterOutputStream的子類都是裝飾流。具體例子跟InputStream是對應的。

例項操作演示:

【案例】向檔案中寫入字串

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 /** * 位元組流 * 向檔案中寫入字串 * */ import java.io.*; class hello{ public static void main(String[] args) throws IOException { String fileName="D:"+File.separator+"hello.txt"; File f=new File(fileName); OutputStream out =new FileOutputStream(f); String str="Hello World"; byte[] b=str.getBytes(); out.write(b); out.close(); } }

你也可以一個位元組一個位元組的寫入檔案:

【案例】逐位元組寫入檔案

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 /** * 位元組流 * 向檔案中一個位元組一個位元組的寫入字串 * */ import java.io.*; class hello{ public static void main(String[] args) throws IOException { String fileName="D:"+File.separator+"hello.txt"; File f=new File(fileName); OutputStream out =new FileOutputStream(f); String str="Hello World!!"; byte[] b=str.getBytes(); for (int i = 0; i < b.length; i++) { out.write(b[i]); } out.close(); } }

【案例】向檔案中追加新內容

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 /** * 位元組流 * 向檔案中追加新內容: * */ import java.io.*; class hello{ public static void main(String[] args) throws IOException { String fileName="D:"+File.separator+"hello.txt"; File f=new File(fileName); OutputStream out =new FileOutputStream(f,true);//true表示追加模式,否則為覆蓋 String str="Rollen"; //String str="\r\nRollen"; 可以換行 byte[] b=str.getBytes(); for (int i = 0; i < b.length; i++) { out.write(b[i]); } out.close(); } }

【案例】複製檔案

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 /** * 檔案的複製 * */ import java.io.*; class hello{ public static void main(String[] args) throws IOException { if(args.length!=2){ System.out.println("命令列引數輸入有誤,請檢查"); System.exit(1); } File file1=new File(args[0]); File file2=new File(args[1]); if(!file1.exists()){ System.out.println("被複制的檔案不存在"); System.exit(1); } InputStream input=new FileInputStream(file1); OutputStream output=new FileOutputStream(file2); if((input!=null)&&(output!=null)){ int temp=0; while((temp=input.read())!=(-1)){ output.write(temp); } } input.close(); output.close(); } }

【案例】使用記憶體操作流將一個大寫字母轉化為小寫字母

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 /** * 使用記憶體操作流將一個大寫字母轉化為小寫字母 * */ import java.io.*; class hello{ public static void main(String[] args) throws IOException { String str="ROLLENHOLT"; ByteArrayInputStream input=new ByteArrayInputStream(str.getBytes()); ByteArrayOutputStream output=new ByteArrayOutputStream(); int temp=0; while((temp=input.read())!=-1){ char ch=(char)temp; output.write(Character.toLowerCase(ch)); } String outStr=output.toString(); input.close(); output.close(); System.out.println(outStr); } }

【案例】驗證管道流:程序間通訊

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 /** * 驗證管道流 * */ import java.io.*; /** * 訊息傳送類 * */ class Send implements Runnable{ private PipedOutputStream out=null; public Send() { out=new PipedOutputStream(); } public PipedOutputStream getOut(){ return this.out; } public void run(){ String message="hello , Rollen"; try{ out.write(message.getBytes()); }catch (Exception e) { e.printStackTrace(); }try{ out.close(); }catch (Exception e) { e.printStackTrace(); } } } /** * 接受訊息類

相關推薦

Java常用IO

cat exce getpath tst IV trac AC output har 一、流的分類: 按照數據流向的不同:輸入流 輸出流 按照處理數據的單位的不同:字節流 字符流(處理的文本文件) 按照角色的不同:節點流(直接作用於文件的) 處理流 二、IO的體系

Java IO

一、IO流概述 概述: IO流簡單來說就是Input和Output流,IO流主要是用來處理裝置之間的資料傳輸,Java對於資料的操作都是通過流實現,而java用於操作流的物件都在IO包中。 分類: 按操作資料分為:位元

【Java基礎知識】IO

1.概念 (1)io流用來處理裝置之間的資料傳輸; (2)Java對資料的操作的操作是通過流的方式; (3)Java用於操作流的物件都在IO包; (4)io流按操作資料分為兩種:位元組流和字元流; (5)io流按流向分為:輸入流、輸出流 Java流類

C#IO

17.3.3 流的文字讀寫器 StreamReader和StreamWriter主要用於以文字方式對流進行讀寫操作,它們以位元組流為操作物件,並支援不同的編碼格式。 StreamReader和StreamWriter通常成對使用,它們的建構函式形式也一一對應。可以通過指定檔名或指定另一個流物件來建立Strea

IO

轉自:點選開啟連結http://www.2cto.com/kf/201312/262036.html 流的概念和作用 學習Java IO,不得不提到的就是JavaIO流。 流是一組有順序的,有起點和終點的位元組集合,是對資料傳輸的總稱或抽象。即資料在兩裝置間的傳輸稱

java IO——緩衝

本篇部落格學習一下內容 緩衝流概述 構造方法 構造方法 構造方法 構造方法 總結 緩衝流概述 緩衝流是對檔案流處理的一種流,它本身並不具備 IO 功能,只是在別的流上加上緩衝提高了效率,當對檔案或其他目標頻繁讀寫或操作效率低,效能差。這時使

Java實現檔案寫入——IO(輸入輸出

輸入輸出的重要性:      輸入和輸出功能是Java對程式處理資料能力的提高,Java以流的形式處理資料。流是一組有序的資料序列,根據操作的型別,分為輸入流和輸出流。      程式從輸入流讀取資料,向輸出流寫入資料。Java是面向物件的程式語言,每一個數

深入理解JAVA I/O系列三:字符

buffer 情況 二進制文件 感到 復制代碼 使用範圍 轉換 fileread 方式 字符流為何存在 既然字節流提供了能夠處理任何類型的輸入/輸出操作的功能,那為什麽還要存在字符流呢?容我慢慢道來,字節流不能直接操作Unicode字符,因為一個字符有兩個字節,字節流一次只

10.5-全棧Java筆記:常見(三)

java上節我們講到「Java中常用流:緩沖流」,本節我們學習數據流和對象流~ 數據流數據流將“基本數據類型變量”作為數據源,從而允許程序以與機器無關方式從底層輸入輸出流中操作java基本數據類型。 DataInputStream和DataOutputStream提供了可以存取與機器無關的所有Java基礎類

C++: I/O(三)——串

name namespace 轉換 pac end 成員 col logs nbsp 一、串流 串流類是 ios 中的派生類 C++的串流對象可以連接string對象或字符串 串流提取數據時對字符串按變量類型解釋;插入數據時把類型 數據轉換成字符串 串流I/O具有格式化功能

python--->io模式(適合零基礎)

python在此感謝前輩們指導,此處是我自己的理解,部分圖片和段落來源於http://www.cnblogs.com/alex3714/articles/5876749.html http://www.cnblogs.com/Anker/p/3254269.html 如果在學習過程中遇到了問題,請咨詢:277

Java輸入輸出2

output put 輸入流 基類 inpu reader 讀取 輸入輸出 NPU InputStream/Reader:所有輸入流的基類,只能從中讀取數據; OutputStream/Writer:所有輸出流的基類,只能向其寫入數據。Java輸入輸出流詳解2

java I/O

practice bubuko put bre 技術分享 writer 多媒體 buffered args 概況 I/O流主要分為二大類別:字符流和字節流。 字節流(基本流) 1、字節輸入流 類名:FileInputStream 特點:讀(對文件進行讀取操作)

IO模型及應用

邊緣 會有 通知機制 子進程 sele lex ons 中一 消息通知 如何閱讀這篇文章順序 1.1:了解同步異步和阻塞非阻塞 1.11: 同步異步 1.12:阻塞非阻塞 1.2:了解一次read操作需要的步驟 1.3:五種模型 1.1:I/O模

4種常見IO模式

IO模式 本文討論的背景是Linux環境下的網路IO。 對於一次IO訪問,資料會先被拷貝到作業系統核心的緩衝區中,然後再從作業系統核心的緩衝區拷貝到應用程式的地址空間。 所以,當發生一個IO操作時,它會經歷兩個階段:1. 等待資料準備2. 將資料從核心拷貝到程序中 對於兩個階段,li

海思3518EV200 SDK中獲取和儲存H.264碼

1 /****************************************** 2 step 2: Start to get streams of each channel. 3 ************************************

Java8--Stream 並行

簡介 並行流就是把一個內容分成多個數據塊,並用不同的執行緒分別處理每個資料塊的流。序列流則相反,並行流的底層其實就是ForkJoin框架的一個實現。 java.util.Collection < E >新添加了兩個預設方法 default Stre

PTAL1-020 帥到沒朋友(20 分)及其IO效率

當芸芸眾生忙著在朋友圈中發照片的時候,總有一些人因為太帥而沒有朋友。本題就要求你找出那些帥到沒有朋友的人。輸入格式:輸入第一行給出一個正整數N(<=100),是已知朋友圈的個數;隨後N行,每行首先給出一個正整數K(<=1000),為朋友圈中的人數,然後列出一個朋友

網路

network-flows,網路流,傳說中的省選演算法 先推薦一個講網路流思路的網站: https://www.cnblogs.com/ZJUT-jiangnan/p/3632525.html 網路流有兩種寫法,dinic和sap(isap) 本人太弱了,只會dinic 目的

Docker run執行(以volume,network和libcontainer為線索)

通常我們都習慣了使用Docker run來執行一個Docker容器,那麼在我們執行Docker run之後,Docker到底都做了什麼工作呢?本文通過追蹤Docker run(Docker 1.9版本)的執行流程,藉由對volume,network和libcon