第 14章
输入 输出
– 档案
– 位串流
– 字符串流
File类别
不同的操作系统对于文件系统路径的设定各有差别
Windows
Linux
"C:\\Workspace\\CH14\\"
"/home/justin/workspace/ch14"
File类别
File实例用作一个档案或目录的抽象表示
File file = new File(args[0]);
if(file.isFile()) { //是否为档案
System.out.println(args[0] + "檔案 ");
System.out.print(
file.canRead()?"可读 ","不可读 ");
System.out.print(
file.canWrite()?"可写 ","不可写 ");
System.out.println(
file.length() +"位組 ");
}
File类别
else {
//列出所有的档案及目录
File[] files = file.listFiles();
ArrayList<File> fileList =
new ArrayList<File>();
for(int i = 0; i < files.length; i++) {
//先列出目录
if(files[i].isDirectory()) {//是否为目录
//取得路径名
System.out.println("[" +
files[i].getPath() + "]");
}
else {
//档案先存入 fileList,待会再列出
fileList.add(files[i]);
}
}
File类别
//列出档案
for(File f,fileList) {
System.out.println(f.toString());
}
System.out.println();
}
RandomAccessFile类别
File file = new File(args[0]);
//建立 RandomAccessFile实例并以读写模式开启档案
RandomAccessFile randomAccessFile =
new RandomAccessFile(file,"rw");
for(int i = 0; i < students.length; i++) {
//使用对应的 write方法写入数据
randomAccessFile.writeChars(students[i].getName());
randomAccessFile.writeInt(students[i].getScore());
}
RandomAccessFile类别
//使用 seek()方法操作存取位置
randomAccessFile.seek((num-1) * Student.size());
Student student = new Student();
//使用对应的 read方法读出数据
student.setName(readName(randomAccessFile));
student.setScore(randomAccessFile.readInt());
System.out.println("姓名," + student.getName());
System.out.println("分数," + student.getScore());
//设定关闭档案
randomAccessFile.close();
RandomAccessFile类别
private static String readName(RandomAccessFile randomAccessfile)
throws IOException {
char[] name = new char[15];
for(int i = 0; i < name.length; i++)
name[i] = randomAccessfile.readChar();
//将空字符取代为空格符并传回
return new String(name).replace('\0',' ');
}
RandomAccessFile类别
读写档案时几个必要的流程
– 开启档案并指定读写方式
– 使用对应的写入方法
– 使用对应的读出方法
– 关闭档案
InputStream,OutputStream
数据流动抽象化为一个串流( Stream)
InputStream,OutputStream
InputStream是所有表示位输入串流的类别之父类别
– System中的标准输入串流 in对象就是一个
InputStream类型的实例
OutputStream是所有表示位输出串流的类别之父类别
– System中的标准输出串流对象 out其类型是
java.io.PrintStream,OutputStream的子类别
InputStream,OutputStream
很少直接操作 InputStream或 OutputStream
上的方法,这些方法比较低阶
通常会操作它们的子类别
try {
System.out.print("输入字元,");
System.out.println("输入字符十进制 表示," +
System.in.read());
}
catch(IOException e) {
e.printStackTrace();
}
FileInputStream,FileOutputStream
建立 FileInputStream或 FileOutputStream的实例时,必须指定档案位置及文件名,实例被建立时档案的串流就会开启
不使用串流时,您必须关闭档案串流,以释放与串流相依的系统资源
FileInputStream fileInputStream =
new FileInputStream(new File(args[0]));
FileOutputStream fileOutputStream =
new FileOutputStream(new File(args[1]));

fileInputStream.close();
fileOutputStream.close();
FileInputStream,FileOutputStream
while(true) {
if(fileInputStream.available() < 1024) {
//剩余的资料比 1024字节少
//一位一位读出再写入目标文件
int remain = -1;
while((remain = fileInputStream.read())
!= -1) {
fileOutputStream.write(remain);
}
break;
}
else {
//从来源档案读取数据至缓冲区
fileInputStream.read(buffer);
//将数组数据写入目标文件
fileOutputStream.write(buffer);
}
}
FileInputStream,FileOutputStream
以附加的模式来写入档案
FileOutputStream fileOutputStream =
new FileOutputStream(args[1],true);
BufferedInputStream,BufferedOutputStream
BufferedInputStream的资料成员 buf是个位数组,默认为 2048字节
BufferedOutputStream的资料成员 buf是个位数组,默认为 512个字节
BufferedInputStream,BufferedOutputStream
BufferedInputStream bufferedInputStream =
new BufferedInputStream(
new FileInputStream(srcFile));
BufferedOutputStream bufferedOutputStream =
new BufferedOutputStream(
new FileOutputStream(desFile));
System.out.println("复制档案," +
srcFile.length() +"字节 ");
while(bufferedInputStream.read(data) != -1) {
bufferedOutputStream.write(data);
}
//将缓冲区中的数据全部写出
bufferedOutputStream.flush();
//关闭串流
bufferedInputStream.close();
bufferedOutputStream.close();
BufferedInputStream,BufferedOutputStream
BufferedInputStream、
BufferedOutputStream并没有改变
InputStream或 OutputStream的行为
只是在操作对应的方法之前,动态的为它们加上一些是缓冲区功能
DataInputStream,DataOutputStream
DataOutputStream dataOutputStream =
new DataOutputStream(
new FileOutputStream(args[0]));
for(Member member,members) {
//写入 UTF字符串
dataOutputStream.writeUTF(member.getName());
//写入 int资料
dataOutputStream.writeInt(member.getAge());
}
//出清所有数据至目的地
dataOutputStream.flush();
//关闭串流
dataOutputStream.close();
提供一些对 Java基本数据型态写入的方法
DataInputStream,DataOutputStream
DataInputStream dataInputStream =
new DataInputStream(
new FileInputStream(args[0]));
//读出数据并还原为对象
for(int i = 0; i < members.length; i++) {
//读出 UTF字符串
String name = dataInputStream.readUTF();
//读出 int资料
int score = dataInputStream.readInt();
members[i] = new Member(name,score);
}
//关闭串流
dataInputStream.close();
ObjectInputStream,ObjectOutputStream
要直接储存对象,定义该对象的类别必须实作 java.io.Serializable界面
serialVersionUID代表了可串行化对象版本
从档案读回对象时两个对象的
serialVersionUID不相同的话,就会丢 出
java.io.InvalidClassException
public class User implements Serializable {
private static final long serialVersionUID = 1L;

}
ObjectInputStream,ObjectOutputStream
在写入对象时,您要使用 writeObject()方法
读出对象时则使用 readObject()方法,被读出的对象都是以 Object的型态传回
ObjectInputStream,ObjectOutputStream
public static void writeObjectsToFile(
Object[] objs,String filename) {
File file = new File(filename);
try {
ObjectOutputStream objOutputStream =
new ObjectOutputStream(
new FileOutputStream(file));
for(Object obj,objs) {
//将对象写入档案
objOutputStream.writeObject(obj);
}
//关闭串流
objOutputStream.close();
}
catch(IOException e) {
e.printStackTrace();
}
}
ObjectInputStream,ObjectOutputStream
FileInputStream fileInputStream =
new FileInputStream(file);
ObjectInputStream objInputStream =
new ObjectInputStream(fileInputStream);
while(fileInputStream.available() > 0) {
list.add((User) objInputStream.readObject());
}
objInputStream.close();
ObjectInputStream,ObjectOutputStream
//附加模式
ObjectOutputStream objOutputStream =
new ObjectOutputStream(
new FileOutputStream(file,true)) {
//如果要附加对象至档案后
//必须重新定义这个方法
protected void writeStreamHeader()
throws IOException {}
};
for(Object obj,objs) {
//将对象写入档案
objOutputStream.writeObject(obj);
}
objOutputStream.close();
SequenceInputStream
可以看作是数个 InputStream对象的组合
当一个 InputStream对象的内容读取完毕后,
它就会取出下一个 InputStream对象,直到所有的 InputStream物件都读取完毕
SequenceInputStream
//建立 SequenceInputStream
//并使用 BufferedInputStream
BufferedInputStream bufInputStream =
new BufferedInputStream(
new SequenceInputStream(enumation),
8192);
BufferedOutputStream bufOutputStream =
new BufferedOutputStream(
new FileOutputStream(filename),8192);
byte[] data = new byte[1];
//读取所有档案数据并写入目的地档案
while(bufInputStream.read(data) != -1)
bufOutputStream.write(data);
bufInputStream.close();
bufOutputStream.flush();
bufOutputStream.close();
PrintStream
使用 java.io.PrintStream可以自动为您进行字符转换的动作
默认会使用操作系统的编码来处理对应的字符转换动作
PrintStream printStream = new PrintStream(
new FileOutputStream(
new File("test.txt")));
printStream.println(1);
printStream.close();
ByteArrayInputStream,ByteArrayOutputStream
ByteArrayInputStream可以将一个数组当作串流输入的来源
ByteArrayOutputStream则可以将一个位数组当作串流输出的目的地
PushbackInputStream
拥有一个 PushBack缓冲区
从 PushbackInputStream读出数据后,只要
PushBack缓冲区没有满,就可以使用
unread()将资料推回串流的前端
Reader,Writer
在处理串流数据时,会根据系统默认的字符编码来进行字符转换
Reader,Writer是抽象类,在进行文本文件的字符读写时真正会使用其子类别
可以直接在建构 Reader的实例时,自行指定读取时的编码
InputStreamReader reader =
new InputStreamReader(byteArrayStream,"Big5");
InputStreamReader,OutputStreamWriter
要对 InputStream,OutputStream进行字符处理,可以使用 InputStreamReader、
OutputStreamWriter为加上字符处理的功能
FileInputStream fileInputStream =
new FileInputStream(args[0]);
//为 FileInputStream加上字符处理功能
InputStreamReader inputStreamReader =
new InputStreamReader(fileInputStream);
FileOutputStream fileOutputStream =
new FileOutputStream("backup_" + args[0]);
//为 FileOutputStream加上字符处理功能
OutputStreamWriter outputStreamWriter =
new OutputStreamWriter(fileOutputStream);
InputStreamReader,OutputStreamWriter
int ch = 0;
//以字符方式显示档案内容
while((ch = inputStreamReader.read()) != -1) {
System.out.print((char) ch);
outputStreamWriter.write(ch);
}
System.out.println();
inputStreamReader.close();
outputStreamWriter.close();
可以自行指定字符编码
InputStreamReader inputStreamReader =
new InputStreamReader(fileInputStream,"Big5");
FileReader,FileWriter
想要存取的是一个文本文件,可直接使用
java.io.FileReader,java.io.FileWriter类别
FileReader fileReader =
new FileReader(args[0]);
FileWriter fileWriter =
new FileWriter(args[0] + ".txt");
int in = 0;
char[] wlnChar = {'\r','\n'};
while((in = fileReader.read()) != -1) {
if(in == '\n') {
//写入 "\r\n"
fileWriter.write(wlnChar);
}
else
fileWriter.write(in);
}
fileReader.close();
fileWriter.close();
BufferedReader,BufferedWriter
System.in是个位串流,为了转换为字符串流,可使用 InputStreamReader为其进行字符转换,然后再使用 BufferedReader为其增加缓冲功能
BufferedReader reader =
new BufferedReader(new InputStreamReader(System.in));
BufferedReader,BufferedWriter
//缓冲 FileWriter字符输出串流
BufferedWriter bufWriter =
new BufferedWriter(new FileWriter(args[0]));
String input = null;
//每读一行进行一次写入动作
while(!(input =
bufReader.readLine()).equals("quit")) {
bufWriter.write(keyin);
// newLine()方法写入与操作系统相依的换行字符
bufWriter.newLine();
}
PrintWriter
除了接受 OutputStream实例作为自变量之外,PrintWriter还可以接受 Writer对象作为输出的对象
CharArrayReader,CharArrayWriter
可以将字符数组当作字符数据输出或输入的来源
PushbackReader
拥有一个 PushBack缓冲区,只不过
PushbackReader所处理的是字符
只要 PushBack缓冲区没有满,就可以使用
unread()将资料回推回串流的前端