精华内容
下载资源
问答
  • Java压缩/解压缩大文件(> 1GB)
    2021-02-26 08:58:41

    如果将缓冲区大小设置为文件大小,那么意味着只要文件大小太大而无法使用内存,就会出现OutOfMemoryError。

    使用正常的缓冲区大小,让它做到这一点 - 以流式方式缓冲数据,一次一个块,而不是一次一个。

    该类实现缓冲的输出流。通过设置这样一个输出流,应用程序可以将字节写入底层输出流 流,而不必对每个字节写入底层系统调用 。

    因此,使用缓冲区比非缓冲区写入效率更高。

    而且从write方法:

    一般来说,此方法存储从给定的阵列到此 流的缓冲区字节,冲洗缓冲液根据需要基础输出流 。但是,如果所请求的长度至少与此流的缓冲区一样大,则此方法将刷新缓冲区,并将字节直接写入基础输出流。

    每次写入都会导致内存缓冲区填满,直到缓冲区满。当缓冲区满时,它将被刷新并清除。如果使用非常大的缓冲区,则会在刷新之前将大量数据存储在内存中。如果你的缓冲区与输入文件大小相同,那么你就说你需要在整个内容读入内存之前先将其清空。使用默认的缓冲区大小通常很好。将会有更多的物理写入(刷新);你避免了爆炸的记忆。

    通过允许您指定特定的缓冲区大小,API可让您选择内存消耗和I/O之间的适当平衡以适合您的应用程序。如果您调整应用程序的性能,您可能会调整缓冲区大小。但是在很多情况下,默认大小都是合理的。

    更多相关内容
  • 本篇文章主要介绍了Java解压缩zip - 解压缩多个文件或文件夹实例,非常具有实用价值,有需要的可以了解一下。
  • java内存解压zip文件,没有磁盘操作,效率高,基于apache commons-compress实现
  •   Zip是常用的无损压缩算法实现,Java中提供了Zip的实现,本文演示基于内存的方式进行压缩和解压,演示只针对一层目录结构进行,多层目录只需递归操作进行即可。   文中提供完整的工具类,以供大家使用。   ...

    欢迎大家关注本博,同时欢迎大家评论交流,可以给个赞哦!!!

      Zip是常用的无损压缩算法实现,Java中提供了Zip的实现,本文演示基于内存的方式进行压缩和解压,演示只针对一层目录结构进行,多层目录只需递归操作进行即可。

      文中提供完整的工具类,以供大家使用。

      Maven依赖

      ant: ant: 1.8.0:JDK1.7以下版本环境下,JDK原生的ZIP流处理会出现中文条目乱码的问题,此依赖提供了ZIP相关的流实现, 可以完美的解决低版本JDK出现的问题。JDK1.7及JDK1.7+版本上已无此问题。

      commons-io: commons-io: 2.4: JDK原生的流操作是比较繁琐的,例如:流的开闭处理、流的转换处理等,会使得代码无序且凌乱。commons-io针对IO操作提供了良好的封装,可以使用简单的操作完成繁杂的处理,commons-io本身已经对IO做了相对完善的封装。

    <dependency>
    	<groupId>ant</groupId>
    	<artifactId>ant</artifactId>
    	<version>1.8.0</version>
    </dependency>
    <dependency>
    	<groupId>commons-io</groupId>
    	<artifactId>commons-io</artifactId>
    	<version>2.4</version>
    </dependency>
    

      工具类

      通常情况下,可能并不会使用基于内存压缩的方式,但在某些业务场景下,还是有其施展的舞台。

      下面是提供的ZIP算法实现的工具类,提供了compressByZip、compressByZipJdkLower7、decompressByZip三个方法,在无特殊需求的情况下,基本可以满足压缩和解压的需求,代码如下:

    package com.arhorchin.securitit.compress.zip;
    
    import java.io.BufferedInputStream;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipInputStream;
    import java.util.zip.ZipOutputStream;
    
    import org.apache.poi.util.IOUtils;
    
    /**
     * @author Securitit.
     * @note 基于内存以ZIP算法进行压缩和解压工具类.
     */
    public class ZipRamUtil {
    
        /**
         * 条目名称使用的默认字符.
         */
        public static String CHARSET_GBK = "GBK";
    
        /**
         * 使用ZIP算法进行压缩.
         * @param sourceFileBytesMap 待压缩文件的Map集合.
         * @return 压缩后的ZIP文件字节数组.
         * @throws Exception 压缩过程中可能发生的异常,若发生异常,则返回的字节数组长度为0.
         */
        public static byte[] compressByZip(Map<String, byte[]> sourceFileBytesMap) throws Exception {
            // 变量定义.
            ZipEntry zipEntry = null;
            ZipOutputStream zipZos = null;
            ByteArrayOutputStream zipBaos = null;
    
            try {
                // 压缩文件变量初始化.
                zipBaos = new ByteArrayOutputStream();
                zipZos = new ZipOutputStream(zipBaos);
                // 将文件添加到ZIP条目中.
                if (null != sourceFileBytesMap && sourceFileBytesMap.size() > 0) {
                    for (Map.Entry<String, byte[]> singleFile : sourceFileBytesMap.entrySet()) {
                        zipEntry = new ZipEntry(singleFile.getKey());
                        zipZos.putNextEntry(zipEntry);
                        zipZos.write(singleFile.getValue());
                    }
                } else {
                    zipBaos = new ByteArrayOutputStream();
                }
            } finally {
                if (null != zipBaos)
                    zipBaos.close();
                if (null != zipZos)
                    zipZos.close();
            }
            return zipBaos.toByteArray();
        }
    
        /**
         * 使用ZIP算法进行压缩.
         * @param sourceFileBytesMap 待压缩文件的Map集合.
         * @return 压缩后的ZIP文件字节数组.
         * @throws Exception 压缩过程中可能发生的异常,若发生异常,则返回的字节数组长度为0.
         */
        public static byte[] compressByZipJdkLower7(Map<String, byte[]> sourceFileBytesMap) throws Exception {
            return compressByZipJdkLower7(sourceFileBytesMap, CHARSET_GBK);
        }
    
        /**
         * 使用ZIP算法进行压缩.
         * @param sourceFileBytesMap 待压缩文件的Map集合.
         * @return 压缩后的ZIP文件字节数组.
         * @throws Exception 压缩过程中可能发生的异常,若发生异常,则返回的字节数组长度为0.
         */
        public static byte[] compressByZipJdkLower7(Map<String, byte[]> sourceFileBytesMap, String charset)
                throws Exception {
            // 变量定义.
            ByteArrayOutputStream zipBaos = null;
            org.apache.tools.zip.ZipOutputStream zipZos = null;
    
            try {
                // 压缩文件变量初始化.
                zipBaos = new ByteArrayOutputStream();
                zipZos = new org.apache.tools.zip.ZipOutputStream(zipBaos);
                // 将文件添加到ZIP条目中.
                if (null != sourceFileBytesMap && sourceFileBytesMap.size() > 0) {
                    for (Map.Entry<String, byte[]> singleFile : sourceFileBytesMap.entrySet()) {
                        zipZos.putNextEntry(new org.apache.tools.zip.ZipEntry((singleFile.getKey())));
                        zipZos.write(singleFile.getValue());
                    }
                } else {
                    zipBaos = new ByteArrayOutputStream();
                }
            } finally {
                if (null != zipBaos)
                    zipBaos.close();
                if (null != zipZos)
                    zipZos.close();
            }
            return zipBaos.toByteArray();
        }
    
        /**
         * 使用ZIP算法进行解压.
         * @param sourceZipFileBytes ZIP文件字节数组.
         * @return 解压后的文件Map集合.
         * @throws Exception 解压过程中可能发生的异常,若发生异常,返回Map集合长度为0.
         */
        public static Map<String, byte[]> decompressByZip(byte[] sourceZipFileBytes) throws Exception {
            // 变量定义.
            String zipEntryName = null;
            ZipEntry singleZipEntry = null;
            ZipInputStream sourceZipZis = null;
            BufferedInputStream sourceZipBis = null;
            ByteArrayInputStream sourceZipBais = null;
            Map<String, byte[]> targetFilesFolderMap = null;
    
            try {
                // 解压变量初始化.
                targetFilesFolderMap = new HashMap<String, byte[]>();
                sourceZipBais = new ByteArrayInputStream(sourceZipFileBytes);
                sourceZipBis = new BufferedInputStream(sourceZipBais);
                sourceZipZis = new ZipInputStream(sourceZipBis);
                // 条目解压缩至Map中.
                while ((singleZipEntry = sourceZipZis.getNextEntry()) != null) {
                    zipEntryName = singleZipEntry.getName();
                    targetFilesFolderMap.put(zipEntryName, IOUtils.toByteArray(sourceZipZis));
                }
            } finally {
                if (null != sourceZipZis)
                    sourceZipZis.close();
                if (null != sourceZipBis)
                    sourceZipBis.close();
                if (null != sourceZipBais)
                    sourceZipBais.close();
    
            }
            return targetFilesFolderMap;
        }
    
    }
    

      工具类测试

      在Maven依赖引入正确的情况下,复制上面的代码到项目中,修改package,可以直接使用,下面我们对工具类进行简单测试。测试类代码如下:

    package com.arhorchin.securitit.compress.zip;
    
    import java.io.File;
    import java.util.HashMap;
    import java.util.Map;
    
    import org.apache.commons.io.FileUtils;
    
    import com.arhorchin.securitit.compress.zip.ZipRamUtil;
    
    /**
     * @author Securitit.
     * @note ZipRamUtil工具类测试.
     */
    public class ZipRamUtilTester {
    
        public static void main(String[] args) throws Exception {
            Map<String, byte[]> fileBytesMap = null;
    
            fileBytesMap = new HashMap<String, byte[]>();
            // 设置文件列表.
            File dirFile = new File("C:/Users/Administrator/Downloads/个人文件/2020-07-13/files");
            for (File file : dirFile.listFiles()) {
                fileBytesMap.put(file.getName(), FileUtils.readFileToByteArray(file));
            }
    
            byte[] memoryBytes = ZipRamUtil.compressByZip(fileBytesMap);
            FileUtils.writeByteArrayToFile(new File("C:/Users/Administrator/Downloads/个人文件/2020-07-13/ram.zip"), memoryBytes);
            
            fileBytesMap = ZipRamUtil.decompressByZip(memoryBytes);
            System.out.println(fileBytesMap.size());
        }
    
    }
    

      运行测试后,通过查看ram.zip和控制台输出解压后文件数量,可以确认工具类运行结果无误。

      总结

      1) 在小文件、文件数量较小且较为固定时,提倡使用基于内存压缩和解压方式。使用内存换时间,减少频繁的磁盘操作。

      2) 在大文件、文件数量较大时,提倡使用基于磁盘压缩和解压方式。过大文件对服务会造成过度的负载,磁盘压缩和解压可以缓解这种压力。可以参见《Java Zip 基于磁盘实现压缩和解压》

      3) JDK1.6及以下版本中,JDK提供的java.util.zip.*进行压缩时,对于中文条目名称处理会出现乱码,需要额外引用Ant包,使用其org.apache.tools.zip.*来解决这个问题。

      若文中存在错误和不足,欢迎指正!

    本博微信公众号“超哥说码”,欢迎大家订阅,公众号正在完善中,会及时将更优质的博文推送于您!
    在这里插入图片描述

    展开全文
  • 如果将缓冲区大小调整为文件大小,则表示只要文件大小太大而无法使用可用内存,就会出现OutOfMemoryError。使用正常的缓冲区大小让它做它的工作 - 以流式方式缓冲数据,一次缓冲一个块,而不是一次性缓冲。有关说明...

    如果将缓冲区大小调整为文件大小,则表示只要文件大小太大而无法使用可用内存,就会出现OutOfMemoryError。

    使用正常的缓冲区大小让它做它的工作 - 以流式方式缓冲数据,一次缓冲一个块,而不是一次性缓冲。

    有关说明,请参阅BufferedOutputStream的文档:

    The class implements a buffered output stream. By setting up such an

    output stream, an application can write bytes to the underlying output

    stream without necessarily causing a call to the underlying system for

    each byte written.

    因此,使用缓冲区比非缓冲写入更有效。

    并从write方法:

    Ordinarily this method stores bytes from the given array into this

    stream's buffer, flushing the buffer to the underlying output stream

    as needed. If the requested length is at least as large as this

    stream's buffer, however, then this method will flush the buffer and

    write the bytes directly to the underlying output stream.

    每次写入都会导致内存缓冲区填满,直到缓冲区已满。缓冲区已满时,将刷新并清除。如果使用非常大的缓冲区,则会在刷新之前将大量数据存储在内存中。如果您的缓冲区与输入文件的大小相同,那么您说在刷新之前需要将整个内容读入内存。使用默认缓冲区大小通常很好。将有更多的物理写入(刷新);你避免爆炸记忆。

    通过允许您指定特定的缓冲区大小,API允许您在内存消耗和I / O之间选择适当的平衡以适合您的应用程序。如果您调整应用程序的性能,最终可能会调整缓冲区大小。但是在许多情况下,默认大小是合理的。

    展开全文
  • LZ4 Java 基于Yann Collet的工作,可从获得Java的LZ4压缩。... 这两种压缩算法产生的流使用相同的压缩格式,解压缩速度非常快,并且可以通过相同的解压缩器实例进行解压缩。 实作 对于LZ4压缩机,
  • java实现哈夫曼压缩与解压缩

    千次阅读 2019-09-30 10:30:03
    哈夫曼压缩与解压缩java版) 一哈夫曼树以及文件压缩原理: 1.哈夫曼树 : 2.如何利用haffman编码实现文件压缩: 二主要技术点: 三实现过程: 四运行展示: 哈夫曼压缩与解压缩java版) 一哈夫曼树以及...

    目录

    哈夫曼压缩与解压缩(java版)

    一哈夫曼树以及文件压缩原理:

    1.哈夫曼树 :

    2.如何利用haffman编码实现文件压缩:

    二主要技术点:

    三实现过程:

    四运行展示: 


    哈夫曼压缩与解压缩(java版)

    一哈夫曼树以及文件压缩原理:

    1.哈夫曼树 :

    给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近(频率越高的结点离根越进)。

    以 下数组为例,构建哈夫曼树

    int a[] = {0,1,2,3,4,5,6,7,8}

    我们可以发现以下规律

    1:9个数构成的哈夫曼树一共有17个结点,也就是可以n个数可以生产2*n-1个结点

    2:数字越大的数离根节点越近,越小的数离根节点越近。

    2.如何利用haffman编码实现文件压缩:

    比如abc.txt文件中有以下字符aaaabbbccde,

    1.进行字符统计

    aaaabbbccde
    
    a : 4次
    b : 3次
    c : 2次
    d : 1次
    e : 1次

    2.用统计结果构建哈夫曼树

    3.用哈夫曼树生成哈夫曼编码(从根结点开始,路径左边记为0,右边记为1):

    a的编码:1
    b的编码:01
    c的编码:000
    d的编码:0011
    e的编码:0010

    4.哈夫曼编码代替字符,进行压缩。

    源文件内容为:aaaabbbccde
    将源文件用对应的哈夫曼编码(haffman code)替换,则有:11110101 01000000 00110010   (总共3个字节)

    由此可见,源文件一共有11个字符,占11字节的内存,但是经过用haffman code替换之后,只占3个字节,这样就能达到压缩的目的

    二主要技术点:

    1.哈夫曼树算法(哈夫曼压缩的基本算法)

    2.哈希算法(字符统计时候会用到,也可以直接用HashMap统计)

    3.位运算(涉及到将指定位,置0或置1)

    4.java文件操作,以及缓冲操作。

    5.存储模式(大端存储,小端存储,能看懂文件16进制的形式)

    7.设置压缩密码,解压输入密码解压(小编自己加的内容)

    三实现过程:

    以上述aaaabbbccde为例

    1.字符统计:

    public class FreqHuf {
    	public static int BUFFER_SIZE = 1 << 18;
    	int freq[] = new int[256];
    	File file;
    	int count;
    	List<HuffmanFreq> list;
    	
    	FreqHuf(String pathname) throws Exception {
    		list = new ArrayList<>();
    		this.file = new File(pathname);
    		if(!file.exists()){
    			throw new Exception("文件不存在");
    		}
    		System.out.println("进行字符统计中");
    		CensusChar();
    		System.out.println("字符统计完毕");
    	}
    	
    	public void CensusChar() throws IOException{
    		int intchar;
    		FileInputStream fis = new FileInputStream(file);
    		System.out.println("统计中");
    
    //这种统计处理方案,速度极慢,不建议使用,以下采用缓存读数据。
    //		while((intchar = fis.read()) != -1){
    //			freq[intchar]++;
    //		}
    
    		//这里采用缓存机制,一次读1 << 18个字节,大大提高效率。
    		byte[] bytes = new byte[BUFFER_SIZE];
    		while((intchar = fis.read(bytes))!= -1){
    			for(int i = 0; i < intchar;i++){
    				int temp = bytes[i]& 0xff;
    				freq[temp]++;
    			}
    		}
    		
    		
    		
    		fis.close();
    		
    		for(int i = 0; i < 256; i++){
    			if(freq[i] != 0){
    				this.count++;
    			}
    		}
    		
    		int index = 0;
    		for(int i = 0; i < 256; i++){
    			if(freq[i] != 0){
    				HuffmanFreq huffman = new HuffmanFreq();
    				huffman.character = (char)i;
    				huffman.freq = freq[i];
    				list.add(index, huffman);
    			}
    		}
    	}
    }
    //统计每个字符和其频率的类
    public class HuffmanFreq {
    	char character;
    	int freq;
    	
    	HuffmanFreq() {
    	}
    	
    	HuffmanFreq(int character,int freq) {
    		this.character = (char)character;
    		this.freq = freq;
    	}
    
    	char getCharacter() {
    		return character;
    	}
    
    	void setCharacter(int character) {
    		this.character = (char)character;
    	}
    
    	int getFreq() {
    		return freq;
    	}
    
    	void setFreq(int freq) {
    		this.freq = freq;
    	}
    	
    	byte[] infoToByte(){
    		byte[] bt = new byte[6];
    		
    		byte[] b1 = ByteAnd8Types.charToByte(character);
    		for(int i= 0; i < b1.length;i++){
    			bt[i] = b1[i];
    		}
    		
    		byte[] b2 = ByteAnd8Types.intToBytes2(freq);
    		int index = 2;
    		for(int i= 0; i < b2.length;i++){
    			bt[index++] = b2[i];
    		}
    		
    		return bt;
    	}
    
    	@Override
    	public String toString() {
    		return "Huffman [character=" + character + ", freq=" + freq + "]";
    	}
    }

    2.用统计结果构建哈夫曼树:

    //treeSize为总节点数
    private void creatTree(int treeSize){
    		int temp;
    		treeList = new ArrayList<HuffTreeNode>();
    		for(int i =  0; i < treeSize; i++){
    			HuffTreeNode node = new HuffTreeNode();
    			treeList.add(i, node);
    		}
    		
    		for(int i = 0; i < charCount; i++){
    			HuffTreeNode node = treeList.get(i);
    			node.freq.freq = charList.get(i).getFreq();
    			node.freq.character = charList.get(i).getCharacter();
    			node.left = -1;
    			node.right = -1;
    			node.use = 0;
    		}
    		
    		for(int i = charCount; i < treeSize; i++){
    			int index = i;
    			HuffTreeNode node = treeList.get(i);
    			node.use = 0;
    			node.freq.character = '#';
    			node.right = searchmin(index);
    			node.left = searchmin(index);
    			node.freq.freq = treeList.get(node.right).freq.freq + treeList.get(node.left).freq.freq;
    			temp  = searchmin(++index);
    			if(temp == -1){
    				break;
    			}
    			treeList.get(temp).use = 0;
    		}
    	}
    	
    	private int searchmin(int count){
    		int minindex = -1;
    		
    		for(int i = 0; i < count; i++){
    			if(treeList.get(i).use == 0){
    				minindex = i;
    				break;
    			}
    		}
    		if(minindex == -1){
    			return -1;
    		}
    		for(int i = 0; i < count; i++){
    			if((treeList.get(i).freq.freq <= treeList.get(minindex).freq.freq) && treeList.get(i).use == 0){
    				minindex = i;
    			}
    		}
    		treeList.get(minindex).use = 1;
    		return minindex;
    	}

    3.用哈夫曼树生成哈夫曼编码(从根结点开始,路径左边记为0,右边记为1):

            private void bulidhuftreecode(int root, String str){
    		if(treeList.get(root).getLeft() != -1 && treeList.get(root).getRight() != -1){
    			bulidhuftreecode(treeList.get(root).getLeft(), str+"0");
    			bulidhuftreecode(treeList.get(root).getRight(),  str + "1");
    		}
    		else{
    			treeList.get(root).code = str;
    		}	
    	}

     4.哈夫曼编码代替字符,进行压缩,压缩前首先要将文件头(文件标志,字符数量,最后一个字节有效位,密码)字符和其频率的那张表格写入文件,以便于解压缩

        public void creatCodeFile(String path) throws Exception{
    		byte value = 0;
    		int index = 0;
    		int arr[] = new int[256];
    		int intchar;
    		
    		for(int i = 0; i < charCount; i++){
    			arr[treeList.get(i).freq.character] = i;
    			
    		}
    		File file = new File(path);
            if(!file.exists()){
                 if(!file.createNewFile()){
                	 throw new Exception("创建文件失败");
                 }
            }
    		int count = charList.size();
    		HuffmanHead head = new HuffmanHead(count, howlongchar(count), password);
                    //将文件头信息写入文件
    		this.write = new RandomAccessFile(file, "rw");
    		write.write(head.InfoToByte());
                    //将字符及其频率的表写入文件
    		for(HuffmanFreq freq : charList){
    			byte[] bt = freq.infoToByte();
    			write.write(bt);
    		}
    		//将字符用哈夫曼编码进行压缩,这里读写都是采用缓存机制
    		byte[] readBuffer = new byte[BUFFER_SIZE];
    		while((intchar = read.read(readBuffer))!= -1){
    			ProgressBar.SetCurrent(read.getFilePointer());
    			for(int i = 0; i < intchar;i++){
    				int temp = readBuffer[i]& 0xff; 
    				String code = treeList.get(arr[temp]).code;
    				char[] chars = code.toCharArray();
    				
    				for(int j = 0; j < chars.length; j++){
    					if(chars[j] == '0'){
    						value = CLR_BYTE(value, index);
    					}
    					if(chars[j] == '1'){
    						value = SET_BYTE(value, index);
    					}
    					if(++index >= 8){
    						index = 0;
    						writeInBuffer(value);
    					}
    				}
    			}
    		}
    		//此方法速度较慢
    //		while((intchar = is.read()) != -1){
    //			String code = treeList.get(arr[intchar]).code;
    //			char[] chars = code.toCharArray();
    //			
    //			for(int i = 0; i < chars.length; i++){
    //				if(chars[i] == '0'){
    //					value = CLR_BYTE(value, index);
    //				}
    //				if(chars[i] == '1'){
    //					value = SET_BYTE(value, index);
    //				}
    //				if(++index >= 8){
    //					index = 0;
    //					oos.write(value);
    //				}
    //			}
    //		}
    		if(index != 0){
    			writeInBuffer(value);
    		}
    	    byte[] Data = Arrays.copyOfRange(writeBuffer, 0, writeBufferSize);
    	    write.write(Data);
    	    write.close();
    		read.close();
    	}
            //指定位,置1
            byte SET_BYTE(byte value, int index){
    		return (value) |= (1 << ((index) ^ 7));
    	}	
            //指定位,置0
    	byte CLR_BYTE(byte value, int index){ 
    		return (value) &= (~(1 << ((index) ^ 7)));
    	}
            //判断指定位是否为0,0为false,1为true
    	boolean GET_BYTE(byte value, int index){ 
    		return ((value) & (1 << ((index) ^ 7))) != 0;
    	}

    如果一个字节一个字节往文件里写,速度会极慢,为了提高效率,写也采用缓存,先写到缓存区,缓存区满了后写入文件,

            private void writeInBuffer(byte value) throws Exception {
    		if(writeBufferSize < BUFFER_SIZE){
    			writeBuffer[writeBufferSize] = value;
    			if(++writeBufferSize >= BUFFER_SIZE){
    				write.write(writeBuffer);
    				writeBufferSize = 0;
    			}
    		} else{
    			throw new Exception("写入文件出错");
    		}
    	}

    到这里压缩就完成了,以下为解压缩方法

    1.从写入文件中的字符统计的表读出放入list里

    public void init() throws Exception{
    		char isHUf = read.readChar();
                    //验证文件头信息
    		if(isHUf != '哈'){
    			throw new Exception("该文件不是HUFFMAN压缩文件");
    		}
    		this.charCount = read.readChar();
    		this.treeSize = 2*charCount -1;
    		this.lastIndex = read.readChar();
    		int password = read.readInt();
    		if(password != this.password.hashCode()){
    			System.out.println("密码错误");
    		} else{
    			System.out.println("密码正确,正在解压");
    		}
    		
                    //从文件中将字符统计的表读出
    		byte[] buffer = new byte[charCount * 6];
    		read.seek(10);
    		read.read(buffer, 0, charCount * 6);
    		ProgressBar.SetCurrent(read.getFilePointer());
    		for(int i = 0; i < buffer.length; i+=6){
    			byte[] buff = Arrays.copyOfRange(buffer, i, i+2);
    			ByteBuffer bb = ByteBuffer.allocate (buff.length);
    		    bb.put (buff);
    		    bb.flip ();
    		    CharBuffer cb = cs.decode (bb);
    		    byte[] buff1 = Arrays.copyOfRange(buffer, i+2, i+6);
    		    int size = ByteAnd8Types.bytesToInt2(buff1, 0);
    		    HuffmanFreq freq = new HuffmanFreq(cb.array()[0], size);
    		    charList.add(freq);
    		}
    	}

    2.用统计结果构建哈夫曼树(和以上代码一样)

    3.用哈夫曼树生成哈夫曼编码(从根结点开始,路径左边记为0,右边记为1)(和以上代码一样)

    4.遍历文件每个字节,根据哈夫曼编码找到对应的字符,将字符写入新文件

            public void creatsourcefile(String pathname) throws Exception{
    		int root = treeList.size() - 1;
    		int fininsh = 1;
    		long len;
    		File file = new File(pathname);
    		if(!file.exists()){
    			  if(!file.createNewFile()){
    				  throw new Exception("创建文件失败");
    	          }
    		}
    		write = new RandomAccessFile(file, "rw");
    		
    		int intchar;
    		byte[] bytes = new byte[1<<18];
    		int index = 0;
    		while((intchar = read.read(bytes))!= -1){
    			len = read.getFilePointer();
    			ProgressBar.SetCurrent(len);
    			for(int i = 0; i < intchar;i++){
    				for(;index < 8 && fininsh != 0;){
    					if(GET_BYTE(bytes[i], index)){
    						root = treeList.get(root).right;
    					} else{
    						root = treeList.get(root).left;
    					}
    					if(treeList.get(root).right== -1 && treeList.get(root).left == -1){
    						byte temp = (byte)treeList.get(root).freq.character;
    						writeInBuffer(temp);
    						root = treeList.size() - 1;
    					}
    					index++;
    					if(len == this.goalfilelenth && i == intchar-1){
    						if(index >= this.lastIndex){
    							fininsh = 0;
    						}
    					}
    				}
    				index = 0;
    			}
    		}
    		byte[] Data = Arrays.copyOfRange(writeBuffer, 0, writeBufferSize);
    		write.write(Data);
    		write.close();
    		write.close();
    		read.close();
    	}

    四运行展示: 

    以上为哈夫曼压缩,需要具体代码的,可以私信我,谢谢阅读。下方也可以下载资源

    展开全文
  • .tar.gz格式文件需要先对目录内文件进行tar压缩,然后使用GZip进行压缩。   本文针对基于磁盘的压缩和解压进行演示,演示只针对一层目录结构进行,多层目录只需递归操作进行即可。   Maven依赖   org.apache....
  • java(JDK)中我们可以使用ZipOutputStream去创建zip压缩文件,(参考我之前写的文章 使用java API进行zip递归压缩文件夹以及解压 ),也可以使用GZIPOutputStream去创建gzip(gz)压缩文件,但是java中没有一种官方...
  • 解压到硬盘再读进来耽误时间。varLZip:TZipFile;LMem:TMemoryStream;LBytes:TBytes;beginLZip:=TZipFile.Create;tryLMem:=TMemoryStream.Create;...//演示加载到内存流LMem.Position:=0;//这里打开流...
  • java解压缩zip文件-多个.csv格式表格

    千次阅读 2016-10-19 11:28:10
    import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.Input
  • java实现压缩、解压缩的常见问题Memo 国庆假期,宅呀~ 无意中看到一篇java压缩算法的文章,就顺便度娘了一些相关文章来看。 本来想深入研究一下算法,但是,毕竟是假期,哪有那份心思啊,就实际应用简单Memo...
  • 自己找了很久的一个内存直接压缩和解压缩的东西,静态链接库效率不错。
  • JAVA常用压缩算法底层原理&性能比较

    千次阅读 2020-08-26 22:01:09
    压缩算法 目前常用的几个压缩算法 GZIP,一个压缩比高的慢速算法,压缩后的数据适合长期使用。 JDK中的java.util.zip.GZIPInputStream / GZIPOutputStream便是这个算法的实现。 deflate,zip文件用的就是这一算法...
  • 解压缩memShell.zip cd memShell java -jar inject.jar 用法 anyurl?pass_the_world = pass //显示此帮助页面。 anyurl?pass_the_world = pass&model = exec&cmd = whoami //运行os命令。 anyurl?pass_the_...
  • 1、在解决问题之前,先看下jvm堆内存结构,如下图所示: 对于Java应用,虚拟机管理的内存,可以参考如下图所示: 一般对于一个应用来说,如果内存使用过大,可以从两块来分析,第一:堆内存,第二:堆外内存。...
  • 数组压缩原理     我们知道基本数据类型的大小是固定的,比如int32位(1b),而一个物理存储单元占4kb,若只存一个int类型的话,会浪费非常大的物理空间。所以就有了压缩技术。当你存储固定大小...
  • 由于aspose比较吃内存,操作大一点的文件就会堆溢出,所以请先设置好java虚拟机参数:-Xms1024m -Xmx1024m(参考值)。如果亲们在使用过程中有任何问题,请在楼下回复即可。本人亲自破解,内含Eclipse工程,直接导入...
  • 如何获取一个Java对象所占内存大小

    千次阅读 2021-02-26 12:51:59
    ASIHttpRequest:创建队列、下载请求、断点续传、解压缩 ps:本文转载自网络:http://ryan.easymorse.com/?p=12 感谢作者 工程完整代码下载地址:RequestTestDownload1 可完成: 下载指定链接的zip压缩文件 ......
  • java堆外内存泄漏

    万次阅读 2016-07-14 13:53:01
    java堆外内存泄漏 最近有个系统在做压力测试, 环境配置: 4核CPU 8g内存 jdk1.6.0_25,jvm配置-server -Xms2048m -Xmx2048m 出现问题如下 执行并发300人,压测持续1个小时内存使用率从20%上升到100%,tps从1100多...
  • Java各种类型所占用的内存空间究竟多大?
  • Java实现文件的压缩与解压

    万次阅读 多人点赞 2015-05-08 18:17:00
    在开发过程中,有时需要对用户上传的文件进行一个压缩操作,以节约硬盘空间,那么用Java怎么实现文件的压缩与解压呢?很简单,Java为我们提供了一个包,专门负责文件的压缩与解压的,那个包就是java.util.zip;   ...
  • ImageMagick的"转换"命令行... 例如,仅解压缩一个11600 x 5152的图像将消耗大约227MB的内存。 调整大小的过程用的还不止这些。在Java中,是否有一种方法可以将非常大的图像调整为合理的大小,而又不对内存中的整...
  • Java记一次前后端大数据压缩过程

    千次阅读 2021-11-18 16:54:36
    在网上也找了很多的方法,有点是后端压缩了,但是速度也不理想,有的是后端加密了,前端不了等等原因。 整个结论结果就是: 后端使用Base64压缩,前端使用Base64解压,其中依靠编码转换方法(unzip)。 ...
  • 之前没有接触过用Java压缩文件的,所以就直接上网找了一个例子改了一下用了,改完以后也能使用,但是随着前端所传图片的大小越来越大的时候,耗费的时间也在急剧增加, 最后测了一下压缩20M的文件竟然需要30秒的...
  • 综述 许多信息资料都或多或少的包含一些多余的数据。通常会导致在客户端与服务器之间,应用程序与计算机之间极大的数据传输量。...这篇文章简要的介绍了数据的压缩与解压缩,并展示了用java.util.zip包来实
  • ZIpFile.entries()获取的是压缩包内的所有文件(包括文件夹),不只是第一层的文件(和文件夹
  •   Zip是常用的无损压缩算法实现,Java中提供了Zip的实现,本文演示基于磁盘的方式进行压缩和解压,演示只针对一层目录结构进行,多层目录只需递归操作进行即可。   文中提供完整的工具类,以供大家使用。   ...
  • 由于aspose比较吃内存,操作大一点的文件就会堆溢出,所以请先设置好java虚拟机参数:-Xms1024m -Xmx1024m(参考值)。如果亲们在使用过程中有任何问题,请在楼下回复即可。本人亲自破解,内含Eclipse工程,直接导入...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 40,694
精华内容 16,277
关键字:

java解压缩内存

java 订阅