最近闲暇时间开始写点通用基础类在写到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. Java实现文件压缩与解压

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

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

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

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

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

  8. Linux中文件压缩与解压

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

  9. linux下文件压缩与解压操作

    对于刚刚接触Linux的人来说,一定会给Linux下一大堆各式各样的文件名给搞晕.别个不说,单单就压缩文件为例,我们知道在Windows下最常见的压缩文件就只有两种,一是,zip,另一个是.rap.可 ...

随机推荐

  1. UML图中经常用到几种的关系图例

    学习这个东西挺奇怪的,时间一长就容易忘记,或者记不清楚.今天看到一些UML图的关系,发现有些出入了,索性就写下来,以后再忘记的时候过来看看. 在UML的类图中,常见的有以下几种关系: 继承(Gener ...

  2. MPLS

    Multiprotocol Label Switching From Wikipedia, the free encyclopedia "MPLS" redirects here. ...

  3. Android 动态获取ListView的高度

    public static void setListViewHeightBasedOnChildren(ListView listView) { ListAdapter listAdapter = l ...

  4. 帝吧出征FB:这李毅吧的“爆吧”文化是如何形成的

    声明:本文不对爆吧行为及其涉及的事件进行是非判断,只探讨帝吧文化本身,欢迎拍砖.更正和补充. 一.“帝吧FB出征”事件梳理 继上次全网集体骂 “薯片”事件后,昨日(1月20日)晚7点,又发生了一次互联 ...

  5. C++中string 的使用

    string类的构造函数:string(const char *s);    //用c字符串s初始化string(int n,char c);     //用n个字符c初始化此外,string类还支持 ...

  6. 了解常见的开源协议(BSD, GPL, LGPL,MIT)

    一直对各种开源协议比较模糊, 特意在网上搜索了一下资料, 整理总结,以作记录 如果不喜欢长篇大论的话, 看下图就可以了 基本概念了解: 1. Contributors 和 Recipients Con ...

  7. 更换免开发证书账号出现的Your build settings specify a provisioning profile with the UUID&quot;&quot;,however,no such provisioning profile was found

    更换了免费的个人开发者账号后会出现这个错误 解决方法:在Finder中右键打开工程文件(显示包内容),用文本编辑器打开后缀名为.pbxproj的文件,command+f 搜索"PROVISI ...

  8. 信息二战炸弹:中国到美国咨询公司Say no

    疯抢/文 在禁止Windows8操作系统參与政府採购,以及在中国销售的全部外国IT产品和服务都须通过新的安全审查之后,英国<金融时报>今天报料中国已禁止国企使用美国咨询公司服务. 这则消息 ...

  9. Maven编译中的一些坑

    错误1: invalid LOC header 这个错误比较好解决,jar下载不完全,去到相应的Maven包目录,把东西删掉重新编译就行. 错误2: java.lang.TypeNotPresentE ...

  10. 特殊计数序列——Catalan数

    Catalan数 前10项 \(1,1,2,5,14,42,132,429,1430,4862\) (注:从第\(0\)项起) 计算式 \(C_n=\frac{1}{n+1}\dbinom{2n}{n ...