FileCompressor.java Source code

Java tutorial

Introduction

Here is the source code for FileCompressor.java

Source

//package util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class FileCompressor {

    private Map<String, Integer> countMap;

    private List<String> topWords;

    private Map<String, Character> map;

    private static final char[] WORDS = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
            'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
            'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };

    public String compress(String context) {

        context = context.toLowerCase();
        preprocess(context);
        StringBuilder mapLine = new StringBuilder();
        for (Entry<String, Character> e : map.entrySet()) {
            String key = e.getKey();
            String value = e.getValue().toString();
            context = context.replace(key, value);
            mapLine.append(key);
            mapLine.append(value);
        }
        mapLine.append(System.getProperty("line.separator"));

        StringBuilder out = new StringBuilder(context);
        out.insert(0, mapLine.toString());

        map = null;

        return out.toString();
    }

    public String decompress(String context) throws IOException {
        // process map line
        BufferedReader reader = new BufferedReader(new StringReader(context));
        String mapLine = reader.readLine();
        mapLineprocess(mapLine);

        // create content without mapline
        StringBuilder out = new StringBuilder();
        String tmp;
        while ((tmp = reader.readLine()) != null) {
            out.append(tmp);
            out.append(System.getProperty("line.separator"));
        }

        context = out.toString();
        for (Entry<String, Character> e : map.entrySet()) {
            String key = e.getKey();
            String value = e.getValue().toString();
            context = context.replace(value, key);
        }

        return context;

    }

    private void mapLineprocess(String mapLine) {
        // create map for character replacement
        if (map == null) {
            map = new HashMap<String, Character>();
        }

        char[] line = mapLine.toCharArray();
        StringBuilder key = new StringBuilder();
        for (int i = 0; i < line.length; i += 3) {
            key.append(line[i]);
            key.append(line[i + 1]);
            map.put(key.toString(), line[i + 2]);
            key.setLength(0);
        }
    }

    private void preprocess(String content) {
        // count and get top used words
        count(content);

        // create map for character replacement
        if (map == null) {
            map = new HashMap<String, Character>();
        }
        for (int i = 0; i < WORDS.length && i < topWords.size(); i++) {
            map.put(topWords.get(i), WORDS[i]);
        }
        topWords = null;
    }

    private boolean isBreakLine(char ch) {
        char[] breakLine = System.getProperty("line.separator").toCharArray();
        for (char c : breakLine) {
            if (c == ch)
                return true;
        }
        return false;
    }

    private void count(String content) {
        if (countMap == null) {
            countMap = new HashMap<String, Integer>();
        }
        char[] chs = content.toCharArray();

        StringBuilder bytestr = new StringBuilder();

        // count
        for (char ch : chs) {
            if (isBreakLine(ch))
                continue;
            bytestr.append(ch);
            if (bytestr.length() == 2) {
                int count = 0;
                if (countMap.containsKey(bytestr.toString())) {
                    count = countMap.get(bytestr.toString());
                }
                countMap.put(bytestr.toString(), ++count);
                bytestr.setLength(0);
            }
        }

        // sort
        List<Entry<String, Integer>> lists = new ArrayList<Entry<String, Integer>>();
        lists.addAll(countMap.entrySet());
        Collections.sort(lists, new Comparator<Entry<String, Integer>>() {

            @Override
            public int compare(Entry<String, Integer> pO1, Entry<String, Integer> pO2) {
                return pO2.getValue().compareTo(pO1.getValue());
            }
        });

        // to top words
        if (topWords == null) {
            topWords = new ArrayList<String>();
        }
        for (int i = 0; i < WORDS.length && i < lists.size(); i++) {
            topWords.add(i, lists.get(i).getKey());
        }

        countMap = null;

    }

    public static void main(String[] args) throws IOException {

        String file = "D:\\XJad.rar.txt";
        BufferedReader reader = new BufferedReader(new FileReader(file));
        BufferedWriter writer = new BufferedWriter(new FileWriter(file + "_out.txt"));
        StringBuilder content = new StringBuilder();
        String tmp;

        while ((tmp = reader.readLine()) != null) {
            content.append(tmp);
            content.append(System.getProperty("line.separator"));
        }

        FileCompressor f = new FileCompressor();
        writer.write(f.compress(content.toString()));

        writer.close();
        reader.close();

        reader = new BufferedReader(new FileReader(file + "_out.txt"));
        StringBuilder content2 = new StringBuilder();

        while ((tmp = reader.readLine()) != null) {
            content2.append(tmp);
            content2.append(System.getProperty("line.separator"));
        }

        String decompressed = f.decompress(content2.toString());
        String c = content.toString();
        System.out.println(decompressed.equals(c));
    }
}