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()方法强制清空缓存区)