学习Java小结-3
来源:互联网 发布:软件机器人 编辑:程序博客网 时间:2024/06/05 15:32
学习Java也有近一个月了,基础语法、常用类也有所了解。上周把文件相关操作进行了一个总结,制作了一个简单的文件常用操作的工具类。
此处详解文件的打包与解包
工具类包含了容下功能的实现:
1、 拷贝文件
2、 移动文件
3、 遍历文件夹
4、 获取文件夹内所有文件
5、 文件打包与解包
5-1 文件的打包
思路:要将文件进行打包,首先需要拿到文件当中的所有文件对象,然后将所有的文件安装一定的组织关系存入一个文件当中。
既然是打包,那么就应该有一个打包后的文件类型,在这里我将包文件类型定义为pakge类型的文件
public static String PACKAGE_TYPE = ".pakge";
在上面已经实现了获取文件中的所有文件,现在需要将所有的文件存入一个文件当中。这个就简单了,只需要遍历获取了所有的文件对象的List集合对象,将每一个文件依次写入一个文件当中即可。
/** * 打包一个文件(夹) * @param srcDir 要打包的目标文件(夹)绝对路径字符串 * @param dir 打包文件的存贮绝对路径字符串 * @return boolean TRUE表示成功打包 */ public static boolean packageFile(String srcDir, String dir) { //创建文件对象 File srcFile = new File(srcDir); File destFile = new File(dir + PACKAGE_TYPE); //通过文件对象获取源文件的绝对路径,避免参数字符差异 String srcFilePath = srcFile.getAbsolutePath(); //如果源文件存在,则进行打包操作 if (srcFile.exists()) { //通过已有方法获取所有文件 ArrayList<File> fileList = new ArrayList<File>(); FileControls.getAllFiles(srcFilePath, fileList); try { //以追加方式创建文件输出流,绑定打包文件 FileOutputStream fs = new FileOutputStream(destFile, true); for (Filef : fileList) { if (!f.getFilePath().isDirectory()) { FileInputStream fi = new FileInputStream(f.getFilePath()); //创建缓冲字节数组 byte[] buffer = new byte[4096]; //获取当前文件总长(字节数) long size = f.length(); while (true) { //如果未写入的字节数比缓冲数组长,则读取并写入4096字节 if (size > 4096) { fi.read(buffer); fs.write(buffer); //未写入字节数减少4096 size -= 4096; } else { //读取并写入剩余字节,关闭输入流 fi.read(buffer, 0, (int) size); fs.write(buffer, 0, (int) size); fi.close(); break; } } } } //刷新输出流,关闭输出流 fs.flush(); fs.close(); return true; } catch (IOException e) { e.printStackTrace(); } } else { System.out.println("源文件\"" + srcFile.getAbsolutePath() + "\"不存在"); } return false; }
这里可以看到,打包功能已经完成。接下来看解包的实现。
5-2 文件的解包
思路:在这里突然发现,上面实现的打包功能无法解包。为啥呢?因为包中的文件名、文件大小信息均没有进行保留。因此需要对上面的打包功能进行优化。在打包的时候要将文件名、文件大小写入到打包文件中。这样在解包的时候才可以将包文件中的文件正常的完整的解包出来。
因此,增加了一个功能类Filesize
public static class Filesize implements Serializable { private static final long serialVersionUID = -1035346214239079079L; private File filePath; private long fileSize; public File getFilePath() { return filePath; } public long getFileSize() { return fileSize; } public void setFilePath(String filePath) { this.filePath = new File(filePath); this.fileSize = this.filePath.length(); } }
该功能类Filesize有两个属性:1、文件对象。2、文件对象的大小。另外可以看到该功能类实现了Serializable接口,这是为了能够该类对象能够序列化到文件中。以便于将文件的名称、大小的信息保存下来。
因为要将文件信息保存到该功能类中,因此重载获取所有文件对象的方法。重载时发现,目录文件不需要进行获取
public static void getAllFiles(String srcPath, ArrayList<FileControls.Filesize> files) { File file = new File(srcPath); if (file.exists()) { File[] fileList = file.listFiles(); if (fileList != null && fileList.length > 0) { for (File src : fileList) { getAllFiles(src.getAbsolutePath(), files); } } if (!file.isDirectory()) { //构建功能类对象 FileControls.Filesize fileSize = new FileControls.Filesize(); fileSize.setFilePath(file.getAbsolutePath()); files.add(fileSize); } } }
打包方法优化后的代码如下
/** * 对打包文件进行解包,默认解包路径为打包文件同级路径,解包的后的文件对象的父目录为 * 包文件父目录/包文件名 * * @param packageFilePath 包文件绝对路径字符串 * @return 成功解包则返回TRUE */ public static boolean upPackges(String packageFilePath) { File packageFile = new File(packageFilePath); FileInputStream fin = null; ObjectInputStream oin = null; if (packageFile.exists()) { try { fin = new FileInputStream(packageFile); oin = new ObjectInputStream(fin); ArrayList<FileControls.Filesize> list = new ArrayList<FileControls.Filesize>(); //反序列化出文件详细信息集合对象 //如果强转失败,则会抛出ClassCastException异常,说明这不是一个大包文件 list = (ArrayList<FileControls.Filesize>) oin.readObject(); if (list.size() != 0) { for (int i = 0; i < list.size(); i++) { File file = list.get(i).getFilePath(); //如果该文件是目录,则直接创建目录 if (!file.isDirectory()) { //构建包文件的绝对路径字符串 String dir = packageFile.getParent() + "\\" + file.getName(); //创建解包文件 File destfile = new File(dir); //创建父级目录 destfile.getParentFile().mkdirs(); FileOutputStream fout = new FileOutputStream(destfile); //获取文件大小 long filesize = list.get(i).getFileSize(); //通过缓冲法将文件类容读取并写入解包的对应文件中 byte[] buffer = new byte[4096]; while (true && filesize > 0) { if (filesize > 4096) { fin.read(buffer); fout.write(buffer); filesize -= 4096; } else { fin.read(buffer, 0, (int) filesize); fout.write(buffer, 0, (int) filesize); break; } } fout.flush(); fout.close(); } else { file.mkdirs(); } } //关闭输入流 oin.close(); return true; } } catch (ClassCastException ce) { System.out.println("这不是一个包文件"); try { oin.close(); fin.close(); } catch (IOException e) { e.printStackTrace(); } } catch (Exception e) { e.printStackTrace(); } } return false; }
到这里,所以的功能已经完整的实现。代码已经上传到GitHub中,这是GitHub的链接
阅读全文
0 0
- 学习Java小结-3
- Java学习小结
- Java”方法“学习小结
- JAVA RMI学习小结
- Java学习小结
- java学习小结
- JAVA学习小结
- JAVA学习小结
- UserHandle.java学习小结
- Java线程学习小结
- Java基本学习小结
- Java Swing学习小结
- JAVA SE学习小结
- java IO学习小结
- Java Iterator学习小结
- Java继承学习小结
- Java多线程学习小结
- java学习小结 11.9
- Spring学习记录
- hdu 1022
- java异常体系及注意事项
- 《Java编程思想》转型与警告
- C语言 常犯的九个小错误
- 学习Java小结-3
- Kotlin一步一个脚印学习基础一
- 异常捕获机制
- 学习javascript闭包
- POj
- java练习题1
- DBConnect
- Hbase伪分布式配置
- Linux下修改权限命令