文档章节

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

Z
 Z13
发布于 2017/01/18 16:38
字数 1167
阅读 19
收藏 0
.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);
    }
}

 

本文转载自:http://peak1992.iteye.com/blog/2353295

Z

Z13

粉丝 0
博文 8
码字总数 0
作品 0
广州
程序员
私信 提问
Mac Pro 下搭建maven环境

版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/lyhhj/article/details/48477191 突然想学习一下Spring MVC,要用到maven环境,自己搭建了一下,就记下来防止以后忘...

进阶的玄武
2015/09/15
0
0
CKEditor和CKFinder整合实现上传下载功能

事先说明:此整合的是java版本的, 用到的有:jsp + ckeditor + ckfinder (没有servlet 及其它框架技术) 一.需要的资源: 用到的网站,文件自己下载: a) ckeditor_3.6.2 (解压) download...

jxlgzwh
2013/03/06
696
0
Android-NDK 开发之第四个例子--用C/C++调用Java

用C/C++调用Java的方法我没有去研究,也不知道从哪里开始研究,对Linux我了解到很少,希望有朋友可以给些资料,我的水平很差,望大家多多包涵。 这个例子是别人的代码,我忘记从来里弄来的了...

鉴客
2011/11/25
4.4K
2
ubuntu如何完全卸载和安装 Java及android环境?

最近,迷上了java,一时间什么环境变量/虚拟机都猛然袭来,有点不适。环境配置在前,这所自然。平时搞PHP都喜欢自己倒腾环境,自然时因为系统默认版本并不如意罢。java而言,也有类似情节。不...

NILYANG
2013/02/27
18.6K
1
Ubuntu10.04中手动安装jdk6

在UBUNTU中搭建android开发环境,需要安装jdk。命令行下载特别慢,手动安装吧。 提示:最好使用root登录,不然下面第三步的移动文件夹会提示你的权限不够。 一,下载jdk安装文件:jdk-6u24-li...

拉风的道长
2012/07/18
682
0

没有更多内容

加载失败,请刷新页面

加载更多

读书笔记:深入理解ES6 (五)

第五章 解构:使数据访问更便捷 第1节 为什么使用解构功能?   在ES5中,开发者们从对象、数组中获取特定数据并赋值给变量,编写了很多看起来同质化的代码。例如: 1 let options = {2 ...

张森ZS
20分钟前
18
0
CentOS7 yum方式安装MySQL5.7

在CentOS中默认安装有MariaDB,这个是MySQL的分支,但为了需要,还是要在系统中安装MySQL,而且安装完成之后可以直接覆盖掉MariaDB。 1 下载并安装MySQL官方的 Yum Repository [root@localho...

roockee
28分钟前
14
0
Allegro三种自定义设置快捷键的方法

Allegro自定义设置快捷键的三种方法: 1、在Allegro PCB editor 命令窗口直接定义 2、通过修改用户变量env文件来设置快捷键 3、定义笔画为快捷键 1、在Allegro PCB editor 命令窗口直接定义 ...

demyar
33分钟前
15
0
如何做一张能让人眼前一亮的大屏?

作为在职场驰骋的社会人,提到数据可视化大家应该都不陌生了。数据可视化的作用也不用我多说,主要是利用图形化手段,更清晰直观地将数据展示。多层次、交互式的可视化分析能够方便决策者理解...

朕想上头条
33分钟前
8
0
TL138/1808/6748-EthEVM开发板硬件CPU、FLASH、RAM

TL138/1808/6748-EthEVM是广州创龙基于SOM-TL138/1808/6748核心板开发的一款开发板,具有三个网络接口。由于SOM-TL138/1808/6748核心板管脚兼容,所以此三个核心板共用同一个底板。开发板采用...

Tronlong创龙
38分钟前
11
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部