Java文件操作有多种类:文本文件IO、二进制文件IO、随机文件IO、对象序列化IO操作。下面将对每种操作进行介绍:
1、文本文件IO
Java.io包提供以Wirter和Reader为超类的两组API类进行文本文件IO的处理和操作。
文本文件IO输出类为PrintWriter,提供了具体文本输出的方法,使输出数据流成为可写的格式化的文本字符串。BufferedWriter用户文本文件的缓冲输出。PrintWriter常用的方法有print、println、flush、close。
文本文件IO输入类为BufferedReader和FileReader。BufferedReader实现了对文本文件读入的功能,常用的方法有read()、readLine()、skip(long chars)、close()。readLine当读入到文件节后为,读入的数据为null;read方法读到文件结尾时,其内容为-1。
下面为一个例子
package com.file; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; public class TextFileIO { public void FileWrite(String name) { File outFile = new File(name); try { PrintWriter out = new PrintWriter(new BufferedWriter( new FileWriter(outFile))); out.println("This line will be written to the file."); out.println("\tAuthor:Jerome"); out.close(); } catch (IOException e) { e.printStackTrace(); } finally { } } public void FileRead(String name) { File inFile = new File(name); try { BufferedReader in = new BufferedReader(new FileReader(inFile)); String line = in.readLine(); while (line != null) { System.out.println(line); line = in.readLine(); } in.close(); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { TextFileIO fileOperator = new TextFileIO(); fileOperator.FileWrite("TextFile.txt"); fileOperator.FileRead("TextFile.txt"); } }
2、二进制文件IO
Java用来进行二进制文件IO的API类为数据流IO(XXXStream)。常用的二进制文件输出类有DataOutputStream、BufferedOutputStream、FileOutputStream。
DataOutputStream实现了DataOutput接口的所有二进制文件输出方法,writeUF()方法执行对指定字符串输出时,首先利用两个字节表示字符串中的字节数。
DataInputStream实现了DataInput接口的二进制文件输入操作的接口。下面是二进制文件IO操作的一个例子
package com.file; import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class BinaryFileIO { public void BinaryFileWrite(String fileName) { try { DataOutputStream out = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(fileName))); out.writeBoolean(true); out.writeChar('A'); out.writeDouble(99.9); out.writeChars("abcdefg"); out.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void BinaryFileRead(String fileName) { DataInputStream in; try { in = new DataInputStream(new FileInputStream(fileName)); boolean flag = in.readBoolean(); char ch = in.readChar(); double d = in.readDouble(); char[] chars = new char[7]; for (int i = 0; i < 7; i++) { chars[i] = in.readChar(); } System.out.println(flag + "," + ch + "," + d + "," + new String(chars)); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String[] args) { BinaryFileIO fileOperator = new BinaryFileIO(); fileOperator.BinaryFileWrite("BinaryFile.txt"); fileOperator.BinaryFileRead("BinaryFile.txt"); } }
3、对象序列化
序列化的目的是为了在二进制文件执行对对象文件的IO,保证对象写出和读入的一致性。序列化的对象必须实现了Serializable接口的实例。ObjectOutputStream和ObjectInputStream处理对象序列化IO。下面对象序列化的一个例子。
package com.file; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; enum SEX { Male, FEMALE; } class Person implements Serializable { private String name; private int age; private SEX sex; Person(String name, int age, SEX sex) { this.name = name; this.age = age; this.sex = sex; } public String getName() { return name; } public int getAge() { return age; } public SEX getSex() { return sex; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]"; } } public class ObjectSerialIO { public void ObjectSerialWrite(String fileName, Person writeObject) { try { ObjectOutputStream out = new ObjectOutputStream( new BufferedOutputStream(new FileOutputStream(fileName))); out.writeObject(writeObject); out.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void ObjectSerialRead(String fileName) { ObjectInputStream in; try { in = new ObjectInputStream(new FileInputStream(fileName)); Person person = (Person) in.readObject(); System.out.println("Read serial object" + person); in.close(); } catch (IOException | ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String[] args) { ObjectSerialIO objectSerialOperator = new ObjectSerialIO(); Person person = new Person("Zhangsan", 20, SEX.Male); objectSerialOperator.ObjectSerialWrite("ObjectSerialFile", person); objectSerialOperator.ObjectSerialRead("ObjectSerialFile"); } }
4、随机文件IO
上面讨论的所有文件IO技术都是按次序执行数据的读写操作。在实际应用中经常需要对文件进行随机访问,Java中通过RandomAccessFile类提供用来创建和执行随机文件IO。常用的方法有long getFilePointer()返回当前文件指针的字节位置,开始位置为0,length()返回文件的字节数,seek(long length),按指定位置设置文件指针,setLength(long length)按指定长度设置文件字节长度,int skiBytes(int bytes)从文件指针当前位置跳过指定字节数,并返回实际跳过的字节数。RandomAccessFile支持如下文件访问模式:
“r"——只读;"rw"——读写;"rws"——协调式读写,在多线程/多用户文件读写中,只有一个线程/用户可以访问文件。执行更新文件数据以及更新关于文件本身信息metadata的操作。
"rws"——协调式读写。与“rws”相同,但每次访问不涉及对文件本身信息metadta的更新操作。
文件本身信息metadta包括:文件长度、更新日期以及其他文件信息。
由于随机文件IO例子比较多,这里就不介绍了。
5、其他
最后介绍一下用Scanner读入文件,Scanner不仅可以从标准设备,如键盘,也可以从指定文件,或指定服务器读入数据。下面是一个简单的例子。
package com.file; import java.util.Scanner; public class ScannerIO { public static void main(String[] args) { Scanner in = new Scanner(System.in); int i = in.nextInt(); double d = in.nextDouble(); String str = in.nextLine(); System.out.println(i + "," + d + "," + str); in.close(); } }