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<String, Exception> addFile(String fileName) throws IOException {
buildParentPath();
File file = new File(fileName);
parentFilePath = file.getParentFile().getAbsolutePath();
buildOutputStream();
return addFileByFullPath(fileName);
}
private Map<String, Exception> addFileByFullPath(String fileName)
throws IOException {
Map<String, Exception> errorInfo = new HashMap<String, Exception>();
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<String, Exception> 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(“路徑”);即可