17.4.4 FileOutputStream(文件输出流)
FileOutputStream 创建了一个可以向文件写入字节的类OutputStream,它常用的构造函数如下:
FileOutputStream(String filePath)
FileOutputStream(File fileObj)
FileOutputStream(String filePath, boolean append)
它们可以引发IOException或SecurityException异常。这里filePath是文件的全称路径,fileObj是描述该文件的File对象。如果append为true,文件以设置搜索路径模式打开。FileOutputStream的创建不依赖于文件是否存在。在创建对象时FileOutputStream在打开输出文件之前创建它。这种情况下你试图打开一个只读文件,会引发一个IOException异常。下面的例子创建一个样本字节缓冲器。先生成一个String对象,接着用getBytes( )方法提取字节数组对等体。然后创建了三个文件。第一个file1.txt将包括样本中的各个字节。第二个文件是file2.txt,它包括所有字节。第三个也是最后一个文件file3.txt,仅包含最后的四分之一。不像FileInputStream类的方法,所有FileOutputStream类的方法都返回一个void类型值。在出错情况下,这些方法将引发IOException异常。
// Demonstrate FileOutputStream.
import java.io.*;
class FileOutputStreamDemo {
public static void main(String args[]) throws Exception {
String source = "Now is the time for all good men\n"
+ " to come to the aid of their country\n"
+ " and pay their due taxes.";
byte buf[] = source.getBytes();
OutputStream f0 = new FileOutputStream("file1.txt");
for (int i=0; i < buf.length; i += 2) {
f0.write(buf[i]);
}
f0.close();
OutputStream f1 = new FileOutputStream("file2.txt");
f1.write(buf);
f1.close();
OutputStream f2 = new FileOutputStream("file3.txt");
f2.write(buf,buf.length-buf.length/4,buf.length/4);
f2.close();
}
}
下面是运行该程序之后,每个文件的内容,首先是file1.txt:
Nwi h iefralgo e
t oet h i ftercuty n a hi u ae.
接着,是file2.txt:
Now is the time for all good men
to come to the aid of their country
and pay their due taxes.
最后,file3.txt
nd pay their due taxes.
17.4.5 ByteArrayInputStream(字节数组输入流)
ByteArrayInputStream是把字节数组当成源的输入流。该类有两个构造函数,每个构造函数需要一个字节数组提供数据源:
ByteArrayInputStream(byte array[ ])
ByteArrayInputStream(byte array[ ], int start, int numBytes)
这里,array是输入源。第二个构造函数创建了一个InputStream类,该类从字节数组的子集生成,以start指定索引的字符为起点,长度由numBytes决定。下面的例子创建了两个ByteArrayInputStream,用字母表的字节表示初始化它们:
// Demonstrate ByteArrayInputStream.
import java.io.*;
class ByteArrayInputStreamDemo {
public static void main(String args[]) throws IOException {
String tmp = "abcdefghijklmnopqrstuvwxyz";
byte b[] = tmp.getBytes();
ByteArrayInputStream input1 = new ByteArrayInputStream(b);
ByteArrayInputStream input2 = new ByteArrayInputStream(b, 0,3);
}
}
input1对象包含整个字母表中小写字母,input2仅包含开始的三个字母。ByteArrayInputStream实现mark( )和reset( )方法。然而,如果 mark( )不被调用,reset( )在流的开始设置流指针——该指针是传递给构造函数的字节数组的首地址。下面的例子说明了怎样用reset( )方法两次读取同样的输入。这种情况下,我们读取数据,然后分别用小写和大写字母打印“abc”。
import java.io.*;
class ByteArrayInputStreamReset {
public static void main(String args[]) throws IOException {
String tmp = "abc";
byte b[] = tmp.getBytes();
ByteArrayInputStream in = new ByteArrayInputStream(b);
for (int i=0; i<2; i++) {
int c;
while ((c = in.read()) != -1) {
if (i == 0) {
System.out.print((char) c);
} else {
System.out.print(Character.toUpperCase((char) c));
}
}
System.out.println();
in.reset();
}
}
}
该例先从流中读取每个字符,然后以小写字母形式打印。然后重新设置流并从头读起,这次在打印之前先将字母转换成大写字母。下面是输出:
abc