Java LZW压缩算法的实现

Java LZW压缩算法的实现,java,compression,lzw,Java,Compression,Lzw,我一直在阅读基于词典的压缩算法,包括LZW和LZSS。然后,我想用Java实现LZW,并开始研究它。我不是开发人员,因此我怀疑我的实现可能没有效率。你能看一下代码并告诉我在我的实现中什么是错误的或效率低下的吗?这是完整的代码 public class LZW { public HashMap compdic, decompdic; String fileName = "walaloo.txt"; short lastcode = 0, dlastcode = 0;

我一直在阅读基于词典的压缩算法,包括LZW和LZSS。然后,我想用Java实现LZW,并开始研究它。我不是开发人员,因此我怀疑我的实现可能没有效率。你能看一下代码并告诉我在我的实现中什么是错误的或效率低下的吗?这是完整的代码

public class LZW {

    public HashMap compdic, decompdic;
    String fileName = "walaloo.txt";
    short lastcode = 0, dlastcode = 0;

    LZW() {
        compdic = new HashMap<String, Integer>();
        decompdic = new HashMap<Integer, String>();
        createDictionary();
    }

    public void createDictionary() {
        try {
            short code;
            char ch;
            FileInputStream fis = new FileInputStream(fileName);
            InputStreamReader rdr = new InputStreamReader(fis, "utf-8");
            while ((code = (short) rdr.read()) != -1) {
                ch = (char) code;

                if (!compdic.containsKey(ch)) {
                    compdic.put("" + ch, code);
                    decompdic.put(code, "" + ch);
                    if (code > lastcode) {
                        lastcode = code;
                        dlastcode = code;
                    }
                }
            }
            fis.close();
        } catch (Exception ex) {
            Logger.getLogger(LZW.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void compressFile() {
        try {
            short code, codeword;
            char c;
            String s;

            System.out.print("Compressing...");
            FileInputStream fis = new FileInputStream(fileName);
            InputStreamReader rdr = new InputStreamReader(fis, "utf-8");
            FileOutputStream fos = new FileOutputStream(fileName + "1.lzw");
            ObjectOutputStream fout = new ObjectOutputStream(fos);

            s = (char) rdr.read() + "";
            while ((code = (short) rdr.read()) != -1) {
                c = (char) code;

                if (!compdic.containsKey(s + c)) {
                    codeword = Short.parseShort(compdic.get(s).toString());

                    fout.writeShort(codeword);
                    compdic.put(s + c, ++lastcode);
                    s = "" + c;
                } else {
                    s = s + c;
                }
            }

            codeword = Short.parseShort(compdic.get(s).toString());
            fout.writeShort(codeword);
            fout.writeShort(00);

            fout.close();
            fis.close();

            System.out.print("done");

        } catch (Exception ex) {
            Logger.getLogger(LZW.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void decompressFile() {
        short priorcode = -1, codeword = -1;
        char c;

        String priorstr, str;
        FileInputStream fis; 
        FileWriter fos; 
        ObjectInputStream fin;

        try {
            fis = new FileInputStream(fileName + "1.lzw");
            fos = new FileWriter(fileName + "2.txt");
            fin = new ObjectInputStream(fis);

            System.out.print("\nDecompressing...");
            priorcode = fin.readShort();
            fos.write(decompdic.get(priorcode).toString());
            while ((codeword = fin.readShort()) != -1) {
                if(codeword == 00)
                    break;

                priorstr = decompdic.get(priorcode).toString();

                if (decompdic.containsKey(codeword)) {
                    str = decompdic.get(codeword).toString();
                    fos.write(str);
                    decompdic.put(++dlastcode, priorstr + str.charAt(0));
                } else {
                    decompdic.put(++dlastcode, priorstr + priorstr.charAt(0));
                    fos.write(priorstr + priorstr.charAt(0));
                }

                priorcode = codeword;
            }

            fos.close();
            fis.close();
            System.out.print("done\n");

        } catch (Exception ex) {
            //Logger.getLogger(LZW.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println("\n\nError: " + ex.getMessage());
            System.out.print(codeword + " " + priorcode + " " + decompdic.get(133) + " " + dlastcode);
        }
    }

    public static void main(String args[]) {
        LZW lzw = new LZW();
        lzw.compressFile();
        lzw.decompressFile();
    }
}
公共类LZW{
公共哈希映射compdic、decompdic;
字符串fileName=“walaloo.txt”;
短lastcode=0,dlastcode=0;
LZW(){
compdic=新的HashMap();
decodic=新的HashMap();
createDictionary();
}
public void createDictionary(){
试一试{
短代码;
char ch;
FileInputStream fis=新的FileInputStream(文件名);
InputStreamReader rdr=新的InputStreamReader(fis,“utf-8”);
而((代码=(短)rdr.read())!=-1){
ch=(char)代码;
如果(!组件容器(ch)){
复合输入(“+ch,代码);
反编译输入(代码“”+ch);
如果(代码>最后代码){
lastcode=代码;
dlastcode=代码;
}
}
}
fis.close();
}捕获(例外情况除外){
Logger.getLogger(LZW.class.getName()).log(Level.SEVERE,null,ex);
}
}
public void compressFile(){
试一试{
短码、码字;
字符c;
字符串s;
系统输出打印(“压缩…”);
FileInputStream fis=新的FileInputStream(文件名);
InputStreamReader rdr=新的InputStreamReader(fis,“utf-8”);
FileOutputStream fos=新的FileOutputStream(文件名+“1.lzw”);
ObjectOutputStream fout=新的ObjectOutputStream(fos);
s=(char)rdr.read()+“”;
而((代码=(短)rdr.read())!=-1){
c=(char)代码;
如果(!组件容器(s+c)){
codeword=Short.parseShort(compdic.get.toString());
fout.writeShort(码字);
compdic.put(s+c,++lastcode);
s=”“+c;
}否则{
s=s+c;
}
}
codeword=Short.parseShort(compdic.get.toString());
fout.writeShort(码字);
四、书面支持(00);
fout.close();
fis.close();
系统输出打印(“完成”);
}捕获(例外情况除外){
Logger.getLogger(LZW.class.getName()).log(Level.SEVERE,null,ex);
}
}
公共void解压缩文件(){
短优先码=-1,码字=-1;
字符c;
字符串优先级,str;
文件输入流fis;
文件编写器;
目的输入流鳍;
试一试{
fis=新文件输入流(文件名+“1.lzw”);
fos=新文件编写器(文件名+“2.txt”);
fin=新目标输入流(fis);
系统输出打印(“\n压缩…”);
priorcode=fin.readShort();
fos.write(decodic.get(priorcode.toString());
while((codeword=fin.readShort())!=-1){
如果(码字==00)
打破
priorstr=decodic.get(priorcode.toString();
if(反编译的containsKey(码字)){
str=decodic.get(码字).toString();
fos.write(str);
decodic.put(++dlastcode,priorstr+str.charAt(0));
}否则{
反编译put(++dlastcode,priorstr+priorstr.charAt(0));
fos.write(priorstr+priorstr.charAt(0));
}
优先级代码=码字;
}
fos.close();
fis.close();
系统输出打印(“完成”);
}捕获(例外情况除外){
//Logger.getLogger(LZW.class.getName()).log(Level.SEVERE,null,ex);
System.out.println(“\n\n错误:+ex.getMessage());
System.out.print(码字+“”+priorcode+“”+decodic.get(133)+“”+dlastcode);
}
}
公共静态void main(字符串参数[]){
LZW LZW=新的LZW();
lzw.compressFile();
lzw.decompressFile();
}
}

您的字典的大小是32767项。(简短)
您不限制它的大小,也不检查它。它适用于小文件。较大文件的数据丢失。

此代码是否已在运行,而您只寻求改进?然后,您可能会更好地询问代码中是否存在任何(已知)问题,您应该说明这些问题,以便我们了解您的问题是什么。这看起来确实非常适合代码审查,如果代码按预期工作,听起来是这样的。当我测试时,代码工作良好。我没有发现任何问题。我最大的怀疑是我在创建压缩字典时使用了short。这意味着一些使用Unicode代码大于32767的非拉丁字母表的语言无法通过这种方法处理。我还没有测试它。
在测试时运行良好
您是如何测试的?建议:1)压缩2)重命名输入文件3)尝试使用新实例(如果不是进程)解压缩。预期结果:浩劫-您的解压似乎需要纯文本来设置
decompdic