1 package com.archiver;
2
3 import java.io.FileInputStream;
4 import java.io.FileOutputStream;
5 import java.io.IOException;
6 import java.util.ArrayList;
7 import java.util.List;
8
9 public class Archiver {
10
11 /**
12 * 把多个文件归档到一个文件中
13 */
14 public void archive(String archFile, String... srcFiles) {
15 for (String srcFile : srcFiles) {
16 appendFile(archFile, srcFile);
17 }
18 }
19
20 /**
21 * 向归档文件中追加内容
22 *
23 * @param archFile
24 * @param srcFile
25 */
26 public void appendFile(String archFile, String srcFile) {
27 FileOutputStream fos=null;
28 FileInputStream fis=null;
29 try {
30 fos = new FileOutputStream(archFile, true);
31 // 1.处理文件名
32 String fileName = getName(srcFile);
33 // 1.1 存储文件名长度
34 byte[] byt = Int2Byte(fileName.length());
35 fos.write(byt);
36 // 1.2 文件字节数组
37 fos.write(fileName.getBytes());
38 // 2、处理文件内容
39 fis = new FileInputStream(srcFile);
40 int count=fis.available();//文件内容长度
41 //存储文件内容长度
42 fos.write(Int2Byte(count));
43 byte[] buff = new byte[1024];
44 int len = 0;
45 while ((len = fis.read(buff)) != -1) {
46 fos.write(buff, 0, len);
47 }
48 } catch (Exception e) {
49 // TODO Auto-generated catch block
50 e.printStackTrace();
51 } finally {
52 try {
53 fis.close();
54 fos.close();
55 } catch (IOException e) {
56 // TODO Auto-generated catch block
57 e.printStackTrace();
58 }
59 }
60
61 }
62 /**
63 * 解归档
64 * @param length
65 * @return
66 */
67 public void unArchiver(String archFile,String destDir){
68 //FileInputStream fis=null;
69 //FileOutputStream fos=null;
70 try {
71 FileInputStream fis=new FileInputStream(archFile);
72 //读取文件名长度
73 byte[] fnameLenBuff=new byte[4];
74 while((fis.read(fnameLenBuff))!=-1){
75
76 int fnameLength=Byte2Int(fnameLenBuff);
77 //读取文件名
78 byte[] fnameBuf=new byte[fnameLength];
79 fis.read(fnameBuf);
80 String fname=new String(fnameBuf);
81 //读取文件内容长度
82 byte[] fcontBuf=new byte[4];
83 fis.read(fcontBuf);
84 int flen=Byte2Int(fcontBuf);
85 //将归档内容写到指定目录处
86 FileOutputStream fos=new FileOutputStream(destDir+"\"+fname);
87 byte[] buf=new byte[1024];
88 int mod=flen % buf.length;
89 int count=0;
90
91 if(mod==0){
92 count=flen/buf.length;
93 }
94 else{
95 count=flen/buf.length+1;
96 }
97 for(int i=0;i<count;i++){
98 //最后一次
99 if(i==(count-1)){
100 mod=(mod==0?buf.length:mod);
101 fis.read(buf, 0, mod);
102 fos.write(buf, 0, mod);
103 fos.close();
104 }
105 else{
106 fis.read(buf);
107 fos.write(buf);
108 }
109 }
110 }
111 fis.close();
112 } catch (Exception e) {
113 e.printStackTrace();
114 // TODO: handle exception
115 }
116 }
117 /**
118 * 提取归档文件的所有文件名
119 * @param length
120 * @return
121 */
122 public List<String> getAllFileName(String archFile){
123 //FileInputStream fis=null;
124 //FileOutputStream fos=null;
125 ArrayList<String> names = new ArrayList<>();
126 try {
127 FileInputStream fis=new FileInputStream(archFile);
128 //读取文件名长度
129 byte[] fnameLenBuff=new byte[4];
130 while((fis.read(fnameLenBuff))!=-1){
131
132 int fnameLength=Byte2Int(fnameLenBuff);
133 //读取文件名
134 byte[] fnameBuf=new byte[fnameLength];
135 fis.read(fnameBuf);
136 String fname=new String(fnameBuf);
137 names.add(fname);
138 //读取文件内容长度
139 byte[] fcontBuf=new byte[4];
140 fis.read(fcontBuf);
141 int flen=Byte2Int(fcontBuf);
142 //跳过文件内容
143 fis.skip(flen);
144 }
145 fis.close();
146 } catch (Exception e) {
147 e.printStackTrace();
148 // TODO: handle exception
149 }
150 return names;
151 }
152 //整数转为字节数组
153 private byte[] Int2Byte(int length) {
154 byte[] a=new byte[4];
155 a[0]=(byte) (length>>24);
156 a[1]=(byte) (length>>16);
157 a[2]=(byte) (length>>8);
158 a[3]=(byte) (length>>0);
159 return a;
160 }
161 //字节数组转为整数
162 private int Byte2Int(byte[] by) {
163 int a1=by[0]<<24;
164 int a2=(by[1]&0xff)<<16;
165 int a3=(by[2]&0xff)<<8;
166 int a4=(by[3]&0xff)<<0;
167
168 return a1|a2|a3|a4;
169 }
170 /**
171 * 获取文件名称
172 *
173 * @param srcFile
174 * @return
175 */
176 private String getName(String srcFilePath) {
177 String seg = null;
178 if(srcFilePath.contains("\")){
179 seg="\";
180 }
181 else if(srcFilePath.contains("/")){
182 seg="/";
183 }
184 return srcFilePath.substring(srcFilePath.lastIndexOf(seg)+1);
185 }
186 }
package com.archiver;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Archiver {
/**
* 把多个文件归档到一个文件中
*/
public void archive(String archFile, String... srcFiles) {
for (String srcFile : srcFiles) {
appendFile(archFile, srcFile);
}
}
/**
* 向归档文件中追加内容
*
* @param archFile
* @param srcFile
*/
public void appendFile(String archFile, String srcFile) {
FileOutputStream fos=null;
FileInputStream fis=null;
try {
fos = new FileOutputStream(archFile, true);
// 1.处理文件名
String fileName = getName(srcFile);
// 1.1 存储文件名长度
byte[] byt = Int2Byte(fileName.length());
fos.write(byt);
// 1.2 文件字节数组
fos.write(fileName.getBytes());
// 2、处理文件内容
fis = new FileInputStream(srcFile);
int count=fis.available();//文件内容长度
//存储文件内容长度
fos.write(Int2Byte(count));
byte[] buff = new byte[1024];
int len = 0;
while ((len = fis.read(buff)) != -1) {
fos.write(buff, 0, len);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
fis.close();
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 解归档
* @param length
* @return
*/
public void unArchiver(String archFile,String destDir){
//FileInputStream fis=null;
//FileOutputStream fos=null;
try {
FileInputStream fis=new FileInputStream(archFile);
//读取文件名长度
byte[] fnameLenBuff=new byte[4];
while((fis.read(fnameLenBuff))!=-1){
int fnameLength=Byte2Int(fnameLenBuff);
//读取文件名
byte[] fnameBuf=new byte[fnameLength];
fis.read(fnameBuf);
String fname=new String(fnameBuf);
//读取文件内容长度
byte[] fcontBuf=new byte[4];
fis.read(fcontBuf);
int flen=Byte2Int(fcontBuf);
//将归档内容写到指定目录处
FileOutputStream fos=new FileOutputStream(destDir+"\"+fname);
byte[] buf=new byte[1024];
int mod=flen % buf.length;
int count=0;
if(mod==0){
count=flen/buf.length;
}
else{
count=flen/buf.length+1;
}
for(int i=0;i<count;i++){
//最后一次
if(i==(count-1)){
mod=(mod==0?buf.length:mod);
fis.read(buf, 0, mod);
fos.write(buf, 0, mod);
fos.close();
}
else{
fis.read(buf);
fos.write(buf);
}
}
}
fis.close();
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}
}
/**
* 提取归档文件的所有文件名
* @param length
* @return
*/
public List<String> getAllFileName(String archFile){
//FileInputStream fis=null;
//FileOutputStream fos=null;
ArrayList<String> names = new ArrayList<>();
try {
FileInputStream fis=new FileInputStream(archFile);
//读取文件名长度
byte[] fnameLenBuff=new byte[4];
while((fis.read(fnameLenBuff))!=-1){
int fnameLength=Byte2Int(fnameLenBuff);
//读取文件名
byte[] fnameBuf=new byte[fnameLength];
fis.read(fnameBuf);
String fname=new String(fnameBuf);
names.add(fname);
//读取文件内容长度
byte[] fcontBuf=new byte[4];
fis.read(fcontBuf);
int flen=Byte2Int(fcontBuf);
//跳过文件内容
fis.skip(flen);
}
fis.close();
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}
return names;
}
//整数转为字节数组
private byte[] Int2Byte(int length) {
byte[] a=new byte[4];
a[0]=(byte) (length>>24);
a[1]=(byte) (length>>16);
a[2]=(byte) (length>>8);
a[3]=(byte) (length>>0);
return a;
}
//字节数组转为整数
private int Byte2Int(byte[] by) {
int a1=by[0]<<24;
int a2=(by[1]&0xff)<<16;
int a3=(by[2]&0xff)<<8;
int a4=(by[3]&0xff)<<0;
return a1|a2|a3|a4;
}
/**
* 获取文件名称
*
* @param srcFile
* @return
*/
private String getName(String srcFilePath) {
String seg = null;
if(srcFilePath.contains("\")){
seg="\";
}
else if(srcFilePath.contains("/")){
seg="/";
}
return srcFilePath.substring(srcFilePath.lastIndexOf(seg)+1);
}
}