初学者请教有关java Zip压缩流中的疑问

PogbaLiu 2016-02-09 02:43:51
package concentration.com;
import java.io.*;
import java.util.zip.*;
public class MyZipCompressing {
private int k = 1; // 定义递归次数变量

public MyZipCompressing() {
// TODO Auto-generated constructor stub
}

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
MyZipCompressing book = new MyZipCompressing();
try {
book.zip("D:/Java/程序/workforever.com/www.zip",
new File("D:/Java/程序/workforever.com/test"));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

private void zip(String zipFileName, File inputFile) throws Exception {
System.out.println("压缩中...");
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(
zipFileName));
BufferedOutputStream bo = new BufferedOutputStream(out);
zip(out, inputFile, inputFile.getName(), bo);
bo.close();
out.close(); // 输出流关闭
System.out.println("压缩完成");
}

private void zip(ZipOutputStream out, File f, String base,
BufferedOutputStream bo) throws Exception { // 方法重载
if (f.isDirectory()) {
File[] fl = f.listFiles();
if (fl.length == 0) {
out.putNextEntry(new ZipEntry(base + "/")); // 创建zip压缩进入点base
System.out.println(base + "/");
}
for (int i = 0; i < fl.length; i++) {
zip(out, fl[i], base + "/" + fl[i].getName(), bo); // 递归遍历子文件夹
}
System.out.println("第" + k + "次递归");
k++;
} else {
out.putNextEntry(new ZipEntry(base)); // 创建zip压缩进入点base
System.out.println(base);
FileInputStream in = new FileInputStream(f);
BufferedInputStream bi = new BufferedInputStream(in);
int b;
while ((b = bi.read()) != -1) {
bo.write(b); // 将字节流写入当前zip目录
}
bi.close();
in.close(); // 输入流关闭
}
}
}


如上面代码所示,这是一段JavaZIP压缩的示例代码,被压缩的test文件夹内有 word.txt和word1.txt两个文件以及一个word2文件夹,另外word2文件夹内有一个word3.txt文件,总共三个文本文件。

问题一:每个文本文件都保存有文字,运行代码后,得到www.zip压缩文件,查看得到的压缩文件,发现word.txt和word1.txt文件保存的文字没有了,保存的文字反而出现在word3.txt文件内。然后我自己修改了一下代码,把buffered缓存流删去,不用buffered修饰输入/出流,结果就是的到压缩文件解压出来就跟源文件一样,不会出现刚才的情况,自己后来怎么也想不通,可能对缓存流理解不够深刻吧,望懂得朋友帮我解疑,谢谢!

问题二:输入流中的int read()方法读取单个字节,返回所读取的字节数据,但是返回类型是int,是不是返回的字节数据会强制转换为int类型
(最后正值新春佳节,祝大家新年快乐,新的一年写出更让人赏心悦目的代码!)

这是代码运行后控制台结果
...全文
190 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
PogbaLiu 2016-02-19
  • 打赏
  • 举报
回复
引用 1 楼 lzk413 的回复:
问题一:运行楼主的代码,结果确实如此,word.txt和word1.txt文件保存的文字没有了,反而出现在word3.txt文件内。但我对zip方法加了一行代码,就好了。

	private void zip(ZipOutputStream out, File f, String base,
			BufferedOutputStream bo) throws Exception { // 方法重载
		if (f.isDirectory()) {
			File[] fl = f.listFiles();
			if (fl.length == 0) {
				out.putNextEntry(new ZipEntry(base + "/")); // 创建zip压缩进入点base
				System.out.println(base + "/");
			}
			for (int i = 0; i < fl.length; i++) {
				zip(out, fl[i], base + "/" + fl[i].getName(), bo); // 递归遍历子文件夹
			}
			System.out.println("第" + k + "次递归");
			k++;
		} else {
			out.putNextEntry(new ZipEntry(base)); // 创建zip压缩进入点base
			System.out.println(base);
			FileInputStream in = new FileInputStream(f);
			BufferedInputStream bi = new BufferedInputStream(in);
			int b;
			while ((b = bi.read()) != -1) {
				bo.write(b); // 将字节流写入当前zip目录
			}
			bo.flush();//加了这行代码
			bi.close();
			in.close(); // 输入流关闭
		}
	}
究其原因,就是因为使用了BufferedOutputStream,导致结果不符合预期。因为BufferedOutputStream对输出带了缓冲,导致本来应该写入word.txt和word1.txt的Entry的数据,被缓冲在内存,最后关闭ZipOutputStream的时候,才写入到word3.txt的Entry里面,这里加上bo.flush(),好让缓冲在内存的数据强制输出到对应的Entry,就好了。 问题二:是的,read返回确实是由byte转成了int,但如果返回值是-1,则表示读到流的末尾
好的,谢谢,我懂了
木飞骄 2016-02-14
  • 打赏
  • 举报
回复
问题一:运行楼主的代码,结果确实如此,word.txt和word1.txt文件保存的文字没有了,反而出现在word3.txt文件内。但我对zip方法加了一行代码,就好了。

	private void zip(ZipOutputStream out, File f, String base,
			BufferedOutputStream bo) throws Exception { // 方法重载
		if (f.isDirectory()) {
			File[] fl = f.listFiles();
			if (fl.length == 0) {
				out.putNextEntry(new ZipEntry(base + "/")); // 创建zip压缩进入点base
				System.out.println(base + "/");
			}
			for (int i = 0; i < fl.length; i++) {
				zip(out, fl[i], base + "/" + fl[i].getName(), bo); // 递归遍历子文件夹
			}
			System.out.println("第" + k + "次递归");
			k++;
		} else {
			out.putNextEntry(new ZipEntry(base)); // 创建zip压缩进入点base
			System.out.println(base);
			FileInputStream in = new FileInputStream(f);
			BufferedInputStream bi = new BufferedInputStream(in);
			int b;
			while ((b = bi.read()) != -1) {
				bo.write(b); // 将字节流写入当前zip目录
			}
			bo.flush();//加了这行代码
			bi.close();
			in.close(); // 输入流关闭
		}
	}
究其原因,就是因为使用了BufferedOutputStream,导致结果不符合预期。因为BufferedOutputStream对输出带了缓冲,导致本来应该写入word.txt和word1.txt的Entry的数据,被缓冲在内存,最后关闭ZipOutputStream的时候,才写入到word3.txt的Entry里面,这里加上bo.flush(),好让缓冲在内存的数据强制输出到对应的Entry,就好了。 问题二:是的,read返回确实是由byte转成了int,但如果返回值是-1,则表示读到流的末尾

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧