1.File类

File类是IO包中唯一代表磁盘文件本身的对象。

File 类定义了一些与平台无关的方法来操纵文件,通过调用File 类提供的各种方法,能够完成创建、删除文件,重命名文件,判断文件的读写权限及文件是否存在,设置和查询文件的最近修改时间等操作。

Java能正确处理UNIX和Windows/DOS约定路径分隔符。如果在Windows版本的Java下用斜线(/),路径处理依然正确。记住:如果Windows/DOS使用反斜线(\)的约定,就需要在字符串内使用它的转义序列(\\)。Java 约定是用UNIX和URL风格的斜线来作路径分隔符。

file方法集合测试:

package dataStructure;

import java.io.File;

public class FileDemo {

	public static void main(String[] args) {
		File f=new File("c:\\2.txt");
		if (f.exists()) 
			f.delete();
		else 
			try {
				f.createNewFile();
			} catch (Exception e) {
				// TODO: handle exception
				System.out.println(e.getMessage());
			}
			System.out.println("文件名: "+f.getName());
			System.out.println("文件路径: "+f.getPath());
			System.out.println("绝对路径: "+f.getAbsolutePath());
			System.out.println("父文件夹名: "+f.getParent());
			System.out.println(f.exists()?"文件存在":"文件不存在");
			System.out.println(f.canWrite()?"文件可写":"文件不可写");
			System.out.println(f.canRead()?"文件可读":"文件不可读");
			System.out.println(f.isDirectory()?"是":"不是"+"目录");
			System.out.println(f.isFile()?"是":"不是"+"文件");
			System.out.println(f.isAbsolute()?"是":"不是"+"绝对路径");
			System.out.println("文件最后修改时间"+f.lastModified());
			System.out.println("文件大小"+f.length()+"Bytes");

		
	}
}

二.RandomAccessFile类

RandomAccessFile类可以说是Java语言中功能最为丰富的文件访问类,它提供了众多的文件访问方法。

RandomAccessFile类支持“ 随机访问"方式,可以跳转到文件的任意位置处读写数据。在要访问一个文件的时候,不想把文件从头读到尾,而是希望像访问一个数据库一样访问一个文本文件,这时使用RandomAccessFile类就是最佳选择。
RandomAcessFile对象类有个位置指示器,指向当前读写处的位置,当读写n个字节后,文件指示器将指向这n个字节后面的下一个字节处。

刚打开文件时,文件指示器指向文件的开头处,可以移动文件指示器到新的位置,随后的读写操作将从新的位置开始。RandomAccessFile在数据等长记录格式文件的随机(相对顺序而言)读取时有很大的优势,但该类仅限于操作文件,不能访问其他的IO设备,如网络、内存映像等。

package dataStructure;

/*RandomAccessFile的例子往文件中写入3名员工的信息,然后按照第2名员工、第1名员工、第3名员工的先后顺序读出。RandomAcessFile可以以只读或读写方式打开文件,具体使用哪种方式取决于用户创建RandomAcessFile类对象的构造方法。方式取决于用户创建RandomAcessFile类对象的构造方法。*/

import java.io.RandomAccessFile;

public class RamdomFileDemo {

	public static void main(String[] args) throws Exception {
		Employee e1= new Employee("zhangsan", 23);
		Employee e2=new Employee("lisi", 24);
		Employee e3= new Employee("wangwu", 25);
		//读写方式
		RandomAccessFile ra = new RandomAccessFile("D:\\1.txt","rw");
		ra.write(e1.name.getBytes());
		ra.writeInt(e1.age);
		ra.write(e2.name.getBytes());
		ra.writeInt(e2.age);
		ra.write(e3.name.getBytes());
		ra.writeInt(e3.age);
		
		ra.close();
		
		//只读方式
		RandomAccessFile raf = new RandomAccessFile("D:\\\\1.txt", "r");
		int len =8;
		
		raf.skipBytes(12);//跳过第1个员工的信息,其姓名8字节,年龄4字节
		System.out.println("第二个");
		String str = "";
		for (int i = 0; i < len; i++) {
			str =str +(char)raf.readByte();			
		}
		System.out.println("name:"+str);
		System.out.println("age:"+raf.readInt());
		
		
		System.out.println("第一个");
		raf.seek(0);       ///将文件指针移动到文件开始位置
		str="";
		for (int i = 0; i < len; i++) {
			str=str+(char)raf.readByte();
		}
		System.out.println("name:"+str);
		System.out.println("age:"+raf.readInt());
		
		
		System.out.println("第三个");
		raf.skipBytes(12);
		str="";
		for (int i = 0; i < len; i++) {
			str=str+(char)raf.readByte();
		}
		System.out.println("name:"+str);
		System.out.println("age:"+raf.readInt());
		raf.close();
	}
	
}

class Employee{
	String name;
	int age;
	final static int LEN=8;
	public Employee(String name ,int age) {
		//要保证每条记录的大小相同,字段长度相等才能准确定位每条记录在文件中的位置
		// TODO Auto-generated constructor stub
		if(name.length()>LEN) {
			//子字符串中的第1个字符对应的是原字符串中的脚标为beginIndex处的字符,但最后的字符
			//对应的是原字符串中的脚标为endIndex-1 处的字符,而不是endIndex处的字符。
			name= name.substring(0,8);
		}else {
			while (name.length()<LEN) {
				name=name+"\u0000";				
			}
		}
		this.name=name;
		this.age=age;
	}
}

三.流类

Java的流式输入/输出建立在4个抽象类的基础上: InputStream、 OutputStream、 Reader 和Writer。

它们用来创建具体流式子类。尽管程序通过具体子类进行输入/输出操作,但顶层的类定义了所有流类的基本通用功能。

InputStream和OutputStream被设计成字节流类,而Reader和Writer 被设计成字符流类。字节流类和字符流类形成分离的层次结构。一般来说,处理字符或字符串时应使用字符流类,处理字节或二进制对象时应使用字节流类。

一般在操作文件流时, 不管是字节流还是字符流,都可以按照以下的方式进行。

(1) 使用File类找到一个文件。

(2)通过File类的对象去实例化字节流或字符流的子类。

(3)进行字节(字符)的读、写操作。

(4)关闭文件流。

1.字节流

package dataStructure;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/*用FileOutputStream类向文件写入一个字符串,
用FileInputStream类读出写入的内容*/
public class StreamDemo {

	public static void main(String[] args) {
		//(1) 使用File类找到一个文件。
		File f= new File("d:\\demo.txt");
		
		//写操作
		OutputStream out= null;
		//(2)通过File类的对象去实例化字节流或字符流的子类。
		/*通过File的对象去实例化OutputStream的对象,此时是通过其子类的FileOutputStream实例
		 * 化的OutputStream对象,属于对象的向上转型*/
		try {
			out = new FileOutputStream(f);
		} catch (FileNotFoundException e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		
		/*因为字节流主要以操作byte数组为主,所以将字符串转为字节数组*/
		byte b[]= "Hello World".getBytes();
		try {
			out.write(b);//(3)进行字节(字符)的读、写操作。
		} catch (IOException e1) {
			// TODO: handle exception
			e1.printStackTrace();
		}
		try {
			out.close();//(4)关闭文件流。
		} catch (IOException e2) {
			// TODO: handle exception
			e2.printStackTrace();
		}
		
		
		//读操作
		InputStream in = null;
		try {
			in = new FileInputStream(f);
		} catch (FileNotFoundException e3) {
			// TODO: handle exception
			e3.printStackTrace();
		}
		
		/*因为字节流主要以操作byte数组为主,声明数组用于接收文件读进来的数据*/
		byte b1[]= new byte[1024];
		int i= 0;
		try {
			i= in.read(b1);//将文件内容读入数组,并返回读入数据的个数
		} catch (IOException e4) {
			// TODO: handle exception
			e4.printStackTrace();
		}
		try {
			in.close();
		} catch (IOException e5) {
			// TODO: handle exception
		    e5.printStackTrace();
		}
		//将byte数组转为字符串输出
		System.out.println(new String(b1,0,i));
	}
}

2.字符流

package dataStructure;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;

/*用FileWriter类向文件写入一个字符串,
用FileReader类读出写入的内容*/
public class Chardemo {

	public static void main(String[] args) {
		//(1) 使用File类找到一个文件。
		File f= new File("d:\\demo.txt");
		
		//写操作
		Writer out= null;
		//(2)通过File类的对象去实例化字节流或字符流的子类。
		/*通过File的对象去实例化Writer的对象,此时是通过其子类的FileWriter实例
		 * 化的Writer对象,属于对象的向上转型*/
		try {
			out = new FileWriter(f);
		} catch (IOException e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		
		/*字符流主要以操作字符为主*/
		String str= "Hello World";
		try {
			out.write(str);//(3)进行字节(字符)的读、写操作。
		} catch (IOException e1) {
			// TODO: handle exception
			e1.printStackTrace();
		}
		try {
			out.close();//(4)关闭文件流。
		} catch (IOException e2) {
			// TODO: handle exception
			e2.printStackTrace();
		}
		
		
		//读操作
		Reader in = null;
		try {
			in = new FileReader(f);
		} catch (FileNotFoundException e3) {
			// TODO: handle exception
			e3.printStackTrace();
		}
		
		/*因为字节流主要以操作char数组为主,声明数组用于接收文件读进来的数据*/
		char c1[]= new char[1024];
		int i= 0;
		try {
			i= in.read(c1);//将文件内容读入数组,并返回读入数据的个数
		} catch (IOException e4) {
			// TODO: handle exception
			e4.printStackTrace();
		}
		try {
			in.close();
		} catch (IOException e5) {
			// TODO: handle exception
		    e5.printStackTrace();
		}
		//将byte数组转为字符串输出
		System.out.println(new String(c1,0,i));
	}
}

FileWriter类并不是直接继承于Writer类,而是继承了Writer类的子类(OutputStreamWriter),此类为字节流和字符流的转换类

说明:真正读取的数据还是字节,只是在内存中将字节转换成了字符。

则字符流用到了缓冲区,而字节流没有(用Writer类中的flush()方法强制清空缓存区)