Linux上常用的压缩包格式是.tar.gz。.tar.gz文件的创建过程有两步。首先把文件打包到tar文件中,然后用gzip压缩tar文件。这里分享下如何在Windows上创建,解压,更新.tar.gz压缩包。
Linux命令
如果在Windows上安装了Linux子系统,可以用Linux命令。
创建.tar.gz
tar -czvf dwt.tar.gz dwt/
解压.tar.gz
tar -xzvf dwt.tar.gz -C tmp/
7zip命令
创建
7z a -ttar -so dwt.tar dwt/ | 7z a -si dwt.tar.gz
解压
7z x dwt.tar.gz -so | 7z x -si -ttar
更新比较复杂
7z x dwt.tar.gz && 7z u dwt.tar dwt && del dwt.tar.gz && 7z a dwt.tar.gz dwt.tar && del dwt.tar
使用C#代码创建,解压,更新.tar.gz
下载SharpZipLib。
创建
private void CreateTarGZ(string tgzFilename, string sourceDirectory)
{
Stream outStream = File.Create(tgzFilename);
Stream gzoStream = new GZipOutputStream(outStream);
TarArchive tarArchive = TarArchive.CreateOutputTarArchive(gzoStream);
// Note that the RootPath is currently case sensitive and must be forward slashes e.g. "c:/temp"
// and must not end with a slash, otherwise cuts off first char of filename
// This is scheduled for fix in next release
tarArchive.RootPath = sourceDirectory.Replace('\\', '/');
if (tarArchive.RootPath.EndsWith("/"))
tarArchive.RootPath = tarArchive.RootPath.Remove(tarArchive.RootPath.Length - 1);
AddDirectoryFilesToTar(tarArchive, sourceDirectory, true, true);
tarArchive.Close();
}
private void AddDirectoryFilesToTar(TarArchive tarArchive, string sourceDirectory, bool recurse, bool isRoot)
{
// Optionally, write an entry for the directory itself.
// Specify false for recursion here if we will add the directory's files individually.
//
TarEntry tarEntry;
if (!isRoot)
{
tarEntry = TarEntry.CreateEntryFromFile(sourceDirectory);
tarArchive.WriteEntry(tarEntry, false);
}
// Write each file to the tar.
//
string[] filenames = Directory.GetFiles(sourceDirectory);
foreach (string filename in filenames)
{
tarEntry = TarEntry.CreateEntryFromFile(filename);
Console.WriteLine(tarEntry.Name);
tarArchive.WriteEntry(tarEntry, true);
}
if (recurse)
{
string[] directories = Directory.GetDirectories(sourceDirectory);
foreach (string directory in directories)
AddDirectoryFilesToTar(tarArchive, directory, recurse, false);
}
}
解压
public void ExtractTGZ(String gzArchiveName, String destFolder)
{
Stream inStream = File.OpenRead(gzArchiveName);
Stream gzipStream = new GZipInputStream(inStream);
TarArchive tarArchive = TarArchive.CreateInputTarArchive(gzipStream);
tarArchive.ExtractContents(destFolder);
tarArchive.Close();
gzipStream.Close();
inStream.Close();
}
更新
.tar.gz解压成.tar
public string ExtractGZipFile(string gzipFileName, string targetDir)
{
// Use a 4K buffer. Any larger is a waste.
byte[] dataBuffer = new byte[4096];
using (System.IO.Stream fs = new FileStream(gzipFileName, FileMode.Open, FileAccess.Read))
{
using (GZipInputStream gzipStream = new GZipInputStream(fs))
{
// Change this to your needs
string fnOut = Path.Combine(targetDir, Path.GetFileNameWithoutExtension(gzipFileName));
using (FileStream fsOut = File.Create(fnOut))
{
StreamUtils.Copy(gzipStream, fsOut, dataBuffer);
}
return fnOut;
}
}
}
更新.tar
public void UpdateTar(string tarFileName, string targetFile, bool asciiTranslate)
{
using (FileStream fsIn = new FileStream(tarFileName, FileMode.Open, FileAccess.Read))
{
string tmpTar = Path.Combine(Path.GetDirectoryName(tarFileName), "tmp.tar");
using (FileStream fsOut = new FileStream(tmpTar, FileMode.OpenOrCreate, FileAccess.Write))
{
TarOutputStream tarOutputStream = new TarOutputStream(fsOut);
TarInputStream tarIn = new TarInputStream(fsIn);
TarEntry tarEntry;
while ((tarEntry = tarIn.GetNextEntry()) != null)
{
if (tarEntry.IsDirectory)
{
continue;
}
// Converts the unix forward slashes in the filenames to windows backslashes
//
string name = tarEntry.Name.Replace('/', Path.DirectorySeparatorChar);
string sourceFileName = Path.GetFileName(targetFile);
string targetFileName = Path.GetFileName(tarEntry.Name);
if (sourceFileName.Equals(targetFileName))
{
using (Stream inputStream = File.OpenRead(targetFile))
{
long fileSize = inputStream.Length;
TarEntry entry = TarEntry.CreateTarEntry(tarEntry.Name);
// Must set size, otherwise TarOutputStream will fail when output exceeds.
entry.Size = fileSize;
// Add the entry to the tar stream, before writing the data.
tarOutputStream.PutNextEntry(entry);
// this is copied from TarArchive.WriteEntryCore
byte[] localBuffer = new byte[32 * 1024];
while (true)
{
int numRead = inputStream.Read(localBuffer, 0, localBuffer.Length);
if (numRead <= 0)
{
break;
}
tarOutputStream.Write(localBuffer, 0, numRead);
}
}
tarOutputStream.CloseEntry();
}
else
{
tarOutputStream.PutNextEntry(tarEntry);
if (asciiTranslate)
{
CopyWithAsciiTranslate(tarIn, tarOutputStream);
}
else
{
tarIn.CopyEntryContents(tarOutputStream);
}
tarOutputStream.CloseEntry();
}
}
tarIn.Close();
tarOutputStream.Close();
}
File.Delete(tarFileName);
File.Move(tmpTar, tarFileName);
}
}
更新.tar.gz
private void UpdateTarGZ(string tgzFilename, string tarFileName)
{
Stream gzoStream = new GZipOutputStream(File.Create(tgzFilename));
using (FileStream source = File.Open(tarFileName,
FileMode.Open))
{
byte[] localBuffer = new byte[32 * 1024];
while (true)
{
int numRead = source.Read(localBuffer, 0, localBuffer.Length);
if (numRead <= 0)
{
break;
}
gzoStream.Write(localBuffer, 0, numRead);
}
}
gzoStream.Close();
File.Delete(tarFileName);
}
编译
dotnet publish -c Release -r win10-x64
运行