Java IO系統:File、RandomAccessFile類(上)

概念

java.io 包幾乎包含了所有操作輸入、輸出需要的類。所有這些流類代表了輸入源和輸出目標。java.io 包中的流支持很多種格式,比如:基本類型、對象、本地化字符集等等。一個流可以理解爲一個數據的序列。輸入流表示從一個源讀取數據,輸出流表示向一個目標寫數據。Java 爲 I/O 提供了強大的而靈活的支持,使其更廣泛地應用到文件傳輸和網絡編程中。

Java 的 I/O 大概可以分成以下幾類:

  • 磁盤操作:File
  • 字節操作:InputStream 和 OutputStream
  • 字符操作:Reader 和 Writer
  • 對象操作:Serializable
  • 網絡操作:Socket
  • 新的輸入/輸出:NIO

File

public class File extends Object implements Serializable, Comparable<File>

File 類是 java.io 包中唯一代表磁盤文件本身的對象,是文件和目錄路徑名的抽象形式,該類不具有從文件讀取信息和向文件寫入信息的功能,它僅描述文件本身的屬性。File 類定義了一些與平臺無關的方法來操作文件,主要用來獲取或處理與磁盤文件相關的信息,像文件名、 文件路徑、訪問權限和修改日期等,還可以瀏覽子目錄層次結構。

構造方法:

1、File(File parent,String child):根據 parent 抽象路徑名和 child 路徑名字符串創建一個新 File 實例。

2、File(String pathname):通過將給定路徑名字符串轉換成抽象路徑名來創建一個新 File 實例。如果給定字符串是空字符串,則結果是空的抽象路徑名。

3、File(String parent,String child):根據 parent 路徑名字符串和 child 路徑名字符串創建一個新 File 實例。

注意:在各個操作系統中,路徑的分隔符是不一樣的,例如:Windows中使用反斜槓:"\",Linux|Unix中使用正斜槓:"/"。在使用反斜槓時要寫成"\\"的形式,因爲反斜槓要進行轉義。如果要讓Java保持可移植性,應該使用File類的靜態常量File.pathSeparator。

方法:

(一)獲取文件屬性

例:獲取並顯示該文件的長度、是否可寫、最後修改日期以及文件路徑等屬性信息

import java.io.File;
import java.util.Date;

public class Iotest {
	public static void main(String[] args) {
	File f = new File("E:\\test","test.txt");
        System.out.println("文件長度:"+f.length()+"字節");
        System.out.println("文件或者目錄:"+(f.isFile()?"是文件":"不是文件"));
        System.out.println("文件或者目錄:"+(f.isDirectory()?"是目錄":"不是目錄"));
        System.out.println("是否可讀:"+(f.canRead()?"可讀取":"不可讀取"));
        System.out.println("是否可寫:"+(f.canWrite()?"可寫入":"不可寫入"));
        System.out.println("是否隱藏:"+(f.isHidden()?"是隱藏文件":"不是隱藏文件"));
        System.out.println("最後修改日期:"+new Date(f.lastModified()));
        System.out.println("文件名稱:"+f.getName());
        System.out.println("文件路徑:"+f.getPath());
        System.out.println("絕對路徑:"+f.getAbsolutePath());
		
	}
}

運行如下:

文件長度:0字節
文件或者目錄:是文件
文件或者目錄:不是目錄
是否可讀:可讀取
是否可寫:可寫入
是否隱藏:不是隱藏文件
最後修改日期:Mon Jul 08 11:19:28 CST 2019
文件名稱:test.txt
文件路徑:E:\test\test.txt
絕對路徑:E:\test\test.txt

(二)創建和刪除文件

  例:判斷文件是否存在,存在刪除,不存在則創建

import java.io.File;
import java.io.IOException;

public class Iotest {
	public static void main(String[] args) {
	File f = new File("E:\\test","test.txt");
        if(f.exists()) {
        	f.delete();
        }    
        
        try {
			f.createNewFile();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
}

(三)創建和刪除目錄

例:判斷目錄是否存在,存在刪除,不存在則創建

import java.io.File;

public class Iotest {
	public static void main(String[] args) {
        File f=new File("E:\\test1");   
        if(f.exists()) {
            f.delete();
        }
        f.mkdir();
    }
}

(四)遍歷目錄

File 類的 list() 方法提供了遍歷目錄功能,該方法有如下兩種重載形式。

1、String[] list()

該方法表示返回由 File 對象表示目錄中所有文件和子目錄名稱組成的字符串數組,如果調用的 File 對象不是目錄,則返回 null。

提示:list() 方法返回的數組中僅包含文件名稱,而不包含路徑。但不保證所得數組中的相同字符串將以特定順序出現,特別是不保證它們按字母順序出現。

2、 String[] list(FilenameFilter filter)

該方法的作用與 list() 方法相同,不同的是返回數組中僅包含符合 filter 過濾器的文件和目錄,如果 filter 爲 null,則接受所有名稱。

例:遍歷C盤根目錄下的所有文件和目錄,並顯示文件或目錄名稱、類型及大小

import java.io.File;
public class Iotest {
	public static void main(String[] args) {
		
		File f = new File("C:/");
		String[] fileList = f.list();
		for(int i = 0; i< fileList.length; i++) {
		    System.out.print(fileList[i] + "\t\t");
		    System.out.print((new File("C:/",fileList[i])).isFile()?"文件"+ "\t\t":"文件夾"+"\t\t");
                    System.out.println((new File("C:/",fileList[i])).length()+"字節");
		}
	}
}

由於 list() 方法返回的字符數組中僅包含文件名稱,因此爲了獲取文件類型和大小,必須先轉換爲 File 對象再調用其方法。如下所示的是實例的運行效果:

$Recycle.Bin		文件夾		0字節
Boot		文件夾		4096字節
bootmgr		文件		399860字節
Documents and Settings		文件夾		4096字節
DRIVERS		文件夾		0字節
Foxmail 7.2		文件夾		4096字節
Intel		文件夾		0字節
pagefile.sys		文件		8262529024字節
PerfLogs		文件夾		0字節
Program Files		文件夾		4096字節
Program Files (x86)		文件夾		4096字節
ProgramData		文件夾		4096字節
System Volume Information		文件夾		0字節
Users		文件夾		4096字節
Windows		文件夾		12288字節
嗨格式錄屏文件		文件夾		0字節
迅雷下載		文件夾		0字節

例:假設希望只列出目錄下的某些文件,這就需要調用帶過濾器參數的 list() 方法。首先需要創建文件過濾器,該過濾器必須實現 java.io.FilenameFilter 接口,並在 accept() 方法中指定允許的文件類型。

如下所示爲允許 SYS、TXT 和 BAK 格式文件的過濾器實現代碼:

import java.io.File;
import java.io.FilenameFilter;

public class FileTest implements FilenameFilter{

	@Override
	public boolean accept(File dir, String name) {
		// TODO Auto-generated method stub
		return  name.endsWith(".sys")||name.endsWith(".txt")||name.endsWith(".bak");
	}

}
import java.io.File;
public class Iotest {
	public static void main(String[] args) {
		
		File f = new File("C:/");
		String[] fileList = f.list(new FileTest());
		for(int i = 0; i< fileList.length; i++) {
		    System.out.print(fileList[i] + "\t\t");
		    System.out.print((new File("C:/",fileList[i])).isFile()?"文件"+ "\t\t":"文件夾"+"\t\t");
                    System.out.println((new File("C:/",fileList[i])).length()+"字節");
		}
	}
}

運行如下:

pagefile.sys		文件		8262529024字節

RandomAccessFile

public class RandomAccessFile extends Object implements DataOutput, DataInput, Closeable

RandomAccessFile既可以讀取文件內容,也可以向文件輸出數據。同時支持“隨機訪問”的方式,可以直接跳轉到文件的任意地方來讀寫數據。與OutputStream、Writer等輸出流不同的是RandomAccessFile允許自由定義文件記錄指針,RandomAccessFile可以不從開始的地方開始輸出,因此RandomAccessFile可以向已存在的文件後追加內容。如果程序需要向已存在的文件後追加內容,則應該使用RandomAccessFile。
RandomAccessFile的一個重要使用場景就是網絡請求中的多線程下載及斷點續傳。

構造方法:

1、RandomAccessFile(File file, String mode)

2、RandomAccessFile(String name, String mode)

RandomAccessFile類有兩個構造函數,其實這兩個構造函數基本相同,只不過是指定文件的形式不同——一個需要使用String參數來指定文件名,一個使用File參數來指定文件本身。除此之外,創建RandomAccessFile對象時還需要指定一個mode參數,該參數指定RandomAccessFile的訪問模式,一共有4種模式:

1)r:表示以只讀方式打開,調用結果對象的任何write方法都將導致拋出IOException

2)rw:打開以便讀取和寫入,如果該文件尚不存在,則嘗試創建該文件

3)rws:打開以便讀取和寫入,相對於"rw",還要求對文件內容或元數據的每個更新都同步寫入到底層存儲設備

4)rwd:打開以便讀取和寫入,相對於"rw",還要求對文件內容的每個更新都同步寫入到底層存儲設備

示例:讀寫文件

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

public class Iotest {
	public static void main(String[] args) throws IOException {
		File file=new File("E:\\test\\words.txt");
		if(file.exists()) {   
			file.delete();
            try {
				file.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
                }
		
		RandomAccessFile raf=new RandomAccessFile(file,"rw");
		String str1="晴天,陰天,多雲,小雨,大風,中雨,小雪,雷陣雨";
		String str2=new String(str1.getBytes("GBK"),"iso8859-1");    //如果不轉換編碼,寫入文件的是亂碼
		raf.writeBytes(str2);    
		
		System.out.println("當前文件指針的位置:"+raf.getFilePointer());
		
		raf.seek(6);    //移動文件指針
		System.out.println("從文件頭跳過6個字節,現在文件內容如下:");
		byte[] buffer=new byte[2];
		int len=0;
		while((len=raf.read(buffer,0,2))!=-1)
		{
		    System.out.print(new String(buffer,0,len));    //輸出文件內容
		}
		
	}
}		

運行如下:

當前文件指針的位置:48
從文件頭跳過6個字節,現在文件內容如下:
陰天,多雲,小雨,大風,中雨,小雪,雷陣雨

 

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