文件归档与解档问题

在大数据开发中,或这一些项目中,经常遇到很多小文件的处理,为了减小namenode内存的占用,提高效率,经常将小文件压缩并归档处理,而在流的读取与写的操作的时候,归档后还需要解档,下面写一个工具类,实现文件的归档与解档:

1.字节数组与整数转化的工具类

package java.util;

/**
 * 数据工具类
 */
public class DataUtil {

	/**
	 * 将整数转换成字节数组
	 */
	public static byte[] int2ByteArr(int i){
		byte[] bytes = new byte[4] ;
		bytes[0] = (byte)(i >> 24) ;
		bytes[1] = (byte)(i >> 16) ;
		bytes[2] = (byte)(i >> 8) ;
		bytes[3] = (byte)(i >> 0) ;
		return bytes ;
	}

	/**
	 * 将字节数组转换成整数
	 */
	public static int byteArr2Int(byte[] arr){
		return  (arr[0] & 0xff) << 24
				| (arr[1] & 0xff) << 16
				| (arr[2] & 0xff) << 8
				| (arr[3] & 0xff) << 0 ;
	}
}

2.实现文件归档与解档

package java.io;

import java.util.DataUtil;

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

/**
 * 归档器
 */
public class Archiver {

	/**
	 * 将file文件追加到xar中
	 */
	public void appendFile(String xar , String file){
		try {
			//归档文件输出流
			FileOutputStream fos = new FileOutputStream(xar,true) ;

			//1.文件名程度
			File f = new File(file);
			String fileName = f.getName();
			byte[] fileNameBytes = fileName.getBytes();
			byte[] fileNameLenBytes = DataUtil.int2ByteArr(fileNameBytes.length);
			fos.write(fileNameLenBytes);

			//2.文件名内容
			fos.write(fileNameBytes);

			//3.文件长度
			int len = (int)f.length();
			byte[] lenBytes = DataUtil.int2ByteArr(len) ;
			fos.write(lenBytes);

			//4.文件内容
			FileInputStream fis = new FileInputStream(f) ;
			byte[] buf = new byte[1024] ;
			int len0 = 0 ;
			while((len0 = fis.read(buf)) != -1){
				fos.write(buf,0,len0);
			}
			fis.close();
			fos.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 解档
	 */
	public void unarchive(String xar , String dir){
		try {
			FileInputStream fis = new FileInputStream(xar) ;
			while(true){
				byte[] byte4 = new byte[4] ;
				int len = fis.read(byte4) ;
				//读到文件尾
				if(len == -1){
					break ;
				}
				//
				byte[] fileNameBytes = new byte[DataUtil.byteArr2Int(byte4)];
				//读取文件名
				fis.read(fileNameBytes);
				String fileName = new String(fileNameBytes) ;
				File newFile = new File(dir,fileName) ;
				FileOutputStream fos = new FileOutputStream(newFile) ;

				//读取文件长度
				fis.read(byte4);
				byte[] fileContBytes = new byte[DataUtil.byteArr2Int(byte4)] ;

				//读取文件内容
				fis.read(fileContBytes) ;
				fos.write(fileContBytes);
				fos.close();
			}
			fis.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

3.测试

package java.test;

import java.io.Archiver;
import org.junit.Test;

/**
 * 测试归档,解档
 */
public class TestArchiver {

	/**
	 * 测试归档
	 */
	@Test
	public void TestArchive(){
		Archiver a = new Archiver();
		a.appendFile("d:/arch/my.xar","d:/arch/1.txt");
		a.appendFile("d:/arch/my.xar","d:/arch/2.gif");
		a.appendFile("d:/arch/my.xar","d:/arch/3.mp3");
	}
	/**
	 * 测试归档
	 */
	@Test
	public void TestUnarchive(){
		Archiver a = new Archiver();
		a.unarchive("d:/arch/my.xar","d:/arch/unarch");
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值