java代碼實現多文件tar包壓縮且壓縮文件能放到linux服務器上正常解壓

 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(“路徑”);即可

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章