java代码实现tar包压缩文件的代码在网上能找到很多,但是要不就是压缩之后的文件会有空文件夹在压缩包中,要不就是压缩之后的文件在Linux服务器上解压出现问题,产生这个问题的主要原因是文件的目录分隔符没有设置正确,如果我们想让压缩之后的文件能在Linux服务器上正常解压,该怎么做呢?
首先我们要用File.separator代替“/”;(Windows和Linux目录分隔符的表示方法一个是“/”,一个是“\”)
比如:d://test.tar替换为”d:”+ File.separator +”test.tar” d:/test.tar 替换为”d:”+ File.separator +”test.tar”
如果不加,跨平台解压,到Linux服务器解压可能会解压出来的是一个路径;
其次要在代码中加入filePath = filePath.replace(File.separator, “/”);把所有的“\\”替换成“/”
此处不加,可能会导致压缩文件有空的文件夹产生
最后要把outputStream设置成如下格式:
outputStream.setLongFileMode(TarOutputStream.LONGFILE_GNU);(此处有三种设置方法且此处用的是ant-1.7.1.jar包的方法)
如果使用commons-compress-1.9.jar进行压缩,则此处使用的是:
outputStream.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
此处不加的话就会报错,类似:
“java.lang.RuntimeException: file name ‘sss/workspace/java/projects/AIM_AGENT’ is too long ( > 100 bytes)
at org.apache.commons.compress.archivers.tar.TarArchiveOutputStream.handleLongName(TarArchiveOutputStream.java:674)
at org.apache.commons.compress.archivers.tar.TarArchiveOutputStream.putArchiveEntry(TarArchiveOutputStream.java:275)
at tar.TarBuildfile.archiveFile(TarBuildfile.java:171)”
commons-compress-1.9.jar压缩解压包的官网说明如下:http://commons.apache.org/proper/commons-compress/tar.html
以下代码在ant-1.7.1.jar下编译通过,能正常压缩并使用tar解压命令在Linux服务器上正常解压。
package tar;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import org.apache.tools.tar.TarEntry;
import org.apache.tools.tar.TarOutputStream;
public class TarFileBuilder {
private String tarFileName;
private String parentFilePath;
private TarOutputStream outputStream = null;
private boolean isClosed = false;
public TarFileBuilder(String tarFileName) {
this.tarFileName = tarFileName;
}
public Map addFile(String fileName) throws IOException {
buildParentPath();
File file = new File(fileName);
parentFilePath = file.getParentFile().getAbsolutePath();
buildOutputStream();
return addFileByFullPath(fileName);
}
private Map addFileByFullPath(String fileName)
throws IOException {
Map errorInfo = new HashMap();
File file = new File(fileName);
if (file.isDirectory()) {
addDir(file, getEntryFileName(parentFilePath, fileName));
} else {
try {
addFile(file, getEntryFileName(parentFilePath, fileName));
} catch (IOException e) {
e.printStackTrace();
errorInfo.put(fileName, e);
}
}
return errorInfo;
}
public void addDir(File file,String entryFileName) throws IOException {
if(!entryFileName.endsWith(“/”) && !entryFileName.endsWith(“\\”)) {
entryFileName = entryFileName + “/”;
}
TarEntry tarEntry = new TarEntry(entryFileName);
outputStream.putNextEntry(tarEntry);
outputStream.closeEntry();
for (String item : file.list()) {
//addFileByFullPath(file.getAbsolutePath() + File.separator + item);
addFileByFullPath(file.getAbsolutePath() + “/” + item);
}
}
public void addFile(File file, String entryFileName) throws IOException {
buildOutputStream();
InputStream inputStream = null;
try {
inputStream = new FileInputStream(file);
TarEntry tarEntry = new TarEntry(entryFileName);
int length = 0;
byte[] buffer = new byte[4096];
tarEntry.setSize(file.length());
outputStream.putNextEntry(tarEntry);
while ((length = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, length);
outputStream.flush();
}
outputStream.closeEntry();
} finally {
outputStream.closeEntry();
if (inputStream != null) {
inputStream.close();
}
}
}
private void buildParentPath() {
File file = new File(tarFileName).getParentFile();
//System.out.println(file);
if (!file.exists()) {
file.mkdirs();
}
}
private String getEntryFileName(String parentFilePath, String filePath) {
filePath = filePath.substring(parentFilePath.length());
while (filePath.startsWith(File.separator)) {
filePath = filePath.substring(1);
//把所有的“//”转换为“/”
filePath = filePath.replace(File.separator, “/”);
}
return filePath;
}
private void buildOutputStream() throws FileNotFoundException {
if (outputStream == null || isClosed) {
outputStream = new TarOutputStream(
new FileOutputStream(tarFileName));
outputStream.setLongFileMode(TarOutputStream.LONGFILE_TRUNCATE);
isClosed = false;
}
}
public void close() throws IOException {
if (outputStream != null) {
outputStream.close();
}
isClosed = true;
}
public static void main(String[] args) {
TarFileBuilder tarFileBuilder = new TarFileBuilder(“d:”+ File.separator +”test.tar”);
try {
Map map = tarFileBuilder.addFile(“E:”+ File.separator +”sss”);
//System.out.println(map);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
tarFileBuilder.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
此代码想要进行多文件压缩到同一个文件夹中,直接调用tarFileBuilder.addFile(“路径”);即可