最近闲暇时间开始写点通用基础类在写到tar类型文件压缩与解压时遇到点问题

压缩用的类库我是下载的 SharpZipLib_0860版本

先上代码

加压核心

		/// <summary>
/// 内部文件及文件夹压缩方法
/// </summary>
/// <param name="paths">被压缩的文件及文件夹路径</param>
/// <param name="outputStream">tar压缩文件流</param>
/// <param name="basePath">压缩文件流基于的根路径</param>
private void AddCompressFileAndFolders(string[] paths, TarOutputStream outputStream, string basePath, int compression)
{
try
{
foreach (string path in paths)
{
TarEntry entry = null;
if (FolderProvider.IsFolder(path))
{
if (string.IsNullOrEmpty(basePath))
basePath = FolderProvider.GetSuperFolderPath(path); //is directory
string[] subFileAndFolders = FolderProvider.GetAllContainsFileAndFolderPaths(path);
TarHeader header = new TarHeader();
header.Name = path.Replace(basePath + "\\", string.Empty) + "\\";
header.Mode = compression;
entry = new TarEntry(header);
if (subFileAndFolders.Length == 0)
{
outputStream.PutNextEntry(entry);
outputStream.CloseEntry();
}
/*当前路径为子路径的父路径*/
AddCompressFileAndFolders(subFileAndFolders, outputStream, basePath, compression);
}
else
{
//is file
using (FileStream file = System.IO.File.OpenRead(path))
{
string filePath = path;
if (!string.IsNullOrEmpty(basePath))
{
filePath = path.Replace(basePath + "\\", string.Empty);
}
else
{
filePath = Path.GetFileName(path);
} byte[] buffer = new byte[1024 * 1024 * 4];
int size = 1;
TarHeader header = new TarHeader();
header.Name = filePath;
header.ModTime = DateTime.Now;
header.Size = file.Length;
entry = new TarEntry(header);
outputStream.PutNextEntry(entry); while (size > 0)
{
size = file.Read(buffer, 0, buffer.Length);
if (size == 0)
break;
outputStream.Write(buffer, 0, size);
}
outputStream.CloseEntry();
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}

解压核心

		/// <summary>
/// 功能:解压tar格式的文件。
/// </summary>
/// <param name="zipFilePath">压缩文件路径</param>
/// <param name="unZipDir">解压文件存放路径,为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹</param>
/// <param name="password">密码</param>
/// <returns>解压是否成功</returns>
public bool UnCompressFile(string zipFilePath, string unZipDir = null, string password = null)
{
if (zipFilePath == string.Empty)
{
throw new Exception("压缩文件不能为空!");
}
if (!System.IO.File.Exists(zipFilePath))
{
throw new Exception("压缩文件不存在!");
}
//解压文件夹为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹
if (string.IsNullOrEmpty(unZipDir))
unZipDir = zipFilePath.Replace(Path.GetFileName(zipFilePath), Path.GetFileNameWithoutExtension(zipFilePath));
if (!unZipDir.EndsWith("\\"))
unZipDir += "\\";
if (!Directory.Exists(unZipDir))
FolderProvider.CreateDirectory(unZipDir); try
{
using (TarInputStream input = new TarInputStream(System.IO.File.OpenRead(zipFilePath)))
{
//if (!string.IsNullOrEmpty(password)) input.Password = password; TarEntry theEntry;
while ((theEntry = input.GetNextEntry()) != null)
{
string directoryName = Path.GetDirectoryName(theEntry.Name);
//string fileName = Path.GetFileName(Encoding.UTF8.GetString(theEntry.Name));
string fileName = Path.GetFileName(theEntry.Name);
if (directoryName.Length > 0)
{
Directory.CreateDirectory(unZipDir + directoryName);
}
if (!directoryName.EndsWith("\\"))
directoryName += "\\";
if (fileName != String.Empty)
{
// Because the uncompressed size of the file is unknown,
// we are using an arbitrary buffer size.
byte[] buffer = new byte[1024 * 1024 * 4];
int size = buffer.Length; using (FileStream streamWriter = System.IO.File.Create(unZipDir + theEntry.Name))
{
while (size > 0)
{
size = input.Read(buffer, 0, buffer.Length);
if (size == 0) break;
streamWriter.Write(buffer, 0, size);
}
}
}
}//while
}
}
catch (Exception ex)
{
throw ex;
}
return true;
}//解压结束

遇到的问题是

1,中文乱码,

2 压缩文件中的空文件夹下多了个不知道是没有没名称的文件夹还是没有名称及后缀名的文件但是用解压方法解压或是解压工具解压后确实是空文件夹

中文乱码的解决:

根据问题应该是在字符与byte转换时没有指点Encoding造成的, 下载SharpZipLib_0860_SourceSamples.zip,源码查看

先调整加压函数,修个TarHeader文件里的下面的函数,下面是修正后的

		/// <summary>
/// Add <paramref name="name">name</paramref> to the buffer as a collection of bytes
/// </summary>
/// <param name="name">The name to add</param>
/// <param name="nameOffset">The offset of the first character</param>
/// <param name="buffer">The buffer to add to</param>
/// <param name="bufferOffset">The index of the first byte to add</param>
/// <param name="length">The number of characters/bytes to add</param>
/// <returns>The next free index in the <paramref name="buffer"/></returns>
public static int GetNameBytes(string name, int nameOffset, byte[] buffer, int bufferOffset, int length)
{
if (name == null)
{
throw new ArgumentNullException("name");
} if (buffer == null)
{
throw new ArgumentNullException("buffer");
} int i; ///解决tar压缩中文乱码问题
byte[] arrName = Encoding.GetEncoding(Thread.CurrentThread.CurrentCulture.TextInfo.OEMCodePage).GetBytes(name);
for (i = 0; i < length - 1 && nameOffset + i < arrName.Length; ++i)
{
buffer[bufferOffset + i] = (byte)arrName[nameOffset + i];
} for (; i < length; ++i)
{
buffer[bufferOffset + i] = 0;
} return bufferOffset + length;
}

编译后调用,运行单元测试,压缩文件中中文显示正常,运行解压测试,解压后依旧乱码,

继续调整TarHeader文件中的函数,调整后如下:

		/// <summary>
/// Parse a name from a header buffer.
/// </summary>
/// <param name="header">
/// The header buffer from which to parse.
/// </param>
/// <param name="offset">
/// The offset into the buffer from which to parse.
/// </param>
/// <param name="length">
/// The number of header bytes to parse.
/// </param>
/// <returns>
/// The name parsed.
/// </returns>
static public StringBuilder ParseName(byte[] header, int offset, int length)
{
if (header == null)
{
throw new ArgumentNullException("header");
} if (offset < 0)
{
#if NETCF_1_0
throw new ArgumentOutOfRangeException("offset");
#else
throw new ArgumentOutOfRangeException("offset", "Cannot be less than zero");
#endif
} if (length < 0)
{
#if NETCF_1_0
throw new ArgumentOutOfRangeException("length");
#else
throw new ArgumentOutOfRangeException("length", "Cannot be less than zero");
#endif
} if (offset + length > header.Length)
{
throw new ArgumentException("Exceeds header size", "length");
} StringBuilder result = new StringBuilder(length);
List<byte> temp = new List<byte>();
for (int i = offset; i < offset + length; ++i)
{
if (header[i] == 0)
{
break;
}
//result.Append((char)header[i]);
temp.Add(header[i]);
} result.Append(Encoding.GetEncoding(Thread.CurrentThread.CurrentCulture.TextInfo.OEMCodePage).GetString(temp.ToArray())); return result;
}

之前说的第二个问题还没解决,希望有哪位大侠解决了告诉我一下,多谢

CSharp tar类型文件压缩与解压的更多相关文章

  1. Linux之文件压缩与解压

    文件压缩与解压 1.tar命令 tar命令可以为Linux的文件和目录创建档案. 利用tar,可以为某一特定文件创建档案(备份文件),也可以在档案中改变文件,或者向档案中加入新的文件.tar最初被用来 ...

  2. I/O操作之文件压缩与解压

    与文件压缩与解压相关的类在java.util.zip包下 实例 //文件压缩 import java.io.File; import java.io.FileInputStream; import j ...

  3. python tar.gz格式压缩、解压

    一.压缩 需求描述 现在有一个目录,需要将此目录打包成tar.gz文件.因为有一个Django项目,需要用到此功能! tar.gz 目录结构如下: ./ ├── folder │   ├── .doc ...

  4. 文件压缩、解压工具类。文件压缩格式为zip

    package com.JUtils.file; import java.io.BufferedOutputStream; import java.io.File; import java.io.Fi ...

  5. 文件压缩跟解压(本地&Linux服务器)

    远程解压需要的jar包: <dependency> <groupId>commons-net</groupId> <artifactId>commons ...

  6. Java实现文件压缩与解压

    Java实现ZIP的解压与压缩功能基本都是使用了Java的多肽和递归技术,可以对单个文件和任意级联文件夹进行压缩和解压,对于一些初学者来说是个很不错的实例.(转载自http://www.puiedu. ...

  7. Java实现文件压缩与解压[zip格式,gzip格式]

    Java实现ZIP的解压与压缩功能基本都是使用了Java的多肽和递归技术,可以对单个文件和任意级联文件夹进行压缩和解压,对于一些初学者来说是个很不错的实例. zip扮演着归档和压缩两个角色:gzip并 ...

  8. Linux 文件压缩与解压相关

    tar [-cxtzjvfpPN] 文件与目录 .... 参数:-c :建立一个压缩文件的参数指令-x :解开一个压缩文件的参数指令 -t :查看压缩文件里面的文件 特别注意: c/x/t 同时只能存 ...

  9. Linux中文件压缩与解压

    压缩与解压 compress 文件名 1 -v //详细信息 2 3 -d //等于 uncompress 默认只识别 .Z 如果使用别的后缀,会导致不识别,解压缩失败.也可以使用 -d -c 压缩包 ...

随机推荐

  1. baidu-fex 精彩文章

    7 天打造前端性能监控系统 http://fex.baidu.com/blog/2014/05/build-performance-monitor-in-7-days/ 前端自动化测试探索 http: ...

  2. VIM设置-发现VIM的美

    今天在Linux上调代码,突然发现连高亮都没有.到网上找了找,发现一个大神的微博里有. 在此记录:http://www.cnblogs.com/ma6174/archive/2011/12/10/22 ...

  3. CSS 3 属性学习大纲

    1. Gradient 渐变 2. RGBA 颜色透明 3. Border-radius 圆角 4. text-shadow 文字阴影 5. box-shadow 图层阴影 6. Transform ...

  4. 【Chromium中文文档】OS X 沙箱设计

    OS X 沙箱设计 转载请注明出处:https://ahangchen.gitbooks.io/chromium_doc_zh/content/zh//General_Architecture/OSX ...

  5. [ReactiveCocoa]最简单的RAC入门操作

    当knowckout.js出来的时候,确实被其kobinding惊艳了一下,等到AngularJS出来的时候,把MVVM的模式更是向前推进了一步.所以当ReactiveCocoa出来的时候,也很感兴趣 ...

  6. js自定义类和对象及继承

    1.工厂方式 <script type="text/javascript"> function createObject(name){ var p = new Obje ...

  7. 倒计时 NAN 问题

    http://blog.csdn.net/lishangua/article/details/51506821

  8. ORACLE RAC中一个实例不能随crs自动启动的解决

    现象:在两个节点上做CRS的重启,这个实例都不能随CRS的启动而启动.CRS启动后做crs_start -all可以把没启动的资源起来,而且无报错. 分析:去crsd.log中找原因,发现CRS根本就 ...

  9. SELinux开关导致mysql服务启动不了

    http://www.jb51.net/article/36187.htm 网站突然连接不上数据库,于是朋友直接重启了一下服务器.进到cli模式下,执行 service myqsld start 发现 ...

  10. 前端js模板库 JinkoTemplate

    有时候需要使用ajax来异步生成html,最土的方法就是用js的‘+’连接html代码,生成繁琐.一旦需要修改,对于少量的html代码到没啥问题,要是比较复杂的样式时,就真坑爹了,眼花缭乱有木有?Ji ...