2007年2月25日星期日

Java IO学习笔记(1) 转载

最近在看lucene的原代码,里面有好多Java 的I/O操作,现在顺带复习一下,网上找到一个东东很好,
于是转载过来http://blog.csdn.net/yangxp_82/archive/2005/09/13/479306.aspx

java IO最关键的四个父类:InputStream、OutputStream、Reader、Writer。它们都是public abstract class。
InputSream和OutputStream对于数据的传送是以“byte”为单位的,而Reader和Writer对于数据的传送是以“character”为单位的。所以我们看到java.io包中的类大体上可以分为两大类,一类是以byte处理为主的Stream类,它们都是以XXXStream方式命名的;一类是以character处理为主的Reader/Writer类,它们都是以XXXReader或XXXWriter的方式命名的。
InputStream类方法简介:
InputStream是输入字节数据用的类,所以InputStream类提供了3种重载的read方法(具体方法参见API)。
如果我们要知道这个流中还有多少个byte的数据可以读取时可以调用available方法,注意的是如果InputStream对象调用这个方法的话,它只会返回0,这个方法必须由继承InputStream类的子类对象调用才有用,另外它会抛出IOException异常,必须对此异常进行处理。
如果我们想跳过一些字节来读取的话可以调用skip方法来跳过一些字节来读取。skip方法所需要的参数是long型的,指出要跳过的字节数。
流的处理是单向的,如果想重新读取已经读过的数据,我们必须进行一些处理。有些InputStream是不支持重新读取的(也就是不允许重新定位读取指针),这样我们在进行重新读取前最好先调用markSupported方法来检查一下这个InputStream对象是否支持重定位指针,如果通过,那么我们就可以先使用mark方法来指定指针的位置,然后调用reset方法来让指针指到你要求得位置。(注意的是reset方法可能抛出IOException异常)。
还有就是我们在使用完后,必须对我们打开的流进行关闭(close)。
OutputStream方法的介绍:
OutputStream提供了3个write方法来做数据的输出,这个是和InputStream是相对应的。
还有一个常用的清除缓冲区的方法就是flush。
最好就是close方法
Reader方法的介绍
Reader是输入字符数据用的,它所提供的方法跟InputStream基本一样。不过Reader类没有提供available方法,取而代之的是ready方法。
Writer方法的介绍
Writer类有5个write方法,具体可以查看API。
学习完上面的四个最最基本的四个抽象类之后,我们就来学习Java的节点类,这个对于理解使用IO来说是至关重要的,下面就用一个表格来简单说明,若要详细了解请查看API。
文件(File)
FileInputStream
FileOutputStream
FileReader
FileWriter

内存(数组)
ByteArrayInputStream
ByteArrayOutputStream
CharArrayReader
CharArrayWriter

内存(字符串)

StringReader
StringWriter

管道(Pipe)
PipeInputStream
PipeOutputStream
PipeReader
PipeWriter


下面就是一些必须学习的类(java.io.File)
这个类对文件的操作是至关重要的,对于它的学习必须深入,它不是一仅仅是我们概念中的文件,而且包括目录。详细细节请查看API。
RandomAccessFile对于IO系统来说也是很重要的,它与我们前面介绍的四个抽象类没有关系,它是直接继承自Object类,用于对文件进行随机读取操作。
下面给出一个文件操作的例子:
/**
* 学生类
* @author Sunny
* @version 1.0
*/
import java.io.*;
public class Student implements Serializable{
private String name;
private String id;
private int age;

/**
* 构造函数
* @param name
* @param id
* @param age
*/
public Student(String name, String id, int age) {
setName(name);
setId(id);
setAge(age);
}
/**
*
* @return int
*/
public int getAge() {
return age;
}
/**
*
* @param age
*/
public void setAge(int age) {
if(age>0 && age <100)
this.age = age;
else
this.age = 10;
}
/**
*
* @return String
*/
public String getId() {
return id;
}
/**
*
* @param id
*/
public void setId(String id) {
this.id = id;
}
/**
*
* @return String
*/
public String getName() {
return name;
}
/**
*
* @param name
*/
public void setName(String name) {
this.name = name;
}
}




/**
* 随即存取Student类
* @author Sunny
* @version 1.0
*/
import java.io.RandomAccessFile;
import java.io.IOException;
public final class RandomAccessStudent extends Student {
//name域所占的字节数
private static final int NAME_SIZE = 30;
//id域所占的字节数
private static final int ID_SIZE = 30;
//该对象所占的字节数
public static final int SISE = NAME_SIZE + ID_SIZE + 4;
/**
* 构造函数
* @param name
* @param id
* @param age
*/
public RandomAccessStudent(String name, String id, int age) {
super(name, id, age);
}
/**
* 从随即文件读取一个Student类
* @param file
* @throws IOException
*/
public void read(RandomAccessFile file) throws IOException {
setName(readName(file));
setId(readId(file));
setAge(file.readInt());
}
//从随即文件中读取学生姓名
private String readName(RandomAccessFile file) throws IOException {
return readString(file, NAME_SIZE);
}
//从随即文件中读取学生ID
private String readId(RandomAccessFile file) throws IOException {
return readString(file, ID_SIZE);
}
//从随即文件中读取size字节长度的字符串
private String readString(RandomAccessFile file, int size) throws IOException {
char [] temp = new char[15];
for(int i = 0; i temp[i] = file.readChar();

return new String(temp).replace('\0', ' ');
}
/**
* 把对象写入随即文件
* @param file
* @throws IOException
*/
public void write(RandomAccessFile file) throws IOException {
writeName(file);
writeId(file);
file.writeInt(getAge());
}
//把name写入随即文件
private void writeName(RandomAccessFile file) throws IOException {
writeString(file, getName());
}
//把id写入随即文件
private void writeId(RandomAccessFile file) throws IOException {
writeString(file, getId());
}
//把给定的字符串写入随即文件
private void writeString(RandomAccessFile file, String content) throws IOException {
StringBuffer buffer = null;

if(content != null)
buffer = new StringBuffer(content);
else
buffer = new StringBuffer(15);

buffer.setLength(15);
file.writeChars(buffer.toString());
}
}




/**
* 测试随即文件的读取
* @author Sunny
* @version 1.0
*/
import java.io.*;
public class RandomAccessFileTest {
/**
* @param args
*/
public static void main(String[] args) throws IOException, FileNotFoundException {
File file = new File("random.dat");
if(file.exists())
file.createNewFile();
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");

RandomAccessStudent yang = new RandomAccessStudent("Sunny", "123456", 23);
RandomAccessStudent jin = new RandomAccessStudent("JJJJJ", "12345678", 24);

yang.write(randomAccessFile);
jin.write(randomAccessFile);

randomAccessFile.close();

RandomAccessFile read = new RandomAccessFile(file, "rw");

jin.read(read);
System.out.println(jin.getAge());

read.close();
}
}
上面仅仅是基本的IO简介,更多的知识就是去查看API来完善,还有在JDK1.4中又有java.nio.*这个包,它又是一种新的机制,如果有时间将介绍它的基本机制。

没有评论: