国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Java IO(一)

2019-11-08 01:54:58
字體:
來源:轉載
供稿:網友

一、流的概念

流(Stream)的概念源自UNIX中管道的概念,管道是一條不間斷的字節流,用來實現程序或進程之間的通信。一個流必有源端和目的端(可以是內存、磁盤文件等。)流的源端和目的端可以簡單的看成字節的生產者和消費者。


二、流的分類

根據讀寫位置流分為:

結點流:接從指定的位置(如磁盤文件或內存區域)讀或寫 過濾器:輸入流往往是以其它輸入流作為它的輸入源,經過過濾或處理后再以新的輸入流的形式提供給用戶,輸出流的原理也類似。

根據流的方向分為:

輸入流:用戶可以從輸入流中讀取信息 ,但是不能往里寫信息。輸出流:用戶可以往里寫信息,但是不能從中讀出信息。

根據操作對象的類型是字符還是字節分為兩類:

字節流字符流

Java IO流的繼承結構圖如下: 這里寫圖片描述

三、常用流的詳解

文件操作類:File

在講解流之前,先講解一下之后和流操作緊密相關的文件操作類File類 File類是一個與文件本身操作相關的類——文件的創建、刪除、重命名、取得文件大小和修改日期等。


File類中常用的構造方法和操作方法

No. 方法 類型 描述
1 public File(String pathName) 構造 給定一個要操作文件的完整路徑
2 public boolean exists() 普通 判定給定路徑是否存在
3 public File getParentFile() 普通 找到一個指定路徑的父路徑
4 public boolean mkdirs() 普通 創建指定目錄
5 public boolean createNewFile() 普通 創建文件
6 public boolean delete() 普通 刪除文件
7 public boolean isDirectory() 普通 判斷給定路徑是否是文件夾
8 public boolean isFile() 普通 判斷給定路徑是否是文件
9 public boolean isHidden() 普通 判斷是否隱藏
10 public boolean renameTo(File dest) 普通 為文件重命名
11 public long lastModified() 普通 文件的最后一次修改時間
12 public long length() 普通 取得文件的大小
13 public String getName() 普通 取得文件名稱
14 public [] File listFiles() 普通 將目錄中的文件以File對象數組的方式返回

代碼示例

import java.util.Date;import java.text.SimpleDateFormat;import java.io.File;public class TestDemo{ public static void main(String [] args)throws Exception{ File file = new File("/home/linyimin/DaSi/java/demo.txt"); // 如果文件存在,獲取并輸出文件信息 if(file.exists()){ getInfo(file); } // 如果不存在,先判斷文件的父路徑是否存在,不存在先創建目錄在創建文件,否則直接創建文件 else if(file.getParentFile().exists()){ // 創建文件 file.createNewFile(); // 獲取文件信息 getInfo(file); } else{ // 創建目錄 file.getParentFile().mkdirs(); // 創建文件 file.createNewFile(); // 獲取文件信息 getInfo(file); } // 為文件重命名,并取得重命名后的文件信息 File f = new File("/home/linyimin/DaSi/java/TestDemo.txt"); file.renameTo(f); File newFile = new File("/home/linyimin/DaSi/java/TestDemo.txt"); System.out.

字節流

所有的字節輸入流都直接或間接繼承自InputStream抽象類,輸入流作為數據的來源,我們可以通過輸入流的read方法讀取字節數據;

所有的輸出流都直接或間接繼承自OutputStream抽象類,輸出流接收數據,可以通過write方法寫入字節數據。

對于InputStream、OutputStream類而言,本身定義的是一個抽象類(abstract class),按照抽象類的使用原則來講,需要定義抽象類的子類,根據功能的不同,使用不同的子類完成。按照面向對象的開發原則,子類要為抽象類進行對象的實例化,而后調用的方法以父類中定義的方法為主,方法的具體實現由實例化這個父類的子類完成的。所以對于子類用戶最關心的是構造方法下面主要講解幾種常用的IO操作和其對應定義的子類。

文件操作:FileInputStream & FileOutputStream

程序通過FileInputStream能夠將文件作為數據源,讀取文件中的流,通過File對象或文件路徑等初始化,在其構造函數中,如果傳入的File對象(或與其相對應的文件路徑所表示的File對象)不存在或是一個目錄而不是文件或者由于其他原因無法打開讀取數據,都會導致在初始化階段導致拋出FileNotFoundException異常;
程序可以通過FileOutputStream向文件中寫入數據,也需要通過File對象或文件路徑對其初始化,如同FileInputStream ,如果傳入的File對象(或與其相對應的文件路徑所表示的File對象)是一個目錄而不是文件或者由于其他原因無法創建該文件寫入數據,都會導致在初始化階段拋出FileNotFoundException異常

文件操作流的常用方法

類名稱 No. 方法名稱 類型 描述
FileInputStream 1 public FileInputStream(File file) 構造 實例化FileInputStream,用于從指定文件中讀取數據
FileInputStream 2 public FileInputStream(Stirng name) 構造 實例化FileInputStream,用于從指定文件路徑中讀取數據
InputStream 3 public void close() 普通 關閉輸入流
InputStream 4 public int read() 普通 從指定輸入流中讀取一個字節數據
InputStream 5 public int read(byte [] data) 普通 從指定流中讀取多個字節
InputStream 6 public int read(byte [] data, int off, int len) 普通 從指定流中讀取指定多個字節
FileOutputStream 7 public FileOutputStream(File file) 構造方法 實例化FileOuputStream,用于新建數據
FileOutputStream 8 public FileOutputStream(File file,boolean append) 構造方法 實例化FileOutputStream,用于追加數據
OutputStream 9 public void close() 普通 關閉輸出流
OutputStream 10 public abstract void write(int b) 普通 向文件輸出單個字節
OutputStream 11 public void write(byte [] b) 普通 向文件輸出一組字節數據
OutputStream 12 public void write(byte [] b, int off, int len) 普通 向文件輸出部分字節數據

代碼示例

import java.io.File;import java.io.OutputStream;import java.io.InputStream;import java.io.FileInputStream;import java.io.FileOutputStream;public class TestDemo{ public static void main(String [] args)throws Exception{ // 指定操作文件 File fileOut = new File("/home/linyimin/DaSi/java/OutputStream.txt"); File fileIn = new File("/home/linyimin/DaSi/java/InputStream.txt"); // 實例化FileOutputStream,向文件添加數據 OutputStream out = new FileOutputStream(fileOut); // 實例化FileInputStream,從文件中讀取數據 InputStream in = new FileInputStream(fileIn); String str = "Hello World."; // 將字符串轉換稱字節數組 byte [] data = str.getBytes(); // 向文件中寫如數據 out.write(data); // 從文件中讀取數據并輸出 int len = 0; byte [] temp = new byte[1024]; while(len != -1){ len = in.read(temp); if(len != -1){ System.out.println(new String(temp, 0, len)); } } // 關閉輸出流 out.close(); // 關閉輸入流 in.close(); }}

在以上的例子中,通過FileInputStream的read()方法從/home/linyimin/DaSi/java/InputStream.txt文件中讀取信息,通過FileOutputStream的write()方法向/home/linyimin/DaSi/java/InputStream.txt文件寫入“Hello World.”。在此操作中如果InputStream.txt已經存在,會先清空內容在寫入信息,如果不存在,會自動創建InputStream.txt文件后在寫入數據。如果希望在已存在的文件之后添加數據,應使用public FileOutputStream(fileOut,true)構造方法進行實例化對象,表示向已有文件中追加寫入數據而不是覆蓋已有數據。


內存操作:ByteArrayInputStream & ByteArrayOutputStream

在某個操作需要發生IO操作,但又不希望有一些臨時文件產生,可以使用內存操作流完成,即以內存為操作的終端,以發生IO操作關系。用于以IO流的方式來完成對字節數組內容的讀寫,來支持類似內存虛擬文件或者內存映射文件的讀寫。

ByteArrayInputStream:字節數組輸入流,繼承自InputStream,它會在內存中創建一個字節數組緩沖區,實例化后的字節數組會保存在此緩沖區中。也就是使用一個字節數組當中所有的數據作為數據源,程序可以像輸入流方式一樣讀取字節,可以看作一個虛擬文件,用文件的方式讀取里面的數據。ByteArrayOutputStream:字節數組輸出流,繼承自OutputStream,是與ByteArrayInputStream相對應的輸出流。此類實現一個字節輸出流,數據被寫入一個byte字節數組。緩沖區會隨著數據的不斷寫入而自動增長。

內存操作類的常用方法

類名稱 No. 方法 類型 描述
ByteArrayInputStream 1 public ByteArrayInputStream(byte [] buf) 構造 將字節流轉換稱輸入流
ByteArrayInputStream 2 public int read() 普通 從輸入流中讀取一個字節數據
ByteArrayInputStream 3 public int read(byte [] data) 普通 從指定流中讀取多個字節
ByteArrayInputStream 4 public int read(byte [] data, int off, int len) 普通 從指定流中讀取指定多個字節
ByteArrayOutputStream 5 public ByteArrayOutputStream() 構造 創建一個32個字節
ByteArrayOutputStream 6 public ByteArrayOutputStream(int size) 構造 根據參數指定大小創建緩沖區
ByteArrayOutputStream 7 public void write(int b) 普通 往輸出流中寫入一個字節數據
ByteArrayOutputStream 8 public void write(byte [] b) 普通 往輸出流中寫入一個字節數組數據
ByteArrayOutputStream 9 public void write(byte [] b, int off, int len) 普通 往輸出流中寫入指定多個字節數據
ByteArrayOutputStream 10 public String toString() 普通 使用默認編碼將緩沖區數據編碼成字符串并返回
ByteArrayOutputStream 11 public byte [] toByteArray() 普通 將緩沖區數據通過字節數組返回
代碼示例
import java.io.InputStream;import java.io.OutputStream;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;public class TestDemo{ public static void main(String [] args)throws Exception{ String str = "abcdefghijklmnopqrstuvwsyz"; // 將字符串轉換成字節數組 byte [] data = str.getBytes(); // 將字節數組轉換成輸入流,即將數據輸出到內存 InputStream in = new ByteArrayInputStream(data); // 字節輸出流的實例化,即從內存讀取數據 OutputStream out = new ByteArrayOutputStream(); // 從ByteArrayInputStream中讀取多個字節數據 byte [] b = new byte[1024]; int len = in.read(b); System.out.println(new String(b, 0, len)); // 重置標志位置,從第一個字節開始讀取字節數據 in.reset(); // 從ByteArrayInputStream中一個字節接一個字節讀取數據 int temp = in.read(); while(temp != -1){ // 往輸出流寫入從輸入流中讀取的數據,并把數據變為大寫 out.write(Character.toUpperCase(temp)); System.out.print((char)temp + " "); temp = in.read(); } System.out.println(); // 從輸出流中獲取數據,并轉換成字符數據 System.out.println(out.toString()); }}

程序運行結果: abcdefghijklmnopqrstuvwsyz a b c d e f g h i j k l m n o p q r s t u v w s y z ABCDEFGHIJKLMNOPQRSTUVWSYZ


在上面的例子中,我們通過字符串獲取字節數組將其作為ByteArrayInputStream的數據流來源,然后通過讀取ByteArrayInputStream的數據,將讀到的數據寫入到ByteArrayOutputStream中。


鍵盤操作:System.in

System.in是System類中的一個InputStream類型的常量,用于系統輸入。系統輸入針對標準的輸入設備——鍵盤,也就是俗稱的鍵盤輸入數據,由于System.in是InputStream類型數據,所以接收的數據是字節型。通過調用read()函數完成鍵盤輸入數據操作。


代碼示例
import java.io.IOException;import java.io.InputStream;public class TestDemo{ public static void main(String [] args) throws IOException{ InputStream in = System.in; byte [] data = new byte[1024]; // 從鍵盤輸入多個數據,以回車鍵結束輸入 System.out.println("輸入多個字節數據:"); int len = in.read(data); System.out.println(new String(data, 0, len)); System.out.println("一個字節接一個字節輸入數據:"); int temp = in.read(); while(temp != -1){ // 鍵入回車鍵,則退出輸出 if(temp == '/n'){ break; } // 將輸入的字母變為大寫字母 System.out.print((char)Character.toUpperCase(temp) + " "); // 從鍵盤輸入一個字節數據 temp = in.read(); } }}

程序運行結果: 輸入多個字節數據: Hello 中國 Hello 中國

一個字節接一個字節輸入數據: Hello 中國 H E L L O ? ? - ? ? ?


在上面的例子中,可以發現從鍵盤輸入數據時,既可以多個字節數據同時輸入,也可以一個接一個字節輸入,但應注意的是,在單個字節輸入時,中文輸出會發生亂碼,一般在進行中文操作時,應使用字符流完成。


緩沖區操作:BufferedInputStream & BufferedOutputStream

BufferedInputStream是緩沖輸入流,繼承于FilterInputStream。作用是為其它輸入流提供緩沖功能。BufferedInputStream會將輸入流數據分批讀取,每次讀取一部分數據到緩沖中,操作完緩沖中的數據之后,在從輸入流中讀取下一部分的數據。即BufferedInputStream內部有一個字節數組緩沖區,每次執行read操作的時候就從這buf中讀取數據,從buf中讀取數據沒有多大的開銷。如果buf中已經沒有了要讀取的數據,那么就去執行其內部綁定的InputStream的read方法,而且是一次性讀取很大一塊數據,以便填充滿buf緩沖區。于我們在執行BufferedInputStream的read操作的時候,很多時候都是從緩沖區中讀取的數據,這樣就大大減少了實際執行其指定的InputStream的read操作的次數,也就提高了讀取的效率。

BufferedOutputStream是輸出緩沖流,與BufferedInputStream相對,繼承于FilterOutputStream。作用是為輸出流提供緩沖功能。BufferedOutputStream內部有一個字節緩沖區buf,在執行write操作時,將要寫入的數據先一起緩存在一起,將其存入字節緩沖區buf中,當buf被填充完畢的時候會調用BufferedOutputStream的flushBuffer方法,該方法會通過調用其綁定的OutputStream的write方法將buf中的數據進行實際的寫入操作并將buf的指向歸零(可以看做是將buf中的數據清空)。如果想讓緩存區buf中的數據理解真的被寫入OutputStream中,可以調用flush方法,flush方法內部會調用flushBuffer方法。由于buf的存在,會大大減少實際執行OutputStream的write操作的次數,優化了寫的效率。

緩沖操作的常用方法

類名稱 No. 方法 類型 描述
BufferedInputStream 1 public BufferedInputStream(InputStream in) 構造 實例化BufferedInputStream,使用默認緩沖區大小
BufferedInputStream 2 public BufferedInputStream(InputStream in, int size) 構造 實例化BufferedInputStream,指定緩沖區大小
BufferedInputStream 3 public int read() 普通 從輸入流中讀取一個字節數據
BufferedInputStream 4 public int read(byte [] data) 普通 從指定流中讀取多個字節
BufferedInputStream 5 public int read(byte [] data, int off, int len) 普通 從指定流中讀取指定多個字節
BufferedOutputStream 6 public BufferedOutputStream(OutputStream out) 構造 實例化BufferedOutputStream,使用默認緩沖區大小
BufferedOutputStream 7 public BufferedOutputStream(OutputStream out, int size) 構造 實例化BufferedOutputStream,指定緩沖區大小
BufferedOutputStream 8 public void write(int b) 普通 向輸出緩沖區寫入一個字節數據
BufferedOutputStream 9 public void write(byte [] data) 普通 向輸出緩沖區寫入多個字節數據
BufferedOutputStream 10 public void write(byte [] data, int off, int len) 普通 向輸出緩沖取寫入指定多個字節
BufferedOutputStream 11 public void flush() 普通 清空緩沖區,緩存區buf中的數據理解真的被寫入OutputStream中

代碼示例

import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class TestDemo{ public static void main(String [] args) throws IOException{ File fio = new File(File.separator + "home" + File.separator + "linyimin" + File.separator + "DaSi" + File.separator + "java" + File.separator + "InputStream.txt"); File fout = new File(File.separator + "home" + File.separator + "linyimin" + File.separator + "DaSi" + File.separator + "java" + File.separator + "OutputStream.txt"); // InputStream.txt不存在則創建文件 if(!fio.exists()){ fio.createNewFile(); } // OutputStream.txt不存在則創建文件 if(!fout.exists()){ fout.createNewFile(); } // 實例化BufferedInputStream BufferedInputStream ibuf = new BufferedInputStream(new FileInputStream(fio)); // 實例化BufferedOutputStream BufferedOutputStream obuf = new BufferedOutputStream(new FileOutputStream(fout)); byte [] data = new byte[1024]; // 從BufferedInputStream中多個字節數據 int len = ibuf.read(data); while(len != -1){ // 向BufferedOutputStream中寫入多個數據 obuf.write(data, 0, len); // 繼續從BufferedInputStream中讀取多個字節數據 len = ibuf.read(data); } // 清空輸出緩存區 obuf.flush(); // 關閉輸出輸入流 ibuf.close(); obuf.close(); }}

 程序運行結果: 程序運行前:OutputStream.txt文件不存在,InputStream.txt文件的內容為: Hello World. 1234567890 程序運行后:OutputStream.txt文件的內容為: Hello World. 1234567890


在上面的例子中,實現了將InputStream.txt拷貝到OutputStream.txt。其實不通過BufferedInputStream 和 BufferedOutputStream也可以完成這樣的工作,使用這個兩個類的好處是提升了文件拷貝的效率。下面進行驗證:

直接使用InputStream和OutputStream完成大文件賦值

代碼

import java.io.File;import java.io.InputStream;import java.io.OutputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.math.BigDecimal;public class TestDemo{ public static void main(String [] args) throws IOException{ File fio = new File("/home/linyimin/Downloads/
linux_11gR2_database_2of2.z

程序運行結果:

復制大小為:949.25M的文件共花費時間:49.048s


使用緩沖區完成大文件的復制

代碼

import java.io.File;import java.io.InputStream;import java.io.OutputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.math.BigDecimal;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;public class TestDemo{ public static void main(String [] args) throws IOException{ File fio = new File("/home/linyimin/Downloads/linux_11gR2_database_2of2.zip"); File fout = new File("/home/linyimin/Downloads/linux_11gR2_database_2of2-copy.zip"); InputStream in = null; OutputStream out = null; // 創建文件 try{ fout.createNewFile(); in = new BufferedInputStream(new FileInputStream(fio)); out = new BufferedOutputStream(new FileOutputStream(fout)); } catch(Exception e){ e.printStackTrace(); } // 獲取復制文件大小,并轉換成單位M,保留兩位小數 double length = new BigDecimal(fio.length() / 1024.0 / 1024).divide(new BigDecimal(1), 2, BigDecimal.ROUND_HALF_UP).doubleValue(); // 文件復制開始時間 long start = System.currentTimeMillis(); // 從輸入流中讀取多個字節數據 byte [] data = new byte[1024]; int len = in.read(data); while(len != -1){ // 將從輸入流中讀出的數據寫入輸出流中 out.write(data); // 繼續從輸入流中讀取數據 len = in.read(data); } // 文件復制結束時間 long end = System.currentTimeMillis(); // 將文件復制時間轉換成秒并保留三位小數 double time = new BigDecimal((end - start) / 1000.0).divide(new BigDecimal(1), 3, BigDecimal.ROUND_HALF_UP).doubleValue(); System.out.println("復制大小為:" + length + "M的文件共花費時間:" + time + "s"); }}

程序運行結果:

復制大小為:949.25M的文件共花費時間:32.93s


比較以上兩個程序的執行結果,使用緩沖區操作的效率確實要提高不少。


管道流操作:PipeInputStream & PipeOutputStream

管道流操作主要用于兩個線程之間進行管道通信。PipedInputStream和PipedOutputStream一般是結合使用的,一般在一個線程中執行PipedOutputStream 的write操作,而在另一個線程中執行PipedInputStream的read操作。單獨使用PipedInputStream或單獨使用PipedOutputStream時沒有任何意義的,必須將二者通過connect方法(或在構造函數中傳入對應的流)進行連接綁定,如果單獨使用其中的某一個類,就會觸發IOException: PipeNotConnected.

代碼示例

import java.io.IOException;import java.io.PipedInputStream;import java.io.PipedOutputStream;public class TestDemo{ public static void main(String [] args)throws Exception{ // 實例化PipedOutputStream final PipedOutputStream out = new PipedOutputStream(); final PipedInputStream in = new PipedInputStream(out); // 使用匿名內部類實現線程t1 Thread t1 = new Thread(new Runnable(){ @Override public void run(){ try { out.write("Hello Pipe.".getBytes()); } catch (IOException e) { e.printStackTrace(); } } }); // 使用匿名內部類實現線程t2 Thread t2 = new Thread(new Runnable(){ @Override public void run(){ int len = 0; try { // 從線程t1中的輸出流中讀取數據 while((len = in.read()) != -1){ System.out.print((char)len + " "); } } catch (IOException e) { } System.out.println(); } }); // 啟動線程 t1.start(); t2.start(); }}

程序運行結果 H e l l o P i p e .


在上面的程序中,我們創建了兩個線程,并通過構造方法將PipedInputStream流和PipedOutputStream綁定。線程t1在運行時往輸出流中寫入字節數據,而線程t2在運行時阻塞式的執行read操作,等待獲取數據,并輸出。

對象序列化和反序列化操作:ObjectInputStream & ObjectOutputStream

對象序列化指的是將在內存中保存的對象數據(主要指的是一個對象里面所包含的屬性內容)進行二進制傳輸的一種操作.反序列化:將已經被序列化的數據反序列化為對象.

注:要實現序列化,對象所在類必須實現java.io.Serializable接口.Serializable接口沒有方法,屬于一種標識接口,表示一種一種能力.

如果一個類已經實現了序列化接口,那么此類的對象就可以經過二進制數據流進行傳輸,但是還需要對象輸出流ObjectOutputStream和對象輸入流ObjectInputStream完成對象的輸入和輸出.

ObjectOutputStream具有一系列writeXXX方法,在其構造函數中可以傳入一個OutputStream,可以方便的向指定的輸出流中寫入基本類型數據以及String,比如writeBoolean、writeChar、writeInt、writeLong、writeFloat、writeDouble、writeCharts、writeUTF等,除此之外,ObjectOutputStream還具有writeObject方法。在執行writeObject操作時將對象進行序列化成流,并將其寫入指定的輸出流中。ObjectInputStream與ObjectOutputStream相對應,ObjectInputStream有與OutputStream中的writeXXX系列方法完全對應的readXXX系列方法,專門用于讀取OutputStream通過writeXXX寫入的數據。

ObjectOutputStream和ObjectInputStream常用方法

類名稱 No. 方法 類型 描述
ObjectOutputStream 1 public ObjectOutputStream(OutputStream out) 構造 實例化指定輸出流的對象
ObjectOutputStream 2 public void writeObject(Object obj) 普通 向指定輸流寫入數據
ObjectInputStream public ObjectInputStream(InputStream in) 構造 實例化指定輸入流的對象
ObjectInputStream public void readObject(Object obj) 普通 從指定輸入流讀出數據

代碼示例-序列化

import java.io.File;import java.io.Serializable;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectOutputStream;// 定義可以被序列化的類class Person implements Serializable{ private String name; private int age; public Person(String name, int age){ this.name = name; this.age = age; }}public class TestDemo{ public static void main(String [] args) throws FileNotFoundException, IOException{ // 實例化序列化對象 Person per = new Person("張三", 20); File file = new File("/home/linyimin/DaSi/java/serializable.txt"); // 實例化ObjectOutputStream對象 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file)); // 序列化對象 oos.writeObject(per); // 關閉輸出流 oos.close(); }}

程序運行結果: 文件serializable.txtx中的內容: /AC/ED/00sr/00Person:H3/BC/B0/FC/00I/00ageL/00namet/00Ljava/lang/String;xp/00/00/00t/00張三


本程序使用ObjectOutputStream將一個已經實例化的對象序列化到文件中.


代碼示例-反序列化

import java.io.File;import java.io.Serializable;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.ObjectInputStream;//定義可以被序列化的類class Person implements Serializable{ private String name; private int age; public Person(String name, int age){ this.name = name; this.age = age; } @Override public String toString(){ return "姓名:" + this.name + " 年齡:" + this.age; }}public class TestDemo{ public static void main(String [] args) throws FileNotFoundException, IOException, ClassNotFoundException{ // 實例化ObjectInputStream對象 File fio = new File("/home/linyimin/DaSi/java/serializable.txt"); ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fio)); // 實現反序列化 Person per = (Person) ois.readObject(); ois.close(); System.out.println(per); }}

程序運行結果:

姓名:張三 年齡:20


本程序通過ObjectInputStream類將之前已經被序列化的數據反序列化為對象.

字符流

字符流和字節流十分相似,主要區別在于:

字節流是針對字節的操作,而字符流是針對字符的操作字節流在進行IO操作時,直接針對的是操作的數據終端(如文件),而字符流是針對緩存區(可以理解為內存)的操作,然后由緩沖區操作終端(如文件)

下面主要介紹字符流較于字節流的區別之處:

使用Writer類進行輸出的最大方便之處在于:可以直接輸出字符串數據,而不像OutputStream類一樣需要調用getBytes()函數將字符串轉換成字節數組.

代碼示例

import java.io.File;import java.io.Writer;import java.io.FileWriter;public class TestDemo{ public static void main(String [] args)throws Exception{ File file = new File("/home/linyimin/DaSi/java/out.txt"); // 如果文件不不存在,創建文件 if(!file.exists()){ file.createNewFile(); } // 實例化FileWriter對象 Writer out = new FileWriter(file); String str = "Hello World."; // 直接向文件中輸出字符串 out.write(str); // 需要關閉輸出流,數據才會從緩存區寫到文件中 out.close(); }}

程序運行結果

創建out.txt文件,并寫入”Hello World."


本程序通過FileWriter完成直接將字符串寫入指定文件中.

轉換流

所謂轉換流指的是字節流向字符流轉換的操作流.由InputStreamReader和OutputStreamWriter兩個類完成.

InputStreamReader繼承自Reader: InputStream –> Reader(使用構造方法完成)OutputStreamWriter繼承自Writer:OutputStream –> Writer(使用構造方法完成)

代碼示例

import java.io.File;import java.io.Writer;import java.io.OutputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStreamWriter;public class TestDemo{ public static void main(String [] args) throws IOException{ File file = new File("/home/linyimin/DaSi/java/out.txt"); // 實例化字節輸出流 OutputStream out = new FileOutputStream(file); // 將字節輸出流轉換成字符輸出流 Writer wout = new OutputStreamWriter(out); String str = "使用OutputStreamWriter完成輸出流轉換操作"; // 直接向文件輸出字符串 try { wout.write(str); } catch (IOException e) { e.printStackTrace(); } // 關閉輸出流,完成IO操作 wout.close(); }}

程序運行結果

向文件out.txt中輸出字符串"使用OutputStreamWriter完成輸出流轉換操作"


注:處理各種數據都可以通過字節流完成,而在處理中文時使用字符流會更好


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 周至县| 台州市| 岳阳县| 抚顺县| 牡丹江市| 汝阳县| 荆州市| 夏津县| 长白| 德格县| 荣昌县| 新源县| 灵丘县| 高陵县| 通海县| 锦州市| 湘西| 南康市| 阜城县| 会宁县| 江源县| 灵川县| 昭通市| 平江县| 淮滨县| 施甸县| 从化市| 江津市| 赫章县| 江西省| 肥城市| 梓潼县| 茌平县| 阜城县| 田阳县| 鄂托克前旗| 章丘市| 佛坪县| 河西区| 江山市| 博兴县|