欢迎来到我的博客小站。  交流请加我微信好友: studyjava。  也欢迎关注公众号:Java学习之道 Fork me on GitHub

如何处理零碎小文件归档00

如何处理零碎小文件归档:

tar
har
jar
war
ear

0、关键点:

设计协议(因为协议不一样的话,可能各种软件解档出来的内容会发生变化)

1、前情概要

位运算:

0000 0100 = 4
0000 1010 = 10
1111 1111 = -1
0000 0001 = 1
0000 0101 = 5

  • & 与
  • | 或
  • ~ 按位取反
    ~5 = 1111 1010 = -6
  • ^ 按位异或(相同为0,不同为1)
    -1^1 = 1 0000 0000 = 0

2、设计思路

1、设计int和字节数组互相转换的工具类
实现关键:位运算
2、分别按如下顺序将多个零碎小文件归档:
(1)存入文件名长度利用Util工具类转化为字节数组,并存到总字节数组;
(2)存入文件名内容利用f.getName().getBytes转化为字节数组,并存到总字节数组;
(3)存入文件内容长度利用Util工具类转化为字节数组,并存到总字节数组;
(4)将文件内容转化为字节数组[利用文件输入字节流FileInputStream读取,利用字节数组输出流ByteArrayOutputStream进行保存],并利用.toByteArray()方法将保存的字节数组输出流转化为字节数组,然后保存到总字节数组。

3、设计要点

//文件
File f = new File(path);

//读取文件内容到数组中
FileInputStream fis = new FileInputStream(f);
//缓存数组
byte[] buf = new byte[1024];
//记录缓存数组长度
int len0 = 0 ;
//判断文件是否读取完毕
//本来读到的是-128至127;但是在此处read已经将读取到的字节转化成了0~255
while(((len0 = fis.read(buf)) != -1)){
    baos.write(buf, 0, len0);
}
fis.close();
//得到文件内容
byte[] fileContentArr = baos.toByteArray();

注:
问:为何使用fis.read(buf) != -1判断文件是否读取完毕?
答:本来读到的是-128至127;但是在此处read已经将读取到的字节转化成了0~255; 如果不做转化,判断条件就是-129,这样子不方便记忆和理解。

4、具体实现方案

工具util类

package com.mmzs.util;

/**
 * @author: mmzs
 * @date:   2018年8月9日
 * @Description: 
 * 博客地址:https://www.cnblogs.com/mmzs/p/9282412.html
 * @version V1.0
*/
public class Util {
    /**
     * 将int转化为字节数组
     * @return 
     */
    public static byte[] int2Bytes(int i){
        byte[] arr = new byte[4];
        arr[0] = (byte) i;
        arr[1] = (byte) (i >> 8);
        arr[2] = (byte) (i >> 16);
        arr[3] = (byte) (i >> 24);
        return arr;
    }
    
    /**
     * 将字节数组转化为int
     */
    public static int bytes2Int(byte[] bytes){
        int i0 = bytes[0];
        int i1 = (bytes[1] & 0xFF) << 8;
        int i2 = (bytes[2] & 0xFF) << 16;
        int i3 = (bytes[3] & 0xFF) << 24;
        return i0 | i1 | i2 | i3;
    }
}

实现归档Archiver类

package com.mmzs.archiver;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import com.mmzs.util.Util;

/**
 * @author: mmzs
 * @date:   2018年8月8日
 * @Description: 将多个零碎小文件归档
 * 博客地址:https://www.cnblogs.com/mmzs/p/9282412.html
 * @version V1.0
*/
public class Archiver {

    public static void main(String[] args) throws IOException, Exception {
        FileOutputStream fos = new FileOutputStream("d:/test/x.rar");
fos.write(addFile(
"D:/test/test.txt")); fos.write(addFile("D:/test/chart.png")); fos.write(addFile("D:/test/test.xls"));
fos.close();
System.out.println("归档完成,归档后的文件已经存放在"+"d:/test/x.rar"+"目录下"); }
/** * path : d:/xxx/xxx/a.jpg * @throws Exception */ public static byte[] addFile(String path) throws Exception{ //文件 File f = new File(path); //文件名 String fname = f.getName(); //文件名数组 byte[] fnameBytes = fname.getBytes(); int fnameLen = fnameBytes.length; //文件内容长度 int fcontentLen = (int) f.length(); //计算总长度 int total = 4 + fnameLen + 4 + fcontentLen; //初始化总数组 byte[] bytes = new byte[total]; //1.写入文件名长度到总数组 byte[] fnameArr = Util.int2Bytes(fnameLen); System.arraycopy(fnameArr, 0, bytes, 0, 4); //2.写入文件名本身到总数组 System.arraycopy(fnameBytes, 0, bytes, 4, fnameLen); //3.写入文件内容长度到总数组 byte[] fcontentArr = Util.int2Bytes(fcontentLen); System.arraycopy(fcontentArr, 0, bytes, 4 + fnameLen, 4); //4.写入文件内容 //读取文件内容到字节数组中 ByteArrayOutputStream baos = new ByteArrayOutputStream(); FileInputStream fis = new FileInputStream(f); byte[] buf = new byte[1024]; int len = 0; while ((len = fis.read(buf)) != -1) { baos.write(buf, 0, len); } fis.close(); //得到转化为字节数组的文件内容,并将文件内容到总数组 byte[] fileContentArr = baos.toByteArray(); System.arraycopy(fileContentArr, 0, bytes, 4 + fnameLen + 4, fileContentArr.length); return bytes; } }

 最后附一张工程截图:

归档效果图:

 

posted @ 2018-08-10 10:12  淼淼之森  阅读(733)  评论(0编辑  收藏  举报
  👉转载请注明出处和署名