我们从字节流开始介绍Java IO.正如已经解释过的,字节流层次结构的顶端是inputStream类和OutputStream类.一般来说inputStream类和outputStream类的方法可以根据错误抛出IOException,这两个抽象类定义的方法对于他们的所有子类都是有效的.因此,他们形成了所有字节流的最小IO功能集.
InputStream类定义的方法:
方法
|
描述
|
int available()
|
返回当前可读取的输入字节数
|
void close()
|
关闭输入源,任何读取尝试都将生成IOException
|
void mark(int numBytes)
|
在输入流的当前点放置标记,在读取numBytes个字节之前保持有效
|
boolean markSupported()
|
如果调用流支持mark()/reset(),则返回true
|
int read()
|
返回一个整数表示输入的下一个有效字节,返回-1时表示达到文件末尾
|
int read(byte buffer[])
|
尝试读取buffer.length个字节到缓冲区,并返回实际成功读取的字节数,返回-1时表示到达文件末尾.
|
int read(byte buffer[],int offset,int numBytes)
|
尝试读取numBytes个字节到缓冲区中以buffer[offset]开始的位置,并返回实际成功读取的字节数.返回-1时表示到达文件末尾
|
void reset() |
将输入指针重新改为原来设置的标记
|
long skip(long numBytes)
|
忽略(跳过)numByes个输入字节,返回实际忽略的字节数
|
OutputStream类定义的方法:
方法
|
描述
|
void close()
|
关闭输出流,而且任何写尝试都将产生IOException
|
void flush()
|
将已经缓冲的任何输出发送到其目标,即刷新输出缓冲区
|
void write(int b) |
向输出流写入单个字节,注意,形参是int类型,他允许你使用无须强制转换回byte的表达式就可以调用write
|
void write(byte buffer[])
|
向输出流写入一个完整的字节数组
|
void write(byte buffer[],int offset,int numBytes) |
从数组缓冲区的buffer[offset]位置开始写入numBytes个字节的子区间
|
1.读取控制台输入
起初,使用字节流是执行控制台输入的唯一方法,而且许多Java代码依然只能使用字节流或字符流.对于商业代码而言,读取控制台输入的首选方法是使用字符流.这样做可以使程序更易国际化,更易维护,而且直接操作字符要比在字符与字节间来回转换方便的多.然而对于程序示例,自己使用的小型实用程序的处理键盘输入的应用程序而言,使用字节流也是可取的,出于这一点,我们这里使用字节流来介绍控制台IO.
因为System.in是InputStream类的一个实例,所以可以自动拥有访问InputStream类定义的方法的权限.然而,InputStream类只定义了一个读取字节的输入方法read(),read()的三个版本如下所示:
int read() throws IOException int read(byte data[]) throws IOException int read(byte data[],int start,int max) throws IOException
之前介绍过如何使用第一个版本的read()从键盘读取字符.当到达流的末尾时,返回-1.第二个版本的read()从输入流读取字节,并将他们放入data字节数组中,直到数组满,到达流的末尾或有错误发生.他返回读取的字节数,如果到达的末尾,则返回-1.第三个版本的read()从start指定的位置开始将字节放入data中,直到存储max个字节为止.他返回读取的字节数,如果到达流的末尾,则返回-1.错误发生时,所有的版本都抛出IOException.从System.in读取字节时,按回车键产生一个流结束条件.
下面是一个演示从System.in读取字节数组的程序.注意,可能发生的任何IO异常都被抛出到main()以外.这种方法从控制台读取数据时十分常见,但是如果愿意,也可以自己处理这些类型的错误.
public class test2 { // @param args public static void main(String args[]) throws IOException { byte data[] = new byte[10]; System.out.println("Enter some thing:"); System.in.read(data); for(int i=0;i<data.length;i++) System.out.print((char)data[i]); } }
输出:
Enter some thing: reree reree
2.写入控制台输出
与控制台输入的情况一样,Java起初只为控制台输出提供了字节流.Java1.1增加了字符流.要想实现高可移植性代码,推荐使用字符流.但是,因为System.out是一个字节流,所以基于字节的控制台输出依然被广泛应用.
使用已熟悉的print()和pringln()可以轻松的完成控制台输出.这些方法由pringstream类定义(System.out引用的对象类型).虽然System.out是一个字节流,但是使用这种流用于简单的控制台输出也是可行的.
因为printStream是一个从OutputStreram派生的输出流,所以他还实现了低级别的方法write().因此,使用write()向控制器写入是完全可行的.PringStream定义的write()的最简单的形式如下所示:
void write(int byteval)
该方法通过byteval向文件写入指定的字节.尽管byteval被声明为整数,但他只有低8位被写.下面是一个使用write()输出字符X并换行的简单示例:
public static void main(String args[]) throws IOException { int b; b = 'x'; System.out.write(b); System.out.write('\n'); }
输出:
x
不会经常使用write()来执行控制台输出,因为print()和pringln()用起来更为简单.
printStream还提供了另外两个输出方法:pringf()和format(),使用他们可以更详细的控制所输出的数据的格式.例如,可以指定显示的小数位数,最低域宽或负值的格式.