鸿 网 互 联 www.68idc.cn

当前位置 : 主页 > 编程语言开发 > java > >

【Java】文件打包

来源:互联网 作者:佚名 时间:2012-12-28 21:20
最近又接到了实验室的新任务,做文件的批量上传,批量下载。大致需要实现以下几项功能: 1.可以批量选择待上传的文件 2.可以上传大文件 3.能够让用户看到公有云盘的文件列表,私有云盘的文件列表 4.能够让用户以复选的形式批量下载文件,借鉴于各种流行的网

最近又接到了实验室的新任务,做文件的批量上传,香港服务器,批量下载。大致需要实现以下几项功能:

1.可以批量选择待上传的文件

2.可以上传大文件

3.能够让用户看到公有云盘的文件列表,私有云盘的文件列表

4.能够让用户以复选的形式批量下载文件,借鉴于各种流行的网盘批量下载文件时选择的解决方案:将用户选择的文件打包下载。

很开心的表示,我完成了所有的要求,其中不乏从白痴慢慢摸索,磕磕绊绊,但总归圆满。这次来讲讲java实现的文件打包,这次学习到的其它知识和经验,等有空再记下来,免得以后忘记了。

其实java是很面向对象的语言,强大到爆的工具类和API,以至于至今我还不能窥其一二。java.util.zip包中完整的提供了关于文件压缩和解压的工具类和方法,网上流行着各种apache的第三方工具库,异常强大,但我不喜欢引入第三方的工具,究其原因就是很难查到这些工具的引入方法,网上基本上都不讲,上来就是例子代码,各种import完事,看了以后一头雾水,主要是太菜了。所以就自己依靠官方提供的工具,自己慢慢的摸索。

首先,整理一下文件打包逻辑,然后,贴上源码

1.要获得需要打包的文件

//e.g: File file = new File("test.txt");

2.生成最终打包的目标文件

//e.g: File zipFile = new File("DownLoad.zip");//最终打包的压缩包

3.要往压缩包里面写数据,就要使用特别为写压缩包定制的输出流ZipOutputStream,将这个输出流的输出端套在压缩包File变量上,就像把水管套进蓄水池中一样

ZipOutputStream zipStream = new ZipOutputStream(new FileOutputStream(zipFile));//用这个构造最终压缩包的输出流

4.要把提供数据的源头文件的内容读出来,存储在缓冲字节数组里面,使用缓冲技术加快文件读写,关于文件读取,这个很基本了(建FileInputStream流,外层再套上BufferedInputStream流)

FileInputStream zipSource = new FileInputStream(file); BufferedInputStream bufferStream = read = 0; while((read = bufferStream.read(bufferArea, 0, 1024 * 10)) != -1) { }

5.有了byte[]数组,就可以使用ZipOutputStream.write(byte[] b, int off, int len)方法写入压缩包了,但是压缩包是压缩多文件使用的,它具有文件列表,必须要告诉当前应该写到哪一个条目里面,就像图书馆放书到书架上,必须要指定这本书应该放在哪一个书架,ZipEntry就是干这个活的

//压缩条目不是具体独立的文件,而是压缩包文件列表中的列表项,称为条目,就像索引一样 ZipEntry zipEntry = new ZipEntry(file1.getName()); zipStream.putNextEntry(zipEntry);//定位到该压缩条目位置,开始写入文件到压缩包中

6.最后一步,开始使用byte[]数组中存储的已读取信息,向压缩包写数据

((read = bufferStream.read(bufferArea, 0, 1024 * 10)) != -1) { zipStream.write(bufferArea, 0, read); }

至此,文件压缩逻辑备忘完毕,但还得多写几个要点,香港虚拟主机,都是很细节的领悟,以免忘记了没处查

1.关于文件操作中有形形色色的read,write操作,java允许方法重写,这苦了我这样的菜鸟,有点晕,但是使用的时候都一样的名字还是挺便利的。

 

InputStream应该是所有的输入流的鼻祖了,它共定义了3种read方法,各有千秋,官方的API介绍的很专业,非常经典,我常常对于一些细节拿捏不准,今天好好整理一下

1.1. int read():从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。

                     返回:下一个数据字节;如果到达流的末尾,则返回 -1。

 

1.2. int read(byte[] b):从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b中。以整数形式返回实际读取的字节数。如果 b 的长度为 0,则不读取任何字节并返回 0;否则,尝试读取至少一个字节。如果因为流位于文件末尾而没有可用的字节,则返回值 -1;否则,至少读取一个字节并将其存储在 b 中。将读取的第一个字节存储在元素 b[0] 中,下一个存储在 b[1] 中,依次类推。读取的字节数最多等于 b 的长度。设 k 为实际读取的字节数;这些字节将存储在 b[0] 到 b[k-1] 的元素中,不影响 b[k] 到 b[b.length-1] 的元素。类 InputStream 的 read(b) 方法的效果等同于:read(b, 0, b.length);

                    返回:读入缓冲区的总字节数;如果因为已经到达流末尾而不再有数据可用,则返回 -1。

 

1.3. int read(byte[] b, int off, int len):这个得好好说说,将输入流中最多 len 个数据字节读入 byte 数组。尝试读取 len个字节,但读取的字节也可能小于该值。以整数形式返回实际读取的字节数。如果 len 为 0,则不读取任何字节并返回 0;否则,尝试读取至少一个字节。如果因为流位于文件末尾而没有可用的字节,则返回值 -1;否则,至少读取一个字节并将其存储在 b 中。将读取的第一个字节存储在元素 b[off] 中,下一个存储在 b[off+1] 中,依次类推。读取的字节数最多等于 len。设 k 为实际读取的字节数;这些字节将存储在 b[off] 到 b[off+k-1] 的元素中,不影响 b[off+k] 到 b[off+len-1] 的元素。

在任何情况下,b[0] 到 b[off] 的元素以及 b[off+len] 到 b[b.length-1] 的元素都不会受到影响。

                   参数:              b - 读入数据的缓冲区。              的 len 个字节写入此输出流。write(b, off, len) 的常规协定是:将数组 b 中的某些字节按顺序写入输出流;啰嗦了这么多,只怕以后忘了,记忆力要是有云能力就好了,贴上打包文件的java全代码:
网友评论
<