java IO(File類、字節流與字符流、字節字符轉換流)

 

File類

在整個io包中,惟一表示與文件自己有關的類就是File類。使用File類能夠進行建立或刪除文件等經常使用操做,要想使用File類,則首先要觀察File類的構造方法,此類的經常使用構造方法以下java

public File(String pathname)實例化File類的時候,必須設置好路徑根據路徑找到文件

File類中的主要方法和常量

方法或常量windows

類型數組

描述緩存

public static final String pathSeparatorapp

常量spa

表示路徑的分隔符(windows:‘;’)code

public static final String separator對象

常量遞歸

表示路徑分隔符(windows:‘\’)圖片

public File(String pathname)

構造

建立File類對象,傳入完整的路徑

public boolean createNewFile() throws IOException

普通

建立新文件

public boolean exists()

普通

判斷文件是否存在

public boolean delete()

普通

刪除文件

public boolean isDirectory()

普通

判斷給定的路徑是不是一個目錄

public long length()

普通

返回文件的大小

public String[] list()

普通

列出指定目錄的所有內容,只是名稱

public File[] listFiles()

普通

列出指定目錄的所有內容,會列出路徑。

public boolean mkdir()

普通

建立一個目錄

public boolean renameTo(File dest)

普通

爲已有的文件重命名

代碼示例:

import java.io.*;
public class FileDemo01
{
	public static void main(String args[]){
		File file=new File("d:"+File.separator+"test.txt");
		System.out.println("file.pathSeparator:"+file.pathSeparator);	//調用靜態變量
		System.out.println("file.separator:"+file.separator);	//調用靜態變量
		if(file.exists()){	//判斷當前文件是否存在
			file.delete();		//存在就刪除
		}
		try{
			file.createNewFile();	//刪除後從新建立
		}catch(IOException e){
			e.printStackTrace();
		}
		System.out.println("文件的大小:"+file.length());	//輸出新建立文件的大小
	}
}

代碼示例2:

import java.io.*;
public class FileDemo02
{
	public static void main(String args[]){
		File file=new File("d:"+File.separator+"test");
		file.mkdir();	//建立新的文件夾
		File f=new File("d:"+File.separator+"test.txt");
		f.renameTo(new File("d:"+File.separator+"test1.txt"));	//爲已知的文件重命名
		}
}

案例:列出指定目錄的所有文件

import java.io.File ;
import java.io.IOException ;
public class FileDemo03{
	public static void main(String args[]){
		File my = new File("d:" + File.separator) ;	// 操做路徑
		print(my) ;
	}
	public static void print(File file){	// 遞歸調用
		if(file!=null){	// 判斷對象是否爲空
			if(file.isDirectory()){	// 若是是目錄
				File f[] = file.listFiles() ;	// 列出所有的文件
				if(f!=null){	// 判斷此目錄可否列出
					for(int i=0;i<f.length;i++){
						print(f[i]) ;	// 由於給的路徑有多是目錄,因此,繼續判斷
					}
				}
			}else{
				System.out.println(file) ;	// 輸出路徑
			}
		}
	}
};

字節流與字符流

在java.io包中操做文件內容的主要有兩大類:字節流、字符流。兩類都分爲輸入和輸出操做。在字節流中輸出數據主要是使用OutputStream完成,輸入使用的是InputStream,在字符流中輸出主要是使用Writer類完成,輸入主要是使用Reader類完成。

在程序中全部的數據都是以流的方式進行傳輸或保存的,程序須要數據的時候要使用輸入流讀取數據,而當程序須要將一些數據保存 起來的時候,就要使用輸出流完成。

操做流程

在java中IO操做也是有相關步驟的,以文件操做爲例,主要的操做流程以下:

•A、使用File類打開一個文件
•B、經過字節流或字符流的子類,指定輸出的位置
•C、進行讀\寫操做
•D、關閉輸入\輸出

字節流

字節流主要是操做byte類型數據,也byte數組爲準,主要操做類就是

·字節輸出流:OutputStream

·字節輸入流:InputStream

字節輸出流:OutputStream

OutputStream類是整個io包中字節輸出流的最大父類,此類的定義以下:

public abstract class OutputStream extends Object implements Closeable, Flushable
•Closeable:表示能夠關閉的操做,由於程序到最後確定要關閉。
•Flushable:表示刷新,清空內存中的數據。

從以上類的定義中能夠發現,此類是一個抽象類,若是要想使用此類的話,則首先必須經過子類實例化對象,那麼若是如今要操做一個文件,則可使用FileOutputStream類。經過向上轉型以後,能夠爲OutputStream實例化。

OutputStream類中的經常使用方法:

方法	描述
public void close() throws IOException	關閉輸出流
public void flush() throws IOException	刷新緩衝區
public void write(byte[] b) throws IOException	將一個byte數組寫入數據流
public void write(byte[] b,int off,int len)throws IOException	將一個指定範圍的byte數組寫入數據流
public abstract void write(int b) throws IOException	將一個字節數據寫入數據流

要想使用以上的方法,必須使用子類進行實例化,此時使用FileOutputStream子類,此類的構造方法以下:

public FileOutputStream(File file) throws FileNotFoundException

代碼示例:建立文件並寫入字符

import java.io.*;
public class OutputStreamDemo01
{
	public static void main(String args[])	throws Exception{
		//一、使用File類指定一個文件名
		File file=new File("d:"+File.separator+"test.txt");
		//二、建立OutputStream類,併爲此實例化對象
		OutputStream out=new FileOutputStream(file);
		//三、執行寫入操做
		String str="Hello world";
		byte b[]=str.getBytes();
		out.write(b);
		//四、關閉輸入流
		out.close();
	}
}

注:

一、  在操做的時候若是文件自己不存在,則會爲用戶自動建立新文件。

二、  若是要追加的內容須要換行,則在內容中加入「\r\n」就能夠了。

以上的操做在寫入數據以後,文件以前的內容已經不存在了,由於在IO操做中默認的狀況是將其進行覆蓋的,若是如今想執行追加的功能,則必須設置追加的操做,此時能夠經過FileoutputStream向文件中追加內容:其另外的一個構造方法:

FileOutputStream(File file, boolean append)

在構造方法中,若是將append的值設置爲true,則表示在文件的末尾追加內容。

OutputStream out=new FileOutputStream(file,true);

字節輸入流:InputStream

既然程序能夠向文件中寫入內容,則就能夠經過InputStream從文件中把內容讀取進來,首先來看InputStream類的定義:

public abstract class InputStream extends Object implements Closeable

和OutputStream同樣,InputStream自己也是一個抽象類,必須依靠其子類,若是如今是從文件中讀取,子類確定是FileInputStream。構造方法:

public FileInputStream(File file) throws FileNotFoundException
InputStream類的經常使用方法:
方法	描述
public int available() throws IOException	能夠取得輸入文件的大小
public void close() throws IOException	關閉輸入流
public abstract int read() throws IOException	讀取內容,以數字的方式讀取
public int read(byte[] b) throws IOException	將內容讀到byte數組之中,同時返回個數

示例代碼:

import java.io.File ;
import java.io.InputStream ;
import java.io.FileInputStream ;
public class InputStreamDemo01{
	public static void main(String args[]) throws Exception{	// 異常拋出,不處理
		// 第1步、使用File類找到一個文件
		File f= new File("d:" + File.separator + "test.txt") ;	// 聲明File對象
		// 第2步、經過子類實例化父類對象
		InputStream input = null ;	// 準備好一個輸入的對象
		input = new FileInputStream(f)  ;	// 經過對象多態性,進行實例化
		// 第3步、進行讀操做
		byte b[] = new byte[1024] ;		// 全部的內容都讀到此數組之中
		input.read(b) ;		// 讀取內容
		// 第4步、關閉輸出流
		input.close() ;						// 關閉輸出流
		System.out.println("內容爲:" + new String(b)) ;	// 把byte數組變爲字符串輸出
	}
};

以上代碼對文件中的內容讀取了出來,可是數組開闢的空間遠遠要大於文件實際佔用的空間,則此時能夠根據讀取文件的大小來開闢數組空間:

import java.io.File ;
import java.io.InputStream ;
import java.io.FileInputStream ;
public class InputStreamDemo03{
	public static void main(String args[]) throws Exception{	// 異常拋出,不處理
		// 第1步、使用File類找到一個文件
		File f= new File("d:" + File.separator + "test.txt") ;	// 聲明File對象
		// 第2步、經過子類實例化父類對象
		InputStream input = null ;	// 準備好一個輸入的對象
		input = new FileInputStream(f)  ;	// 經過對象多態性,進行實例化
		// 第3步、進行讀操做
        // byte b[] = new byte[input..available()] ;  跟使用下面的代碼是同樣的
		byte b[] = new byte[(int)f.length()] ;		// 數組大小由文件決定
		int len = input.read(b) ;		// 讀取內容
		// 第4步、關閉輸出流
		input.close() ;						// 關閉輸出流\
		System.out.println("讀入數據的長度:" + len) ;
		System.out.println("內容爲:" + new String(b)) ;	// 把byte數組變爲字符串輸出
	}
};

另外一種讀取方法:

import java.io.File ;
import java.io.InputStream ;
import java.io.FileInputStream ;
public class InputStreamDemo05{
	public static void main(String args[]) throws Exception{	// 異常拋出,不處理
		// 第1步、使用File類找到一個文件
		File f= new File("d:" + File.separator + "test.txt") ;	// 聲明File對象
		// 第2步、經過子類實例化父類對象
		InputStream input = null ;	// 準備好一個輸入的對象
		input = new FileInputStream(f)  ;	// 經過對象多態性,進行實例化
		// 第3步、進行讀操做
		byte b[] = new byte[1024] ;		// 數組大小由文件決定
		int len = 0 ; 
		int temp = 0 ;			// 接收每個讀取進來的數據
		while((temp=input.read())!=-1){
			// 表示還有內容,文件沒有讀完
			b[len] = (byte)temp ;
			len++ ;
		}
		// 第4步、關閉輸出流
		input.close() ;						// 關閉輸出流\
		System.out.println("內容爲:" + new String(b,0,len)) ;	// 把byte數組變爲字符串輸出
	}
};

以上的讀取方式在都是比較常見的。

字符流

在程序中一個字符等於2個字節,那麼java提供了Reader、Writer兩個專門操做字符流的類。

·字符輸出流:Writer

·字符輸入流:Reader

字符輸出流:Writer

Writer自己是一個字符流的輸出類,此類的定義以下:

public abstract class Writer extends Object implements Appendable, Closeable, Flushable

此類自己也是一個抽象類,若是要想使用此類,則確定要使用其子類,此時若是是向文件中寫入內容,因此應該使用FileWriter子類。構造方法以下:

public FileWriter(File file) throws IOException

Writer類的經常使用方法:

方法或常量	描述
public abstract void close() throws IOException	關閉輸出流
public void write(String str) throws IOException	將字符串輸出
public void write(char[] cbuf) throws IOException	將字符數組輸出
public abstract void flush() throws IOException	強制性清空緩存

示例代碼:(字符流能夠直接輸出字符串,不須要轉換爲字節)

import java.io.File ;
import java.io.Writer ;
import java.io.FileWriter ;
public class WriterDemo01{
	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() ;						// 關閉輸出流
	}
};

此時若是是想追加內容,與FileInputStream的格式是同樣的,添加appemd屬性爲true;

字符輸入流:Reader

Reader自己是一個字符流的輸入類,此類的定義以下:

public abstract class Reader extends Object implements Closeable, Readable;

此類自己也是一個抽象類,若是要想使用此類,則確定要使用其子類,此時若是是向文件中寫入內容,因此應該使用FileReader子類。構造方法以下:

public FileReaderr(File file) throws IOException

Writer類的經常使用方法:

方法或常量	描述
public abstract void close() throws IOException	關閉輸出流
public int read() throws IOException	讀取單個字符
public int read(char[] cbuf) throws IOException	將內容讀到字符串數組中,返回讀入的長度

示例代碼:(以字符數組的形式讀取出數據)

import java.io.File ;
import java.io.Reader ;
import java.io.FileReader ;
public class ReaderDemo01{
	public static void main(String args[]) throws Exception{	// 異常拋出,不處理
		// 第1步、使用File類找到一個文件
		File f= new File("d:" + File.separator + "test.txt") ;	// 聲明File對象
		// 第2步、經過子類實例化父類對象
		Reader input = null ;	// 準備好一個輸入的對象
		input = new FileReader(f)  ;	// 經過對象多態性,進行實例化
		// 第3步、進行讀操做
		char c[] = new char[1024] ;		// 全部的內容都讀到此數組之中
		int len = input.read(c) ;		// 讀取內容
		// 第4步、關閉輸出流
		input.close() ;						// 關閉輸出流
		System.out.println("內容爲:" + new String(c,0,len)) ;	// 把字符數組變爲字符串輸出
	}
};

字節流在操做的時候自己是不會用到緩衝區(內存)的,是與文件自己直接操做的,而字符流在操做的時候使用到緩衝區的。

經過代碼來驗證字符流使用到了緩存。

import java.io.File ;
import java.io.OutputStream ;
import java.io.FileOutputStream ;
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數組,因此將字符串變爲byte數組
		out.write(b) ;		// 寫入數據
		// 第4步、關閉輸出流
		// out.close() ;						// 關閉輸出流  此處沒有關閉輸出流
	}
};

在使用字節流操做中,即便沒有關閉,最終也是能夠輸出的。

import java.io.File ;
import java.io.Writer ;
import java.io.FileWriter ;
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() ;						// 此時,沒有關閉
	}
};

以上的內容,沒有輸出任何的內容,也就是說,全部的內容都是保存在了緩衝區之中,而若是執行關閉輸出流的話會強制性的刷新緩衝區,因此能夠把內容輸出。

若是如今假設,沒有關閉的話,也能夠手工強制性調用刷新方法:

public void flush() throws IOException

代碼示例:

import java.io.File ;
import java.io.Writer ;
import java.io.FileWriter ;
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) ;						// 將內容輸出,保存文件
		// 第4步、關閉輸出流
		out.flush() ;	// 強制性清空緩衝區中的內容
		// out.close() ;						// 此時,沒有關閉
	}
};

在全部的硬盤保存文件或是進行傳輸的時候都是以字節的方式進行的。包括圖片也是按字節完成,而字符只有在內存中才會造成。因此在開發中使用字節的操做是較多的。

範例:文件拷貝

經過執行該程序拷貝源文件到目標文件:

import java.io.* ;
public class Copy{
	public static void main(String args[]){
		if(args.length!=2){		// 判斷是不是兩個參數
			System.out.println("輸入的參數不正確。") ;
			System.out.println("例:java Copy 源文件路徑 目標文件路徑") ;
			System.exit(1) ;	// 系統退出
		}
		File f1 = new File(args[0]) ;	// 源文件的File對象
		File f2 = new File(args[1]) ;	// 目標文件的File對象
		if(!f1.exists()){
			System.out.println("源文件不存在!") ;
			System.exit(1) ;
		}
		InputStream input = null ;		// 準備好輸入流對象,讀取源文件
		OutputStream out = null ;		// 準備好輸出流對象,寫入目標文件
		try{
			input = new FileInputStream(f1) ;
		}catch(FileNotFoundException e){
			e.printStackTrace() ;
		}
		try{
			out = new FileOutputStream(f2) ;
		}catch(FileNotFoundException e){
			e.printStackTrace() ;
		}
		if(input!=null && out!=null){	// 判斷輸入或輸出是否準備好
			int temp = 0 ;	
			try{
				while((temp=input.read())!=-1){	// 開始拷貝
					out.write(temp) ;	// 邊讀邊寫
				}
				System.out.println("拷貝完成!") ;
			}catch(IOException e){
				e.printStackTrace() ;
				System.out.println("拷貝失敗!") ;
			}
			try{
				input.close() ;		// 關閉
				out.close() ;		// 關閉
			}catch(IOException e){
				e.printStackTrace() ;
			}
		}
	}	
}

字節-字符轉換流

OutputStreamWriter和InputStreamReader

在整個IO包中,實際上就是字節流和字符流,可是除了這兩個流以外,還存在一組字節流-字符流的轉換類。

•OutputStreamWriter:是Writer的子類,將輸出的字符流轉換爲字節流。即:將一個字節流的輸出對象變爲字節流的輸出對象
•InputStreamReader:是Reader的子類,將輸入的字節流變爲字符流,即:將一個字節流的輸入對象變爲字符流的輸入對象。

在OutputStreamWriter類中須要一個字節流的對象:public OutputStreamWriter(OutputStream out),例如:將字節的文件輸出流,以字符的形式輸出。

import java.io.*;
public class OutputStreamWriterDemo01
{
	public static void main(String args[]) throws Exception{	//全部異常拋出
		File file=new File("d:"+File.separator+"test.txt");
		Writer writer=null;		//字符輸出流
		writer=new OutputStreamWriter(new FileOutputStream(file));	//字節流變爲字符流
		String str="hello world!!!!";	
		writer.write(str);	//使用字符流輸出
		writer.close();
	}
}

讀的時候,也可使用字符流的形式讀取字節流的文件。

import java.io.* ;
public class InputStreamReaderDemo01{
	public static void main(String args[]) throws Exception{
		File f = new File("d:" + File.separator + "test.txt") ;	
		Reader reader = null ;
		reader = new InputStreamReader(new FileInputStream(f)) ;	// 將字節流變爲字符流
		char c[] = new char[1024] ;
		int len = reader.read(c) ;	// 讀取
		reader.close() ;	// 關閉
		System.out.println(new String(c,0,len)) ;
	}
};

對於FileWriter和FileReader的說明:

       從JDK文檔中可知FileOutputStream是OutputStream的直接子類,FileInputStream也是InputStream的直接子類,可是在字符流文件的兩個操做類卻有一些特殊,FileWriter並非Writer的子類,而是OutputStream的子類,而FileReader也不是Reader的直接子類,是InputStreamReader的子類。

相關文章
相關標籤/搜索