IO流


IO/輸入與輸出

  • File 
  • RandomAccessFile
  • 各種節點流類
  • 字符編碼
  • 各種過濾流與包裝類
  • IO類的相關應用

File

  • File類是IO包中唯一代表磁盤文件本身信息類,而不是文件中的內容
  • File類定義了一些與平臺無關的方法來操作文件,例如:創建、刪除文件和重命名文件。
  • Java中的目錄被當作是一種特殊的文件使用,list方法可以返回目錄的所有子目錄和文件名。
  • Unix下的路徑分隔符爲(/,Dos下的路徑分隔符爲(\),java可以正確的處理UnixDos路徑的分隔符。

   編程舉例:判斷某個文件是否存在,存在則刪除,不存在則創建

package blackhouse.advanced;

import java.io.*;

public class FileTest
{
	public static void main(String[] args)
	{
		File f = new File("1.txt");
		if (f.exists())
		{			f.delete();
		} else
		{	try
			{	f.createNewFile();
			} catch (IOException e)	{e.printStackTrace();}
		}
		System.out.println("File name:" + f.getName());
		System.out.println("File path:" + f.getPath());
		System.out.println("File abs path:" + f.getAbsolutePath());
		System.out.println("File Parent:" + f.getParent());
		System.out.println(f.exists() ? "exist" : "not exist");
		System.out.println(f.canRead() ? "read" : "not read");
		System.out.println(f.isDirectory() ? "directory" : "not directory");
	}
}

RandomAccessFile 

  • RandomAccessFile類提供了衆多的文件訪問方法
  • RandomAccessFile類支持“隨機訪問”方式。
  • RandomAccessFile類在隨機(相對順序而言)讀寫等長記錄格式文件時有很大的優勢。
  • RandomAccessFile類僅限於操作文件,不能訪問其他的IO設備,如網絡,內存映像等。
  • 兩種構造方法:
  •         new RandomAccessFile(f,"rw");//讀寫方式
  •         new RandomAccessFile(f,"r");//只讀方式

編程實例:往文件中寫入三名員工的信息,每個員工含有姓名和年齡兩個字段,然後安裝第二名、第一名、第三名的先後順序讀出員工的信息。

字節流

  • InputStream OutputStream
  • FileInputStreamFileOutputStream
  • ReaderWriter
  • PipedInputStreamPipedOutputStream
  • ByteArrayInputStreamByteArrayOutputStream
  • 總是代碼的複用性
  • 理解流的概念

理解流的概念

  • 流是字節序列的抽象概念。
  • 文件是數據的靜態存儲形式,而流是指數據傳輸時的形態。
  • 流類分爲兩個大類:節點流類和過濾流類(也叫處理流)

InputStream

程序可以從中連續讀取字節的對象叫輸入流,在java中,用InputStream類中描述所有輸入流的抽象概念

InputStream類的方法

  • int read()
  • Int read(byte[] b)
  • Int read(byte[] b,int off,int len)
  • long ship(long n)
  • int availble()
  • void mark(int readlimit)
  • void reset()
  • Boolean markSupported()
  • void close()

有了垃圾回收器,爲什麼還要調用close方法?

      計算機操作系統所產生的那些東西叫資源,流就是操作系統產生的資源,當程序產生IO流對象的同時,也會創建一個叫流的東西,這個時候在計算機內存裏面其實產生了兩個東西,一個是java程序的類實例對象,一個是系統本身產生的某種資源,java垃圾回收器只會回收java程序產生的類實例對象,不對回收系統本身產生的資源,所以我們程序自己調用流對象的close()方法去通知系統去釋放這個對象所表示的流資源。

OutputStream

程序可以向其中連續寫入字節的對象叫輸出流,在java中,用OutputStream類來描述所有輸出流的抽象概念。

OutputStream類的方法

  • void write(int b)
  • void write(byte[] b)
  • void write(byte[] b,int off,int len)
  • void flush()
  • void close()

        一個關於IO緩衝區的刻骨銘心的經歷!(緩衝區!回憶)

PipedInputStreamPipedOutputStream

  • PipedInputStream類與PipedOutputStream類用於在應用程序中的創建管道通信。
  • PipedInputStreamPipedOutputStream類的編程實例
  • PipedWriterPipedReader
  • 使用管道流類,可以實現各個程序模塊之間的鬆耦合通信。

ByteArrayInputStreamByteArrayOutputStream

  • ByteArrayInputStreamByteArrayOutputStream,用於以IO流的方式來完成對字節數組內容的讀寫,來支持類似內存虛擬文件或者內存映像文件的功能。
  • ByteArrayInputStream的兩個構造方法:
  •          ByteArrayInputStream(byte[] buf)
  •          ByteArrayInputStream(byte[] buf,int offset,int length)  
  • ByteArrayOutputStream的兩個構造函數:
  •          ByteArrayOutputStream()
  •          ByteArrayOutputStream(int)
  • StringReader類和StringWriter類來以字符IO流的方式處理字符串

重視IO程序代碼的複用

  • System.in連接到鍵盤,是InputStream類型的實例對象。System.out連接到顯示器,是PrintStream類的實例對象。
  • 不管各種底層屋裏設備用什麼方式實現數據的終止點,InputStreamread方法總是返回-1來表示輸入流的結束。
  • windows下,按下組合鍵ctrl+z可以產生輸入流的結束標記,在linux下,則是按下ctrl+D組合鍵。
package blackhouse.advanced.ByteArrayTest;

import java.io.*;

public class ByteArrayTest
{
	public static void main(String[] args)
	{
           String tmp = "abcdefghijklmopqrst";
           byte[] src = tmp.getBytes();
           ByteArrayInputStream input = new ByteArrayInputStream(src);
           ByteArrayOutputStream output = new ByteArrayOutputStream();
           transform(input, output);
           byte[] result = output.toByteArray();
           System.out.println(new String(result));
           
           transform(System.in, System.out);
	}

	public static void transform(InputStream in, OutputStream out)
	{
		int ch = 0;
		try
		{
			while ((ch = in.read()) != -1)
			{
				int upperCh = Character.toUpperCase(ch);
				out.write(upperCh);
			}
		} catch (IOException e)
		{
		 			e.printStackTrace();
		}
	}
}


建議:要編程從鍵盤上連續讀取一大段數據時,應儘量將讀取數據的過程放在函數中完成,使用-1來作爲鍵盤輸入的結束點。在該函數中編寫的程序代碼不應該使用System.in讀取數據,而是用一個InputStream類型的形式參數對象來讀取數據,然後將System.in作爲實參傳遞給InputStream類型的形式參數來調用該函數。

包裝類的概念與作用

  • 通過FileOutputStream對象將一個浮點小數寫入到文件中,你感覺有點困難吧?能否通過FileOutputStream對象直接將一個整數寫入到文件呢?(writeint b)寫入最低字節,用這個方法寫入整數也是困難的)
  • 假如有個DataOutputStream類提供了王各種輸出流對象中寫入各種類型的數據(當然包括浮點小數)的方法。你現在所要做的工作就是:傳遞一個FileOutputStream輸出流對象給DataOutputStream實例對象和調用DataOutputStream實例對象的寫入浮點小數的方法。

BufferedInputStreamBufferedOutputStream

  • 緩衝流爲IO增加了內存緩衝區,增加緩衝區有兩個基本目的:
  •           ---允許java程序依次不只操作一個字節,這樣提高了程序的性能。
  •           ---由於有了緩衝區,使得在流上執行skipmarkreset方法都成爲可能。
  • BufferedInputStreamBufferedOutputStreamjava提供的兩個緩衝區包裝類,不管底層系統是否使用了緩衝區,這兩個類在自己的實例對象中創建緩衝區。想想這種緩衝區與底層系統提供的緩衝區的區別。(底層系統提供的緩衝區直接與目標系統交換數據,而在包裝類中需要調用那個輸出流對象將目標數據從對象緩衝區中寫入到目標設備,底層系統緩衝區是一次讀入或者寫入大量數據,)

DataInputStreamDataOutputStream

  • DataOutputStream類提供了三個寫入字符串的方法:
  •       -write Bytes(String s)
  •       -writeChars(String s)
  •       -writeUTF(String s)
  • 爲什麼DataInputStream類中有一個readUTF方法,而沒有"readBytes""readChars"方法呢?

PrintStream

  • PrintStream類提供了一系列得printprintln方法,可以將基本數據類型的數據格式化成字符串輸出。
  • PrintStream對用的PrintWrite類,即使遇到了文本換行符標識符(\n),PintWriter類也不會自動清空緩衝區。
  • PrintWriterprintln方法能根據操作系統的不同而生成相應的文本換行符。Windows下是“\r\n”,而Linux下的文本換行符是"\n".

ObjectInputStreamObjectOutputStream

  • 用於從底層輸入流中讀取對象類型的數據和將對象類型的數據寫入到底層輸出流
  • 所讀寫的對象必須實現了Serializable接口,對象中的transientstatic類型的成員變量不會被讀取和寫入。

字節流與字符流的轉換

  • InputStreamReaderOutputStreamWriter,用於將字節流轉換成字符流來讀寫兩個類,InputStreamReader可以將一個字節流中的字節解碼成字符後讀取,OutputStreamWriter將字符編碼成字節後寫入到一個字節流中。
  • 避免頻繁的在字符與字節間進行轉換,最好不要直接使用InputStreamReaderOutputStreamWrtiter,儘量使用包裝類BufferedWriterBufferedReader類包裝。

Java程序與其他進程的數據通信

  • java中可以用Process類的實例對象來表示子進程,子進程的標準輸入和輸出不再連接到鍵盤和顯示器,而是以管道流的形式連接到父進程的一個輸出流和輸入流對象上。
  • 調用Process類的getOutputStreamgetInputStream方法可以獲得連接到子進程的輸出流和輸入流對象。
  • Decorator設計模式
  • 在程序中用一個對象(the Decorators)包裝另外的一個對象,這是一種被稱爲Decorator的設計模式。


發佈了25 篇原創文章 · 獲贊 21 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章