带缓存的输入/输出流
缓存是I/O的一种性能优化。缓存流为I/O流增加了内存缓存区。有了缓存区,使得在流上执行skip()、mark()和reset()方法都成为可能。
BufferedInputStream与BufferedOutputStream类。
BufferedlnputStream类可以对所有lnputStream类进行带缓存区的包装以达到性能的优化。BufferedlnputStream类有两个构造方法:
BufferedlnputStream(InputStream in);
创建了一个带有32个字节的缓存流;
BufferedlnputStream(InputStream in, int size);
按指定大小来创建缓存区。
一个最优的缓存区的大小,取决于他所在的操作系统、可用的内存空间以及机器配置。从构造方法可以看出,BufferedlnputStream对象位于lnputStream类对象之前。
使用BufferedOutputStream输出信息和用OutputStream输出信息完全一样,只不过BufferedOutputStream有一个flush()方法用来将缓存区的数据强制输出完。BufferedOutputStream类也有两个构造方法:
BufferedOutputStream(OutputStream in);
创建了一个带有32个字节的缓存流;
BufferedOutputStream(OutputStream in, int size);
按指定大小来创建缓存区。
flush()方法就是用于即使在缓存区没有满的情况下,也能将缓存区的内容强制写入到外设,习惯上称这个过程为刷新。flush()方法只对使用缓存区的OutputStream类的子类有效。当调用close()方法时,系统在关闭流之前,也会将缓存区中的信息刷新到磁盘文件中。
BufferedReader和BufferedWriter类
BufferedReader和BufferedWriter类分别继承Reader和Write类。这两个类同样具有内部缓存机制,并可以以行为单位进行输入/输出。
代码如下:
package hhh;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class AboutBuffered {
public static void main(String[] args) throws IOException {
String s[] = {"陌生人!","你好!","再见!"};
File file = new File("word.txt");
try {
FileWriter fw = new FileWriter(file);
BufferedWriter bufw = new BufferedWriter(fw);
for(int k = 0; k < s.length; k++) {
bufw.write(s[k]);
bufw.newLine();
}
bufw.close();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
FileReader fr;
try {
fr = new FileReader(file);
BufferedReader bufr = new BufferedReader(fr);
String S = null;
int i = 0;
while((S = bufr.readLine()) != null) {
i++;
System.out.println(i+":"+S);
}
bufr.close();
fr.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
数据输入/输出流
DataInputStream类DataInputStream类允许应用程序以与机器无关的方式从底层输入流中读取基本Java数据。也就是说当读取一个数据时,不必再关心这个数值应当是哪种字节。
DataInputStream类DataInputStream类的构造方法如下:
DataInputStream(InputStream in)
使用指定的基础InputStream创建一个DataInputStream。
DataOutputStream(OutputStream out)
创建一个新的数据输出流,将数据写入制定基础输出流。
DataOutputStream类提供了如下3种写入字符串的方法:
writeBytes(String s)
writeChars(String s)
writeUTF(String s)
由于Java中的字符是Unicode编码,是双字节的,writeBytes只是将字符串中的每一个字符的低字节内容写入目标设备中;而writeChars将字符串中的每个字符的两个字节的内容都写到目标设备中;writeUTF将字符串按照UTF编码后的字节长度写入目标设备,然后才是每一个字节的UTF编码。
DataInputStream类只提供了一个readUTF()方法返回字符串。这是因为要在一个连续的字节流读取一个字符串,如果没有特殊的标记作为一个字符串的结尾,并且不知道这个字符串的长度,就无法知道读取到什么位置才是这个字符串的结束。DataOutputStream类中只有writeUTF()方法向目标设备中写入字符串的长度,所以也能准确的读回写入字符串。
代码如下:
package hhh;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* 用不同的方法将向指定的磁盘文件中写入数据,通过readUTF()方法将写入的数据输出到控制台上。
* @author hanjiangbo
*
*/
public class Test02 {
public static void main(String[] args) {
try {
FileOutputStream fs = new FileOutputStream("word.txt");
DataOutputStream ds = new DataOutputStream(fs);
ds.writeUTF("使用writeUTF()方法写入数据");
ds.writeChars("使用writeChars()方法写入数据");
ds.writeBytes("使用writeBytes()方法写入数据");
ds.close();
FileInputStream fis = new FileInputStream("word.txt");
DataInputStream dis = new DataInputStream(fis);
System.out.println(dis.readUTF());
} catch (Exception e) {
e.printStackTrace();
}
}
}
用记事本将word.txt打开内容是乱码,而程序通过readUTF读回后显示的却是“使用WriterUTF方法写入数据”。
zip压缩输入/输出流
要从zip文件内读取某个文件,必需要找到对应该文件的“目录进入点”(从它可知文件在zip文件内的位置),才能读取到这个文件的内容。如果要将文件内容写入zip文件内,必须先写入对应于该文件的“目录进入点”,并且把要写入文件内容的位置移到此进入点所指的的位置,然后再写入文件内容。
ZipEntry类产生的对象,是用来代表一个ZIP文件的进入点。ZipInputStream类用来读取ZIP格式的文件,ZipOutputStream类用来写出ZIP格式的文件。
代码如下:
package hhh;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* 压缩E盘的hellow文件夹,在该文件夹中有hellow.txt和hellow2.txt文件,并将压缩后的hellow.zip文件夹保存在E盘根目录下。
* @author hanjiangbo
*
*/
public class ZipTest {
private void zip(String zipFileName, File inputFile) throws Exception{
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName));
zip(out,inputFile,"");
System.out.println("压缩中。。。");
out.close();
}
private void zip(ZipOutputStream out, File f, String base) throws Exception{
if(f.isDirectory()) {
File[] fl = f.listFiles();
if(base.length() != 0) {
out.putNextEntry(new ZipEntry(base+"/"));
}
for(int i = 0; i < fl.length; i++) {
zip(out,fl[i],base+fl[i]);
}
}else {
out.putNextEntry(new ZipEntry(base));
FileInputStream in = new FileInputStream(f);
int b;
System.out.println(base);
while((b = in.read()) != -1) {
out.write(b);
}
in.close();
}
}
public static void main(String[] args) {
ZipTest book = new ZipTest();
try {
book.zip("E:/hello.zip", new File("E:/hello"));
System.out.println("压缩完成!");
} catch (Exception e) {
System.out.println("压缩失败,找不到该文件夹");
}
}
}
解压缩zip文件
ZipInputStream类可用来解压缩,
ZipInputStream类的构造方法:ZipInputStream(InputStream in);
代码如下:
package hhh;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
/**
* 将hello.zip解压
* @author hanjiangbo
*
*/
public class UnzipTest {
public static void main(String[] args) {
File file = new File("hello.zip");
ZipInputStream zin;
try {
ZipFile zipFile = new ZipFile(file);
zin = new ZipInputStream(new FileInputStream(file));
ZipEntry entry = zin.getNextEntry();
while(((entry = zin.getNextEntry())!=null)&&!entry.isDirectory()) {
File tmp = new File("C:\\"+entry.getName());
if(!tmp.exists()) {
tmp.getParentFile().mkdirs();
OutputStream os = new FileOutputStream(tmp);
InputStream in = zipFile.getInputStream(entry);
int count = 0;
while((count = in.read()) != -1) {
os.write(count);
}
os.close();
in.close();
}
zin.closeEntry();
System.out.println(entry.getName()+"解压成功!");
}
zin.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}