forked from KNEMC/KLALB
189 lines
4.8 KiB
Java
189 lines
4.8 KiB
Java
package org.kne.io;
|
|
|
|
import java.io.ByteArrayInputStream;
|
|
import java.io.ByteArrayOutputStream;
|
|
import java.io.DataInputStream;
|
|
import java.io.DataOutputStream;
|
|
import java.io.EOFException;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.OutputStream;
|
|
import java.util.ArrayList;
|
|
import java.util.concurrent.Executors;
|
|
import java.util.concurrent.ThreadFactory;
|
|
import java.util.concurrent.ThreadPoolExecutor;
|
|
import java.util.zip.DataFormatException;
|
|
import java.util.zip.Deflater;
|
|
import java.util.zip.Inflater;
|
|
import org.kne.debug.TimeDebugger;
|
|
|
|
public class Compress {
|
|
static int n=0;
|
|
public static ThreadPoolExecutor exf=(ThreadPoolExecutor) Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*2, new ThreadFactory() {
|
|
|
|
@Override
|
|
public Thread newThread(Runnable r) {
|
|
Thread t=new Thread(r,"Compress #"+(n++));
|
|
t.setDaemon(true);
|
|
return t;
|
|
}
|
|
});
|
|
|
|
|
|
|
|
public static Data compress(Data b) {
|
|
|
|
Deflater def=new Deflater(Deflater.BEST_COMPRESSION, true);
|
|
def.setInput(b.b,b.off,b.len);
|
|
def.finish();
|
|
byte[]bo=new byte[(int) (b.len*1.1)+64];
|
|
int vp=def.deflate(bo,4,bo.length-4);
|
|
|
|
def.end();
|
|
int v=b.len;
|
|
bo[0]=(byte) ((v >>> 24) & 0xFF);
|
|
bo[1]=(byte) ((v >>> 16) & 0xFF);
|
|
bo[2]=(byte) ((v >>> 8) & 0xFF);
|
|
bo[3]=(byte) ((v >>> 0) & 0xFF);
|
|
return new Data(bo,0,vp+4);
|
|
}
|
|
public static Data uncompress(Data b) throws IOException, DataFormatException {
|
|
if(b.len<4){
|
|
throw new EOFException("!!");
|
|
}
|
|
int ch1 =b.b[b.off+0]&0xff;
|
|
int ch2 = b.b[b.off+1]&0xff;
|
|
int ch3 =b. b[b.off+2]&0xff;
|
|
int ch4 =b.b[b.off+3]&0xff;
|
|
|
|
int zix= ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
|
|
|
|
Inflater inf=new Inflater(true);
|
|
inf.setInput(b.b, b.off+4, b.len-4);
|
|
byte[]d=new byte[zix];
|
|
int l=inf.inflate(d);
|
|
inf.end();
|
|
|
|
return new Data(d,0,l);
|
|
}
|
|
private static class compresstask extends Task{
|
|
volatile Data input,output;
|
|
|
|
public compresstask(Data input) {
|
|
super();
|
|
this.input = input;
|
|
}
|
|
|
|
public Data getOutput() {
|
|
return output;
|
|
}
|
|
|
|
@Override
|
|
protected void runTask() {
|
|
output=compress(input);
|
|
}
|
|
|
|
}
|
|
public static void mulcomp(DataOutputStream dos,byte[]in, TimeDebugger dbg) throws IOException {
|
|
ArrayList<Task> l=new ArrayList();
|
|
int count =4;
|
|
int sze=in.length/count;
|
|
int y=in.length%count;
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
Task t=new compresstask(new Data(in,i*sze,sze));
|
|
exf.execute(t);
|
|
l.add(t);
|
|
}
|
|
Data tmp=null;
|
|
if(y>0) {
|
|
tmp=compress(new Data(in,count*sze,y));
|
|
}
|
|
dbg.putTime("compress");
|
|
dos.writeInt(l.size()+(tmp==null?0:1));
|
|
for (int i = 0; i < l.size(); i++) {
|
|
compresstask n=(compresstask) l.get(i);
|
|
n.waitfortask();
|
|
Data g=n.getOutput();
|
|
dos.writeInt(g.len);
|
|
dos.write(g.b, g.off, g.len);
|
|
|
|
}
|
|
|
|
|
|
if(tmp!=null) {
|
|
dos.writeInt(tmp.len);
|
|
dos.write(tmp.b, tmp.off, tmp.len);
|
|
}
|
|
}
|
|
private static class uncompresstask extends Task{
|
|
volatile Data input,output;
|
|
|
|
public uncompresstask(Data input) {
|
|
super();
|
|
this.input = input;
|
|
}
|
|
|
|
public Data getOutput() {
|
|
return output;
|
|
}
|
|
|
|
@Override
|
|
protected void runTask() {
|
|
try {
|
|
output=uncompress(input);
|
|
} catch (IOException e) {
|
|
// TODO �Զ����ɵ� catch ��
|
|
e.printStackTrace();
|
|
} catch (DataFormatException e) {
|
|
// TODO �Զ����ɵ� catch ��
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
}
|
|
public static byte[] muluncomp(DataInputStream dis,TimeDebugger dbg) throws IOException, DataFormatException {
|
|
ArrayList<Task> l=new ArrayList();
|
|
ByteArrayOutputStream bod=new ByteArrayOutputStream(1024);
|
|
int bc=dis.readInt();
|
|
for(int x=0;x<bc;x++) {
|
|
int s=dis.readInt();
|
|
byte []input=new byte[s];
|
|
int offset = 0;
|
|
int numRead = 0;
|
|
while (offset < input.length
|
|
&& (numRead = dis.read(input, offset, input.length - offset)) >= 0) {
|
|
offset += numRead;
|
|
}
|
|
Task tsk=new uncompresstask(new Data(input,0,input.length));
|
|
exf.execute(tsk);
|
|
l.add(tsk);
|
|
|
|
//Data rez=uncompress(new Data(input,0,input.length));
|
|
|
|
} dbg.putTime("read");
|
|
for (int i = 0; i < l.size(); i++) {
|
|
uncompresstask uct=(uncompresstask) l.get(i);
|
|
uct.waitfortask();
|
|
Data rez=uct.getOutput();
|
|
bod.write(rez.b,rez.off,rez.len);
|
|
}
|
|
|
|
|
|
//rez.b.length=rez.off;
|
|
return bod.toByteArray();
|
|
}
|
|
public static void main(String[] args) throws IOException, DataFormatException {
|
|
String s="jjjjjjjjjjjjjjjjjjhjhjhm";
|
|
byte[] ib=s.getBytes();
|
|
Data i=new Data(ib,0,ib.length);
|
|
Data o=compress(i);
|
|
Data d=uncompress(o);
|
|
System.out.println(o.len+" "+d.len);
|
|
//for (int j = d.off; j < d.off+d.len; j++) {
|
|
System.out.println(new String(d.b,d.off,d.len));
|
|
//}
|
|
}
|
|
|
|
}
|