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

猜你喜欢

转载自blog.csdn.net/qq_28825857/article/details/86525313