现在的位置: 首页 > 综合 > 正文

File类与RandomAccessFile类范例

2013年10月18日 ⁄ 综合 ⁄ 共 4756字 ⁄ 字号 评论关闭
public class File
extends Object
implements Serializable, Comparable<File>

文件和目录路径名的抽象表示形式。

用户界面和操作系统使用与系统相关的路径名字符串 来命名文件和目录。此类呈现分层路径名的一个抽象的、与系统无关的视图。抽象路径名 有两个组件:

  1. 一个可选的与系统有关的前缀 字符串,比如盘符,"/" 表示 UNIX 中的根目录,"\\\\" 表示 Microsoft Windows UNC 路径名。
  2. 零个或更多字符串名称 的序列。

抽象路径名中的第一个名称是目录名,对于 Microsoft Windows UNC 路径名则是主机名。抽象路径名中第一个名称之后的每个名称表示一个目录;最后一个名称既可以表示目录,也可以表示文件。 抽象路径名没有前缀和名称序列。

路径名字符串与抽象路径名之间的转换与系统有关。将抽象路径名转换为路径名字符串时,每个名称与下一个名称之间用一个默认分隔符 隔开。默认名称分隔符由系统属性file.separator 定义,可通过此类的公共静态字段
separatorseparatorChar 使其可用。将路径名字符串转换为抽象路径名时,可以使用默认名称分隔符或者底层系统支持的任何其他名称分隔符来分隔其中的名称。

无论是抽象路径名还是路径名字符串,都可以是绝对 路径名或相对 路径名。绝对路径名是完整的路径名,不需要任何其他信息就可以定位它所表示的文件。相反,相对路径名必须使用取自其他路径名的信息进行解释。默认情况下,java.io 包中的类总是根据当前用户目录来解析相对路径名。此目录由系统属性user.dir 指定,通常是 Java 虚拟机的调用目录。

调用此类的 getParent() 方法可以获取抽象路径名的 路径名,它由路径名前缀以及路径名名称序列中的每个名称(最后一个除外)组成。对于任何具有绝对抽象路径名的File 对象,如果其绝对抽象路径名以某个目录的绝对路径名开头,那么该目录的绝对路径名是该
File 对象的祖先。例如,抽象路径名"/usr" 表示的目录是路径名 "/usr/local/bin" 所表示目录的一个祖先。

在处理 UNIX 平台的根目录,以及 Microsoft Windows 平台的盘符、根目录和 UNC 路径名时,将用到前缀这一概念。如下所示:

  • 对于 UNIX 平台,绝对路径名的前缀始终是 "/"。相对路径名没有前缀。表示根目录的绝对路径名的前缀为 "/" 且名称序列为空。
  • 对于 Microsoft Windows 平台,包含盘符的路径名前缀由驱动器号和一个 ":" 组成。如果路径名是绝对路径名,还可能后跟"\\"。UNC 路径名的前缀是
    "\\\\";主机名和共享名是名称序列中的前两个名称。没有指定驱动器的相对路径名没有前缀。

此类的实例可能表示(也可能不表示)实际文件系统对象,如文件或目录。如果它表示这种对象,那么该对象驻留在一个分区 中。分区是文件系统特定于操作系统的存储分区。一个存储设备(例如,物理磁盘驱动器、闪存、CD-ROM)可以包含多个分区。对象(如果有)将驻留在此路径名(绝对形式)某个祖先指定的分区上。

文件系统可以实现对实际文件系统对象上的某些操作(比如,读、写、执行)进行限制。这些限制统称为访问权限。文件系统可以对一个对象设置多个访问权限。例如,一个设置可能适用于对象的所有者,另一个设置则可能适用于所有其他用户。对象上的访问权限可能导致此类的某些方法执行失败。

File 类的实例是不可变的;也就是说,一旦创建,File 对象表示的抽象路径名将永不改变。 

//遍历F盘所有文件,计算文件数以及文件夹数
import java.io.*;

public class FileDemo {
	public static int count = 0;
	public static int count2 = 0;
	public static void main(String[] args) {
		File f = new File("F:" + File.separator);     //为保证java程序平台无关性,用File.separator代替分隔符
		print(f);
		System.out.println(count+"      "+count2);
	}

	public static void print(File file) {
		if (file != null) {
			if (file.isDirectory()) {                 //isDirectory()方法用以判断file是否为目录(文件夹)
				count2++;
				File files[] = file.listFiles();
				if (files != null) {
					for (int i = 0; i < files.length; i++) {
						print(files[i]);
					}
				}
			} else {
				System.out.println(file.getPath());  //取路径
				count++;
			}
		}
	}
}

public class RandomAccessFile
extends Object
implements DataOutput, DataInput, Closeable

此类的实例支持对随机访问文件的读取和写入。随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机访问文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针可以通过getFilePointer 方法读取,并通过
seek 方法设置。

通常,如果此类中的所有读取例程在读取所需数量的字节之前已到达文件末尾,则抛出 EOFException(是一种 IOException)。如果由于某些原因无法读取任何字节,而不是在读取所需数量的字节之前已到达文件末尾,则抛出IOException,而不是
EOFException。需要特别指出的是,如果流已被关闭,则可能抛出 IOException。 

//实施对Employe文件的字节式读取和写入
import java.io.*;
import java.util.*;

class Employe {
	String name;
	float salary;
	Date hireday;

	Employe() {
	};

	Employe(String n, float s, int year, int month, int day) {
		name = n;
		salary = s;
		GregorianCalendar calendar = new GregorianCalendar(year, month, day);
		hireday = calendar.getTime();
	}

	public String toString() {
		return getClass().getName() + "[name=" + name + ",salary=" + salary
				+ ",hireDay=" + hireday + "]";
	}

	public void readData(DataInput in) throws IOException {
		name = DataIO.readFixedString(NAME_SIZE, in);
		salary = in.readFloat();
		int y = in.readInt();
		int m = in.readInt();
		int d = in.readInt();
		GregorianCalendar calendar = new GregorianCalendar(y, m - 1, d);
		hireday = calendar.getTime();
	}

	public void writeData(DataOutput out) throws IOException {
		DataIO.writeFixedString(name, NAME_SIZE, out);
		out.writeDouble(salary);

		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(hireday);
		out.writeInt(calendar.get(Calendar.YEAR));
		out.writeInt(calendar.get(Calendar.MONTH) + 1);
		out.writeInt(calendar.get(Calendar.DAY_OF_MONTH));
	}

	public static final int NAME_SIZE = 40;
	public static final int RECORD_SIZE = 2 * NAME_SIZE + 8 + 4 + 4 + 4;

}

class DataIO {
	public static String readFixedString(int size, DataInput in)
			throws IOException {
		StringBuilder b = new StringBuilder(size);
		int i = 0;
		boolean more = true;
		while (more && i < size) {
			char ch = in.readChar();
			i++;
			if (ch == 0)
				more = false;
			else
				b.append(ch);
		}
		in.skipBytes(2 * (size - i));      //skipBytes()方法用以跳过指定字节数
		return b.toString();
	}

	public static void writeFixedString(String s, int size, DataOutput out)
			throws IOException {
		for (int i = 0; i < size; i++) {
			char ch = 0;
			if (i < s.length())
				ch = s.charAt(i);
			out.writeChar(ch);
		}
	}
}

public class RandomFileTest {
	public static void main(String[] args) throws IOException {
		Employe[] staff = new Employe[3];
		staff[0] = new Employe("jack", 50, 1991, 9, 1);
		staff[1] = new Employe("tom", 30, 1998, 9, 1);
		staff[2] = new Employe("bob", 60, 1999, 9, 1);

		DataOutputStream out;
		try {
			out = new DataOutputStream(new FileOutputStream("employe.dat"));
			for (int i = 0; i < staff.length; i++) {
				staff[i].writeData(out);
			}
			out.close();

			RandomAccessFile in = new RandomAccessFile("employe.dat", "r");
			int n = (int) (in.length() / Employe.RECORD_SIZE);
			Employe[] newStaff = new Employe[n];

			for (int i = n - 1; i >= 0; i--) {
				newStaff[i] = new Employe();
				in.seek(i * Employe.RECORD_SIZE);   //seek()方法用以将指针移到指定位置
				newStaff[i].readData(in);
			}
			in.close();

			for (int i = 0 ; i<newStaff.length;i++)
				System.out.println(newStaff[i].toString());
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		}
	}
}

抱歉!评论已关闭.