Java IO文件流


package com.zb.io.test;


import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.io.OutputStreamWriter;

import java.io.Reader;

import java.io.Writer;


public class IO {

public static final String PATH1 = "temp/1.txt";

public static final String PATH2 = "temp/2.txt";

public static final String PATH3 = "temp/3.txt";

public static final String PATH4 = "temp/4.txt";

public static final String PATH5 = "temp/5.txt";

 

public static void main(String[] args) {

try {

// 創建文件夾和文件

File file = createDirAndFile(PATH1);

// 使用字節流OutPutStream寫入文件信息

setFileByByteIoOutPutStream(file);

// 使用字節流InPutStream讀取文件信息

getFileByByteIoInPutStream(file);

file = createDirAndFile(PATH2);

//使用Writer寫入文件信息

setFileByCharIoWriter(file);

//使用Reader讀取文件信息

getFileByCharIoReader(file);

file = createDirAndFile(PATH3);

//使用OutputStreamWriter寫入文件信息

setFileByCharIoOutputStreamWriter(file);

//使用InputStreamReader讀取文件信息

getFileByCharIoInputStreamReader(file);

file = createDirAndFile(PATH4);

//使用BufferedWriter寫入文件信息

setFileByCharIoBufferedWriter(file);

//使用BufferedReader讀取文件信息

getFileByCharIoBufferedReader(file);

file = createDirAndFile(PATH5);

//使用BufferedOutputStream寫入文件信息

setFileByBufferedOutputStream(file);

//使用BufferedInputStream讀取文件信息

getFileByBufferedInputStream(file);

 

} catch (IOException e) {

e.printStackTrace();

}

}

/**

* 在指定的目錄創建文件夾和文件

* @param path 

* @throws IOException

*/

public static File createDirAndFile(String path) throws IOException {

File fileDir = new File("temp");

if (!fileDir.exists() && !fileDir.isDirectory()) {

System.out.println("開始創建新的文件夾!");

fileDir.mkdir();

} else {

System.out.println("文件夾已存在,無需創建!");

}

System.out.println("當前文件夾的路徑是:" + fileDir.getAbsolutePath());

File file = new File(path);

if (!file.exists()) {

System.out.println("開始創建新的文件!");

file.createNewFile();

} else {

System.out.println("文件已存在,無需創建!");

}

System.out.println("當前文件的路徑是:" + file.getAbsolutePath());

return file;

}


/**

* 使用OutPutStream寫入文件

* @throws IOException

*/

public static void setFileByByteIoOutPutStream(File file) throws IOException {

StringBuffer sb = new StringBuffer("使用字節流OutPutStream寫入文件信息!");

sb.append("\r\n在java中,可以使用InputStream對文件進行讀取,就是字節流的輸入。!");

sb.append("\r\n當讀取文件內容進程序時,需要使用一個byte數組來進行存儲,如此會有如下兩個問題:");

sb.append("\r\n1.如何建立合適大小的byte數組,如果已知輸入流的大小。");

sb.append("\r\n2.如果不知輸入流的大小,則肯定需要建立一個很大的byte數組,那麼byte中很可能有空的內容,那麼如何正確合適的將byte數組的中的內容輸出?");

sb.append("\r\n先看第一個問題:解決之道就是獲取輸入流的大小,創建此大小的byte數組。代碼如下:view plaincopy to clipboardprint?\r\n//使用InputStream從文件中讀取數據,在已知文件大小的情況下,建立合適的存儲字節數組   ");

sb.append("\r\n第二個問題:問題的解決之道就是獲得輸入流何時結束,它在byte中的尾索引位置。可以通過read()方法實現,read()返回讀取的字節內容,當內容爲空時返回-1。利用此特徵可以解決第二個問題。");

OutputStream out = new FileOutputStream(file);

out.write(sb.toString().getBytes());

// 刷新此輸出流並強制寫出所有緩衝的輸出字節

out.flush();

out.close();

System.out.println("字節流寫入文件完成!!!");

}


/**

* 使用InputStream讀取文件

* @throws IOException

*/

public static void getFileByByteIoInPutStream(File file) throws IOException {

InputStream in = new FileInputStream(file);

System.out.println("===============字節流開始讀取文件===================");

//創建合適文件大小的數組

byte b[]=new byte[(int)file.length()];     

//讀取文件中的內容到b[]數組

 in.read(b);

 //關閉流

 in.close();

 System.out.println(new String(b));

in.close();

System.out.println("\n===============文件流讀取完成===================");

}

/**

* 使用Writer寫入文件

* @param file

* @throws IOException 

*/

private static void setFileByCharIoWriter(File file) throws IOException {

Writer wr = new FileWriter(file);

StringBuffer sb = new StringBuffer("使用字符流Writer寫入文件信息!");

sb.append("\r\n java中的字符是Unicode編碼的, InputStream和OutputStream都是用來處理字節的,在處理字符時需要用getBytes()轉換成字節,這就需要編寫字節、字符之間的轉換代碼java中提供了單獨的類對IO設備進行字符輸入與輸出!");

sb.append("\r\n Reader和Writer是所有字符流類的的抽象基類,用於簡化對字符串的輸入輸出編程,即用於讀寫文本數據");

sb.append("\r\n 二進制文件和文本文件的區別。");

sb.append("\r\n 如果一個文件專用於存儲文本字符,而又沒有包含文本之外的字符,就可稱之爲文本文件。除此之外的文件就是二進制文件");

sb.append("\r\n Reader和Writer兩個類主要用於操作文本數據的內容,而InputStream和OutputStream主要操作二進制格式的內容  ");

sb.append("\r\n 使用FileWriter寫入字符數據比FileOutputStream要簡便很多,但是FileReader並不比FileInputStream讀取字符數據要簡便多少,都是要先讀取到一個字符數組或者字節數組中,然後把數組轉換成字符串。");

wr.write(sb.toString());

wr.flush();

wr.close();

System.out.println("字符流寫入文件完成!!!");

}

/**

* 使用Reader讀取文件

* @throws IOException 

*/

public static void getFileByCharIoReader(File file) throws IOException{

Reader reader = new FileReader(file);

char[] buffer = new char[1024];

int length = reader.read(buffer);

System.out.println("===============字符流開始讀取文件===================");

String text = new String(buffer,0,length);

System.out.println(text);

reader.close();

System.out.println("\n===============文件流讀取完成===================");

}

/**

* 使用OutputStreamWriter寫入文件

* @param file

* @throws IOException 

*/

private static void setFileByCharIoOutputStreamWriter(File file) throws IOException {

OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(file));

StringBuffer sb = new StringBuffer("使用OutputStreamWriter寫入文件信息!");

sb.append("\r\n 讀取文件流時,經常會遇到亂碼的現象,造成亂碼的原因當然不可能是一個,這裏主要介紹因爲文件編碼格式而導致的亂碼的問題。首先,明確一點,文本文件與二進制文件的概念與差異。");

sb.append("\r\n 文本文件是基於字符編碼的文件,常見的編碼有ASCII編碼,UNICODE編碼、ANSI編碼等等。二進制文件是基於值編碼的文件,你可以根據具體應用,指定某個值是什麼意思(這樣一個過程,可以看作是自定義編碼。)");

sb.append("\r\n 因此可以看出文本文件基本上是定長編碼的(也有非定長的編碼如UTF-8)。而二進制文件可看成是變長編碼的,因爲是值編碼嘛,多少個比特代表一個值,完全由你決定。");

sb.append("\r\n 對於二進制文件,是千萬不能使用字符串的,因爲字符串默認初始化時會使用系統默認編碼,然而,二進制文件因爲自定義編碼自然與固定格式的編碼會有所衝突,所以對於二進制的文件只能採用字節流讀取、操作、寫入。");

sb.append("\r\n  對於文本文件,因爲編碼固定,所以只要在讀取文件之前,採用文件自身的編碼格式解析文件,然後獲取字節,再然後,通過指定格式初始化字符串,那麼得到的文本是不會亂碼的。  ");

sb.append("\r\n  雖然,二進制文件也可以獲取到它的文本編碼格式,但是那是不準確的,所以不能同日而語。");

out.write(sb.toString());

out.flush();

out.close();

}

/**

* 使用InputStreamReader讀取文件

* @param file

* @throws IOException 

*/

private static void getFileByCharIoInputStreamReader(File file) throws IOException {

InputStreamReader isr = new InputStreamReader(new FileInputStream(file),"UTF-8");

int length = -1;

char[] buffer = new char[1024];

StringBuffer sb = new StringBuffer(0);

System.out.println("===============InputStreamReader開始讀取文件===================");

while((length=isr.read(buffer,0,1024))!=-1){

sb.append(buffer,0,length);

}

isr.close();

System.out.println(sb.toString());

System.out.println("===============InputStreamReader讀取完成===================");

}

/**

* 使用BufferedWriter寫入文件

* @param file

* @throws IOException 

*/

private static void setFileByCharIoBufferedWriter(File file) throws IOException {

BufferedWriter bw = new BufferedWriter(new FileWriter(file));

StringBuffer sb = new StringBuffer("使用BufferedWriter寫入文件信息!");

sb.append("\r\n java.io.BufferedReader和java.io.BufferedWriter類各擁有8192字符的緩衝區。");

sb.append("\r\n 當BufferedReader在讀取文本文件時,會先儘量從文件中讀入字符數據並置入緩衝區,而之後若使用read()方法,會先從緩衝區中進行讀取。");

sb.append("\r\n 如果緩衝區數據不足,纔會再從文件中讀取,使用BufferedWriter時,寫入的數據並不會先輸出到目的地,而是先存儲至緩衝區中。 ");

sb.append("\r\n 如果緩衝區中的數據滿了,纔會一次對目的地進行寫出。");

sb.append("\r\n  從標準輸入流System.in中直接讀取使用者輸入時,使用者每輸入一個字符,System.in就讀取一個字符。爲了能一次讀取一行使用者的輸入,使用了BufferedReader來對使用者輸入的字符進行緩衝。  ");

sb.append("\r\n  readLine()方法會在讀取到使用者的換行字符時,再一次將整行字符串傳入。");

bw.write(sb.toString());

//BufferedWriter換行的方法

bw.newLine();

bw.flush();

bw.close();

}

/**

* 使用BufferedReader讀取文件

* @param file

* @throws IOException 

*/

private static void getFileByCharIoBufferedReader(File file) throws IOException {

BufferedReader br = new BufferedReader(new FileReader(file));

System.out.println("===============BufferedReader開始讀取文件===================");

int length = -1;

String text = br.readLine();

while((text=br.readLine())!=null){

System.out.println(text);

}

System.out.println("===============BufferedReader讀取文件完成===================");

}

/**

*使用BufferedOutputStream寫入文件

* @throws IOException 

*/

private static void setFileByBufferedOutputStream(File file) throws IOException {

BufferedOutputStream bos = new  BufferedOutputStream(new FileOutputStream(file));

StringBuffer sb = new StringBuffer("使用BufferedWriter寫入文件信息!");

sb.append("\r\n 在創建BufferedInputStream  實例時(BufferedOutputStream同上),需要先給定一個InputStream類型的實例(如:FileInputStream)。");

sb.append("\r\n 解釋BufferedInputStream實現流程:其實質是實現了一個緩存裝置,在讀取源數據的時候其實還是用的InputStream來實現的。只是在讀取之前給他們加了一個緩存區而已。");

sb.append("\r\n 注意這個緩存區默認是位數組,大小2048,當讀文件的時候,BufferedInputStream會首先填滿緩存區,然後在使用InputStream的read()方法的時候,把緩存數組中的數據在讀到目的地");

sb.append("\r\n 對BufferedOutputStream,有一個默認512字節的緩存數組,當使用write()方法寫數據時,實質上是先將數據寫至緩存中,當緩存滿時,在用write()方法把數據寫入");

byte[] bytes = sb.toString().getBytes();

bos.write(bytes);

bos.flush();

bos.close();

}

/**

* 使用BufferedInputStream

* @throws IOException 

*/

private static void getFileByBufferedInputStream(File file) throws IOException {

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); 

byte[] buffer = new byte[bis.available()];

int length = 0;

StringBuffer sb = new StringBuffer(0);

System.out.println("===============BufferedInputStream開始讀取文件===================");

while((length=bis.read(buffer,0,buffer.length))!=-1){

System.out.println(new String(buffer));

}

System.out.println("===============BufferedInputStream讀取文件結束===================");

}

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章