输出流 OutputStream
OutputStream是Java标准库提供的最基本的输出流。
和InputStream类似,OutputStream也是抽象类,它是所有输出流的超类。这个抽象类定义的一个最重要的方法就是void write(int b)
public abstract void write(int b) throws IOException;
这个方法会写入一个字节到输出流。要注意的是,虽然传入的是int参数,但只会写入一个字节,即只写入int最低8位表示字节的部分
复制一个文件
通过InputStream读取数据,通过OutputStream写入数据
public static void copy(String from, String to) throws IOException {
File f = new File(from);
File t = new File(to);
if (!f.exists()) {
throw new FileNotFoundException();
}
if (!t.exists()) {
try {
t.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try (InputStream input = new FileInputStream(f);
OutputStream output = new FileOutputStream(t)) {
int fLenght = (int) f.length();
byte[] data = new byte[fLenght];
System.out.println("文件长度为" + fLenght);
int n;
while ((n = input.read(data)) != -1) {
output.write(data);
}
}
}
Filter模式(或者装饰器模式:Decorator)
当我们需要给一个“基础”InputStream附加各种功能时,我们先确定这个能提供数据源的InputStream,因为我们需要的数据总得来自某个地方,例如,FileInputStream,数据来源自文件:
InputStream file = new FileInputStream("test.gz")
我们希望FileInputStream能提供缓冲的功能来提高读取的效率,因此我们用BufferedInputStream包装这个InputStream,得到的包装类型是BufferedInputStream,但它仍然被视为一个InputStream:
InputStream buffered = new BufferedInputStream(file);
最后,如果这个文件已经被gzip压缩,我们可以封装一个GZIPInputStream
,
InputStream gzip = new GZIPInputStream(buffered);
无论我们封装多少次,得到的对象始终是InputStream,我们直接用InputStream来引用它,就可以正常读取
上述这种通过一个“基础”组件再叠加各种“附加”功能组件的模式,称之为Filter模式(或者装饰器模式:Decorator)
操作Zip
ZipInputStream是一种FilterInputStream,他直接读取zip包的内容。
读取
创建一个 ZipInputStream,循环调用getNextEntry(),直到返回null,表示zip流结束
getNextEntry返回一个zipEntry,一个ZipEntry表示一个压缩文件或目录,如果是压缩文件,我们就用read()方法不断读取,直到返回-1
try (ZipInputStream zip = new ZipInputStream(new FileInputStream(...))) {
ZipEntry entry = null;
while ((entry = zip.getNextEntry()) != null) {
String name = entry.getName();
if (!entry.isDirectory()) {
int n;
while ((n = zip.read()) != -1)