您的位置:首页 > 其它

IO输入与输出

2011-01-06 18:29 218 查看
File类:
1.File类是IO包中惟一代表磁盘文件本身信息的类,而不是文件中的内容。
2.File类定义了一些与平台无关的方法来操纵文件。
3.Java中的目录被当作一种特殊的文件使用,list方法可以返回目录中的所有子目录和文件名。
4.在Unix下的路径分隔符为(/),在Dos下的路径分隔符为(/),Java可以正确处理Unix和Dos的路径分隔符。

注意:delete方法删除由File对象的路径所表示的磁盘文件或目录。如果删除的对象是目录,该目录中的内容必须为空。
创建对象的例子:
File f1 = new File(“d://test//1.txt”);

RandomAccessFile类:
RandomAccessFile类可以说是Java语言中功能最为丰富的文件访问类,它提供了众多的文件访问方法。RandomAccessFile类支持“随机访问”方式,我们可以跳转到文件的任意位置处读写数据。
RandomAccessFile对象类有个位置指示器,指向当前读写处的位置,当读写n个字节后,文件指示器将指向这n个字节后的下一个字节处。刚打开文件时,文件指示器指向文件的开头处,我们可以移动文件指示器到新的位置,随后的读写操作将从新的位置开始。
RandomAccessFile类仅限于操作文件,不能访问其它的IO设备,如网络、内存映像等。
RandomAccessFile类有两种方式打开文件:
new RandomAccessFile(f,"rw");//读写方式
new RandomAccessFile(f,"r");//只读方式

节点流
文件是数据的静态存储形式,而流是指数据传输时的形态。
数据流是一串连续不断的数据的集合。
IO流类可分为两大类:节点流类和过滤流类(也叫处理流类)。
程序用于直接操作目标设备所对应的类叫节点流类,程序也可以通过一个间接流类去调用节点流类,以达到更加灵活方便地读写各种类型的数据,这个间接流类就是过滤类。

InputStream与OutputStream类:
程序可以从中连续读取字节的对象叫输入流,用InputStream类完成,程序能向其中连续写入字节的对象叫输出流,用OutputStream类完成。

注意:输入输出类是相对程序而言的,而不是代表文件的。
InputStream类的一些常用方法:
int read(); int read(byte[] b); int read(byte[],int off,int len);
long skip(long n); int available(); void mark(int readlimit);
void reset(); boolean markSupported(); void close();
注意:
当我们在程序中创建了一个IO流对象,同时系统也会创建一个叫流的东西,在这种情况下,计算机内存中实际上产生了两个事物,一个是Java程序中的类的实例对象,一个是系统产生的某种资源,窗口、socket等都是这样的情况。Java垃圾回收器只能管理程序中的类的实例对象,没法去管理系统产生的资源,所以程序需要调用close方法,去通知系统释放其自身产生的资源。

OutputStream类的一些常用方法:
该类所有方法均返回void.
void write(int b); void write(byte[] b); void write(byte[] b,int off,int len); void flush(); void close();

FileInputStream与FileOutputStream类
这两个流节点用来操作磁盘文件,在创建FileInputStream对象时通过构造函数指定文件和路径和名字,这个文件必须是存在和可读的。在创建一个FileOutputStream对象时指定文件如果存在将要被覆盖。

创建一个FileOutputStream对象时,可以为其指定还不存在的文件名,但不能是存在的目录名,也不能是已被其他程序打开了的文件。

Reader与Writer类
Java中的字符是Unicode编码,是双字节的,而InputStream与OutputStream是用来处理字节的,在处理字符文本时不太方便,需要编写额外的程序代码。Java为字符文本的输入输出专门提供了一套单独的类,Reader、Writer两个抽象类与InputStream、OutputStream两个类相对应,同样,Reader、Writer下面也有许多子类,对具体IO设备进行字符输入输出。
对于Reader和Writer类,大体功能和InputStream、OutputStream两个类相同,但并不是它们的代替者,只是在处理字符串时简化了我们的编程。

PipedInputStream与PipedOutputStream类
一个PipedInputStream对象必须和一个PipedOutputStream对象进行连接而产生一个通信管道,PipedOutputStream可以向管道中写入数据,PipedInputStream可以从管道中读取PipedOutputStream写入的数据。
这两个类主要用来完成线程之间的通信,一个线程的PipedInputStream对象能够从另外一个线程的PipedOutputStream对象中读取数据。
例子代码:
Thread t1=new Sender();
Thread t2=new Receiver();
PipedOutputStream out=t1.getOutputStream();
PipedInputStream in=t2.getInputStream();
out.coonect(in);
JDK中还提供了PipedWriter和PipedReder这两个类用于字符文本的管道通信。

ByteArrayInputStream与ByteArrayOutputStream类
这两个类用于以IO流的方式来完成对字节数组内容的读写,来支持类似内存虚拟文件或者内存映像文件的功能。
ByteArrayInputStream的两个构造函数:
ByteArrayInputStream(byte[] buf);
ByteArrayInputStream(byte[] buf,int offse,int length);

ByteArrayOutputStream也有两个构造函数:
ByteArrayOutputStream();
ByteArrayOutputStream(int);

与ByteArrayInputStream和ByteArrayIOutputStream类对应的字符串读写类分别是StringReader和StringWriter。

重视IO程序代码的复用
System.in连接到键盘,是InputStream类型的实例对象System.out连接到显示器,是PrintStream类的实例对象。
不管各种底层物理设备用什么方式实现数据的终止点,InputStream的read方法总是返回-1来表示输入流的结束。
注意:这种方式只能判断文本文件是否结束,不能判断一个二进制文件是否结束。
在Windows下,按下Ctrl+Z组合键可以产生键盘输入流的结束标记,在Linux下,则是按下Ctrl+D组合键来产生键盘输入流的结束标记。

过滤流与包装类
DataOutputStream类提供了往各种输出流对象中写入各种类型的数据(包括浮点小数)的方法。中需传递一个FileOutputStream输出流对象给DataOutputStream实例对象给DataOutputStream实例对象,就可以向文件中写入各种类型的数据。
DataOutputStream并没有对应到任何具体的流设备,一定要给它传递一个对应具体流设备的输出流对象,完成类似DataOutputStream功能的类就是一个包装类,也叫过滤流类或处理流类。
DataOutputStream包装类的构造函数语法:
public DataOutputStream(OutputStream out)
DataOutputStream包装类的部分方法列表:
public final void writeBoolean(boolean v)
public final void writeShort(int v)
public final void writeChar(int v)
public final void writeInt(int v )
为什么DataInputStream类中有一个readUTF方法,而没有readBytes和readChars呢?
这是因为在DataOutputStream类中只有writeUTF方法向目标设备写入了字符串的长度。而另两个方法没有,则无法读取。

BufferedInputStream与BufferedOutputStream类
对IO进行缓冲是一种常见的性能优化,缓冲流为IO流增加了内存缓冲区。增加缓冲区有两个基本目的:
1.允许java程序一次不只操作一个字节,这样提高了程序的性能。
2.由于有了缓冲区,使得在流上执行skip、mark和reset方法都成为可能。

这两个类是Java提供的两个缓冲区包装类,不管底层系统是否使用了缓冲区,这两个类在自己的实例对象中创建缓冲区。

对输入流进行缓冲可以实现部分字符的回流。除了InputStream中常用的read和skip方法,BufferedInputstream还支持mark和reset方法。

BufferedReader和BufferedWriter类:
BufferedReader的readLine方法可以一次读取一行文本,BufferedWriter的newLine方法可以向字符流中写入不同操作系统下的换行符。

注意:如果正在使用一个流栈,程序关闭最上面的一个流也就关闭了栈中的所有底层流对象。

PrintStream类:
这个类提供了一系列的print和println方法,可以实现将基本数据类型的格式化成字符串输出。
IO包中提供了一个与printStream对应的printWriter类,printerWriter类即使遇到换行符(/n)也不会自动清空缓冲区,只在设置了autoflush模式下使用了println方法后才自动清空缓冲区。如果我们希望程序能够生成平台相关的文本换行,而不是在各种平台下都用"/n"作为文本换行,我们就应该使用printWriter的println方法时,PrintWtiter的println方法能根据不同的操作系统而生成相应的换行符。

ObjectInputStream与ObjectOutputStream类
这两个包装类,用于从底层输入流中读取对象类型的数据和将对象类型的的数据写入到底层输出流。
这两个类所读写的对象必须实现了Serializable接口。对象中的transient和static类型的成员变量不会被读取和写入。
使用ObjectInputStream与ObjectOutputStream类保存和读取对象的机制叫序列化。
序列化的好处:
它可以将任何实现了Serializable接口的对象转换为连续的字节数据,这些数据以后仍可以还原为原来的对象状态。即使这些数据通过网络传输也没问题。序列化能处理不同操作系统上的差异,我们可以在windows上产生某个对象,将它们序列化存储,然后通过网络传到linux机器上,该对象仍然可以被正确重建出来,在这期间,我们完全不用担心不同机器上不同的数据表示方式。

字节流与字符流的转换
InputStreamReader和OutputStreamWriter,这两个类是字节流和字符流之间转换的类,InputStreamReader可以将一个字节流解码成字符,OutputStreamWriter将写入的字符编码成字节后写入一个字节流。
为了达到最好的效率,避免频繁地进行字符与字节的相互转换,最好不要直接使用这两个类进行读写,就尽量使用BufferedWriter类包装OutputStreamWriter类,用BufferedReader类包装InputStreamReader类。例如:
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
BufferedWriter out=new BufferedWriter(new OutputStreamReader(System.out));

Decorator设计模式:
在程序中用一个对象包装另外一个对象,这是一种被称为Decorator的设计模式。
如果要设计自己的IO包装类,这个类需要继承以Fileterxxx命名的类,从而扩展了对输入输出流的支持。

Exception类从Throwable类继承的三个printStackTrace方法的定义如下:
1.public void printStackTrace()
2.public void printStackTrace(printStream s)
3.public void printStackTrace(printWriter s)
它们分别把异常的详细信息打印到标准输出流(屏幕上),或者其他的printStream和printWriter流中。

字符编码
为了解决各个国家和地区使用本地化字符编码带来的不利影响,人们将全世界所有的符号进行了统一编码,称为Unicode编码。
要正确地在屏幕打印中文字符,我们写入屏幕输出流的字节内容必须是该中文字符GB2312码,要将中文正确的存入硬盘文件也是一样的道理。

UTF-8编码
ASCII码字符保持原样,仍然只占用一个字节,对于其它国家的字符,UTF-8使用两个或三个字节来表示。
使用UTF-8编码的文件,通常都要有EF BB BF作为文件开头的三个字节数据。
字符的UTF-8编码与Unicode编码之间的转换关系对应下列规则:
-/u0001和/u007f之间的字符,UTF-8编码为:(byte)c。
-/u0000或其范围在/u0080和/u07ff之间的字符,UTF-8编码为:
(byte)(0xc0|(ox1f&(c>>6))),(byte)(0x80|(0x3f&c))。
-/u0800和/uffff之间的字符,UTF-8编码为:
(byte)(0xe0|(0x0f&(c>>12))),(byte)(ox80|(0x3f&(c>>6))),(byte)(0x80|(0x3f&c))

/u0001-/u007f 0xxxxxxx
/u0000或/u0080-/u07ff 110xxxxx 10xxxxxx
/u0800-/uffff 1110xxxx 10xxxxxx 10xxxxxx

UTF-8编码的优点:
1.不出现内容为0x00的字节
2.便于应用程序检测数据在传输过程中是否发生了错误
3.直接处理使用ASCII码的英文文档
UTF_8的缺点:
某些字符要占用3个字节,尤其是中文、日文及韩文等。

Java程序与其它进程的数据通信
在Java程序中可以产生其他的应用程序的进程,在Java程序中启动的进程称为子进程,启动子进程的Java程序称为父进程。
在Java程序中可以用Process类的实例对象来表示子进程,子进程的标准输入和输出不再连接到键盘和显示器,而是以管道流的形式连接到父进程的一个输出流和输入流对象上。调用Process类的getOutputStream和getInputStream方法可以得到这个输出流和输入流对象.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: