`

java 实现.Z解压(代码是忘记在哪里找到的,自己整合了一下)

.Z 
阅读更多
import java.io.*;


public class ZDecodes extends FilterInputStream {


    /**
     * @param is the input stream to decompress
     * @exception IOException if the header is malformed
     */
    public ZDecodes(InputStream is)  throws IOException
    {
        super(is);
        parse_header();
    }


    byte[] one = new byte[1];
    public synchronized int read() throws IOException
    {
        int b = in.read(one, 0, 1);
        if (b == 1)
            return (one[0] & 0xff);
        else
            return -1;
    }


    // string table stuff
    private static final int TBL_CLEAR = 0x100;
    private static final int TBL_FIRST = TBL_CLEAR + 1;

    private int[]  tab_prefix;
    private byte[] tab_suffix;
    private int[]  zeros = new int[256];
    private byte[] stack;

    // various state
    private boolean block_mode;
    private int  n_bits;
    private int  maxbits;
    private int  maxmaxcode;
    private int  maxcode;
    private int  bitmask;
    private int  oldcode;
    private byte finchar;
    private int  stackp;
    private int  free_ent;

    // input buffer
    private byte[]  data = new byte[10000];
    private int     bit_pos = 0, end = 0, got = 0;
    private boolean eof  = false;
    private static final int EXTRA = 64;


    public synchronized int read(byte[] buf, int off, int len)
            throws IOException
    {
        if (eof)  return -1;
        int start = off;

	/* Using local copies of various variables speeds things up by as
	 * much as 30% !
	 */
        int[]  l_tab_prefix = tab_prefix;
        byte[] l_tab_suffix = tab_suffix;
        byte[] l_stack      = stack;
        int    l_n_bits     = n_bits;
        int    l_maxcode    = maxcode;
        int    l_maxmaxcode = maxmaxcode;
        int    l_bitmask    = bitmask;
        int    l_oldcode    = oldcode;
        byte   l_finchar    = finchar;
        int    l_stackp     = stackp;
        int    l_free_ent   = free_ent;
        byte[] l_data       = data;
        int    l_bit_pos    = bit_pos;


        // empty stack if stuff still left

        int s_size = l_stack.length - l_stackp;
        if (s_size > 0)
        {
            int num = (s_size >= len) ? len : s_size ;
            System.arraycopy(l_stack, l_stackp, buf, off, num);
            off += num;
            len -= num;
            l_stackp += num;
        }

        if (len == 0)
        {
            stackp = l_stackp;
            return off-start;
        }


        // loop, filling local buffer until enough data has been decompressed

        main_loop: do
        {
            if (end < EXTRA)  fill();

            int bit_in = (got > 0) ? (end - end%l_n_bits)<<3 :
                    (end<<3)-(l_n_bits-1);

            while (l_bit_pos < bit_in)
            {
                // check for code-width expansion

                if (l_free_ent > l_maxcode)
                {
                    int n_bytes = l_n_bits << 3;
                    l_bit_pos = (l_bit_pos-1) +
                            n_bytes - (l_bit_pos-1+n_bytes) % n_bytes;

                    l_n_bits++;
                    l_maxcode = (l_n_bits==maxbits) ? l_maxmaxcode :
                            (1<<l_n_bits) - 1;

                    if (debug)
                        System.err.println("Code-width expanded to " + l_n_bits);

                    l_bitmask = (1<<l_n_bits)-1;
                    l_bit_pos = resetbuf(l_bit_pos);
                    continue main_loop;
                }


                // read next code

                int pos = l_bit_pos>>3;
                int code = (((l_data[pos]&0xFF) | ((l_data[pos+1]&0xFF)<<8) |
                        ((l_data[pos+2]&0xFF)<<16))
                        >> (l_bit_pos & 0x7)) & l_bitmask;
                l_bit_pos += l_n_bits;


                // handle first iteration

                if (l_oldcode == -1)
                {
                    if (code >= 256)
                        throw new IOException("corrupt input: " + code +
                                " > 255");
                    l_finchar = (byte) (l_oldcode = code);
                    buf[off++] = l_finchar;
                    len--;
                    continue;
                }


                // handle CLEAR code

                if (code == TBL_CLEAR && block_mode)
                {
                    System.arraycopy(zeros, 0, l_tab_prefix, 0, zeros.length);
                    l_free_ent = TBL_FIRST - 1;

                    int n_bytes = l_n_bits << 3;
                    l_bit_pos = (l_bit_pos-1) +
                            n_bytes - (l_bit_pos-1+n_bytes) % n_bytes;
                    l_n_bits  = INIT_BITS;
                    l_maxcode = (1 << l_n_bits) - 1;
                    l_bitmask = l_maxcode;

                    if (debug)  System.err.println("Code tables reset");

                    l_bit_pos = resetbuf(l_bit_pos);
                    continue main_loop;
                }


                // setup

                int incode = code;
                l_stackp = l_stack.length;


                // Handle KwK case

                if (code >= l_free_ent)
                {
                    if (code > l_free_ent)
                        throw new IOException("corrupt input: code=" + code +
                                ", free_ent=" + l_free_ent);

                    l_stack[--l_stackp] = l_finchar;
                    code = l_oldcode;
                }


                // Generate output characters in reverse order

                while (code >= 256)
                {
                    l_stack[--l_stackp] = l_tab_suffix[code];
                    code = l_tab_prefix[code];
                }
                l_finchar  = l_tab_suffix[code];
                buf[off++] = l_finchar;
                len--;


                // And put them out in forward order

                s_size = l_stack.length - l_stackp;
                int num = (s_size >= len) ? len : s_size ;
                System.arraycopy(l_stack, l_stackp, buf, off, num);
                off += num;
                len -= num;
                l_stackp += num;


                // generate new entry in table

                if (l_free_ent < l_maxmaxcode)
                {
                    l_tab_prefix[l_free_ent] = l_oldcode;
                    l_tab_suffix[l_free_ent] = l_finchar;
                    l_free_ent++;
                }


                // Remember previous code

                l_oldcode = incode;


                // if output buffer full, then return

                if (len == 0)
                {
                    n_bits   = l_n_bits;
                    maxcode  = l_maxcode;
                    bitmask  = l_bitmask;
                    oldcode  = l_oldcode;
                    finchar  = l_finchar;
                    stackp   = l_stackp;
                    free_ent = l_free_ent;
                    bit_pos  = l_bit_pos;

                    return off-start;
                }
            }

            l_bit_pos = resetbuf(l_bit_pos);
        } while (got > 0);

        n_bits   = l_n_bits;
        maxcode  = l_maxcode;
        bitmask  = l_bitmask;
        oldcode  = l_oldcode;
        finchar  = l_finchar;
        stackp   = l_stackp;
        free_ent = l_free_ent;
        bit_pos  = l_bit_pos;

        eof = true;
        return off-start;
    }


    /**
     * Moves the unread data in the buffer to the beginning and resets
     * the pointers.
     */
    private final int resetbuf(int bit_pos)
    {
        int pos = bit_pos >> 3;
        System.arraycopy(data, pos, data, 0, end-pos);
        end -= pos;
        return 0;
    }


    private final void fill()  throws IOException
    {
        got = in.read(data, end, data.length-1-end);
        if (got > 0)  end += got;
    }


    public synchronized long skip(long num)  throws IOException
    {
        byte[] tmp = new byte[(int) num];
        int got = read(tmp, 0, (int) num);

        if (got > 0)
            return (long) got;
        else
            return 0L;
    }


    public synchronized int available()  throws IOException
    {
        if (eof)  return 0;

        return in.available();
    }


    private static final int LZW_MAGIC		= 0x1f9d;
    private static final int MAX_BITS		= 16;
    private static final int INIT_BITS		= 9;
    private static final int HDR_MAXBITS 	= 0x1f;
    private static final int HDR_EXTENDED	= 0x20;
    private static final int HDR_FREE     	= 0x40;
    private static final int HDR_BLOCK_MODE	= 0x80;

    private void parse_header()  throws IOException
    {
        // read in and check magic number

        int t = in.read();
        if (t < 0)  throw new EOFException("Failed to read magic number");
        int magic = (t & 0xff) << 8;
        t = in.read();
        if (t < 0)  throw new EOFException("Failed to read magic number");
        magic += t & 0xff;
        if (magic != LZW_MAGIC)
            throw new IOException("Input not in compress format (read " +
                    "magic number 0x" +
                    Integer.toHexString(magic) + ")");


        // read in header byte

        int header = in.read();
        if (header < 0)  throw new EOFException("Failed to read header");

        block_mode = (header & HDR_BLOCK_MODE) > 0;
        maxbits    = header & HDR_MAXBITS;

        if (maxbits > MAX_BITS)
            throw new IOException("Stream compressed with " + maxbits +
                    " bits, but can only handle " + MAX_BITS +
                    " bits");

        if ((header & HDR_EXTENDED) > 0)
            throw new IOException("Header extension bit set");

        if ((header & HDR_FREE) > 0)
            throw new IOException("Header bit 6 set");

        if (debug)
        {
            System.err.println("block mode: " + block_mode);
            System.err.println("max bits:   " + maxbits);
        }


        // initialize stuff

        maxmaxcode = 1 << maxbits;
        n_bits     = INIT_BITS;
        maxcode    = (1 << n_bits) - 1;
        bitmask    = maxcode;
        oldcode    = -1;
        finchar    = 0;
        free_ent   = block_mode ? TBL_FIRST : 256;

        tab_prefix = new int[1 << maxbits];
        tab_suffix = new byte[1 << maxbits];
        stack      = new byte[1 << maxbits];
        stackp     = stack.length;

        for (int idx=255; idx>=0; idx--)
            tab_suffix[idx] = (byte) idx;
    }


    private static final boolean debug = false;

    public static void ZDecodes(String zPath, String oPath) throws Exception{
        ZDecodes(zPath,oPath,true);
    }

    public static void ZDecodes(String zPath, String oPath,boolean isNeedDelSrc) throws Exception{
        OutputStream outputStream = null;
        InputStream in = null;
        try {
            File file = new File(oPath); //解压后的存放路径
            if (!file.exists()) file.createNewFile();
            outputStream = new FileOutputStream(file);
            in = new ZDecodes(new FileInputStream(new File(zPath)));//需要解压的文件
            byte[] buf = new byte[8192];
            while (true) {
                int got = in.read(buf);
                if (got < 0)  break;
                outputStream.write(buf, 0, got);
            }
            outputStream.flush();
        } finally {
            if (null != outputStream) outputStream.close();
            if (null != in) in.close();
        }

        if(isNeedDelSrc){
            FileUtils.deleteFile(zPath);
        }
    }

    public static void main (String args[])  throws Exception
    {
       /* OutputStream outputStream = null;
        InputStream in = null;
        try {
            File tempFile = new File("D:/XXX.txt.Z");//需要解压的文件
            String filepath = "D:/222/XXX.txt";//解压后的存放路径
            outputStream = new FileOutputStream((new File(filepath)));
            in = new ZDecodes(new FileInputStream(tempFile));

            byte[] buf = new byte[100000];
            int tot = 0;
            long beg = System.currentTimeMillis();

            while (true)
            {
                int got = in.read(buf);
                if (got < 0)  break;
                // System.out.write(buf, 0, got);
                outputStream.write(buf, 0, got);
                tot += got;
            }
            outputStream.flush();
            long end = System.currentTimeMillis();
            System.err.println("Time: " + (end-beg)/1000. + " seconds");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != outputStream) outputStream.close();
            if (null != in) in.close();
        }
*/
       String zPath = "D:/XXX.txt.Z";//需要解压的文件
       String oPath = "D:/222/XXX.txt";//解压后的存放路径
        ZDecodes.ZDecodes(zPath, oPath);
    }
}

 

分享到:
评论

相关推荐

    在浏览器上运行Java程序 Doppio.7z

    Doppio是一个开源的JavaScript实现的Java虚拟机,它允许Java代码在Web浏览器中执行,无需依赖本地JVM。这个项目的核心目标是提供一个与标准Java虚拟机兼容的环境,使得开发者可以编写Java代码并直接在浏览器中运行,...

    Java经典指令大全.7z

    - `javac`用于将源代码(.java文件)编译成字节码(.class文件)。 - 编译选项如:`-d`指定输出目录,`-g`添加调试信息,`-nowarn`抑制警告等。 3. **Java解释器 java**: - `java`命令用于运行已编译的Java程序...

    JAVA100例之实例40 压缩和解压文件

    在Java编程语言中,压缩和解压文件是常见的文件操作任务,这在处理大量数据或者进行文件传输时尤其有用。本实例"JAVA100例之实例40 压缩和解压文件"将深入讲解如何使用Java来实现这个功能。我们将探讨使用Java的内置...

    ElasticSearch整合JavaApi代码

    在IT行业中,Elasticsearch(ES)是一种广泛使用的开源全文搜索引擎,它基于Lucene构建,提供了分布式、实时、可扩展的搜索和分析能力。本文将深入探讨如何利用Java API与Elasticsearch进行集成,分为基础使用和高级...

    Java用的在线地图浏览模块.7z

    "Java用的在线地图浏览模块.7z"可能包含了一个用于开发地图应用的Java库或者框架,这可能是开源项目,也可能是自定义开发的组件。这个压缩包中的文件列表并未详细给出,但我们可以基于常见的GIS开发实践来讨论相关...

    hanmingcode.7z

    在描述中,"hanmingcode.7z" 并没有提供具体的内容信息,但我们可以推测这可能包含了与编程或代码相关的资料。文件名"hanmingcode"暗示了这可能是一些关于“韩明代码”或者某个开发者名为韩明的代码库。通常,这种...

    springbt_vesta.7z

    "springbt_vesta.7z" 是一个压缩文件,很可能包含与Spring Boot和Vesta相关的源代码、配置文件或其他资源。Spring Boot是一个流行的Java框架,用于简化创建独立的、生产级别的基于Spring的应用程序。它内置了Tomcat...

    vue_shiro.7z

    本项目 "vue_shiro.7z" 提供了一个完整的开发环境,将 Vue.js(前端)、Element UI(前端UI)、SpringBoot(后端)和 Shiro(安全框架)整合在一起,实现了基于 MySQL 数据库的身份认证和权限控制功能。具体来说,...

    eclipse04.7z.rar

    标题 "eclipse04.7z.rar" 暗示我们正在处理一个关于Eclipse集成开发环境(IDE)的压缩文件。Eclipse是一款开源、跨平台的Java IDE,但同时也支持其他编程语言如C++, Python等。这个压缩文件可能是Eclipse的一个特定...

    scala-hive-HBASE-Api.7z

    Scala、Hive与HBase是大数据处理领域中的关键组件,它们在Java开发环境中扮演着重要角色。...开发者可以通过解压并分析其中的代码,学习如何在Java和Scala环境中有效地利用Hive和HBase进行大数据处理。

    mpr工程文件生成器.7z

    在使用这个生成器之前,用户需要先解压"mpr工程文件生成器.7z",通常可以通过7-Zip软件或者其他支持7z格式的解压工具来完成。 mpr工程文件的生成过程可能涉及以下几个步骤: 1. **项目配置**:用户需要指定工程的...

    10-手机通讯录系统.7z

    1. **源代码**:如`.java`(Java)、`.swift`(iOS Swift)或`.cpp`(C++)等,这些文件代表了应用的核心代码,用于处理数据存储、界面交互、功能实现等。 2. **设计文档**:可能包括`.md`(Markdown)或`.pdf`,...

    Maven2 的新特性.7z

    Maven2 的新特性.7z 文档选项 打印本页 将此页作为电子邮件发送 级别: 初级 键 胡 (jianhgreat@hotmail.com), 西安交通大学硕士 伟红 胡 (huweih@cn.ibm.com), 工程师,IBM 区域合作伙伴支持...

    springboot-all-demo.7z

    《Spring Boot整合Spring Security实现权限控制详解》 在IT领域,Spring Boot以其便捷的开发体验和强大的集成能力深受开发者喜爱。而Spring Security作为Spring生态中的安全框架,为应用程序提供了全面的安全管理...

    baidu-parent.7z

    SSM框架是Java开发Web应用时常用的三大框架整合,包括Spring、SpringMVC和MyBatis。这个名为“baidu-parent.7z”的压缩包很可能包含了一个完整的项目结构,为开发者提供了一个基于SSM的起点。 Spring框架是核心,它...

    基于JAVA的小型办公自动化系统

    【描述】中的“基于JAVA的办公自动化系统”指的是使用Java编程语言开发的软件系统,该系统旨在提高工作效率,整合办公流程,实现信息化管理。它通常包括文档管理、任务分配、日程安排、通知公告、工作流引擎等多种...

    双鱼林jsp版超市信息管理系统.7z

    7z格式是一种高压缩比的数据存储格式,用于整合并保护源代码。 【描述】:这个系统可能包括了库存管理、销售统计、采购订单、客户管理、员工管理等多个模块,旨在通过JavaServer Pages(JSP)技术,结合后端数据库...

    202111126_opencv-2.4.10.7z

    在压缩包"opencv-2.4.10.7z"中,我们可以期待找到OpenCV的源代码、头文件、预编译的静态库文件以及其他相关资源。开发者可以利用这些资源来构建自己的项目,将OpenCV的功能整合到自己的应用程序中。使用静态库时,...

    AlphaTitleBar.7z

    通过对压缩包内容的解压和研究,我们可以学习到具体的实现方式,包括XML布局文件的结构、Java代码逻辑以及如何将这种效果整合进自己的应用。这种自定义的ActionBar渐变效果是Android开发中提高用户体验的一种巧妙...

    dbedit_1.0.3_1.bin.dist_3.X.7z

    在安装dbedit插件时,首先需要解压“dbedit_1.0.3_1.bin.dist_3.X.7z”文件,然后通过Eclipse的“Install New Software”功能,导入解压后的插件文件夹路径,按照向导提示完成安装。安装完成后,可以在Eclipse的...

Global site tag (gtag.js) - Google Analytics