最近闲暇时间开始写点通用基础类在写到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. 获取自动增长IDmysqli函数

    <?php $mysqli=@new mysqli("localhost", "root", "123456", "xsph ...

  2. HTML 语义化

    语义化,让你的网页更好的被搜索引擎理解 要记住学习html标签过程中,主要注意两个方面的学习:标签的用途.标签在浏览器中的默认样式. 标签的用途:我们学习网页制作时,常常会听到一个词,语义化.那么什么 ...

  3. php 数据结构 hash表

    hash表 定义 hash表定义了一种将字符组成的字符串转换为固定长度(一般是更短长度)的数值或索引值的方法,称为散列法,也叫哈希法.由于通过更短的哈希值比用原始值进行数据库搜索更快,这种方法一般用来 ...

  4. List和Tuple类型

    list列表,list是一种有序的集合,可以随时添加和删除其中的元素,L=[]   索引从0开始,第一个元素的索引是0,第二个是1,倒数第一个是-1,倒数第二个是-2,以此类推,使用索引,不要越界   ...

  5. CSS自学笔记(15):CSS3多列布局

    在CSS3中,也新增了一些关于文本布局的几个比较简单的属性.通过这些新增的属性,我们可以对文本进行简单的排版,就想报纸和杂志那样. 新增的部分属性,以及浏览器支持情况: 属性 浏览器支持 column ...

  6. LINQ 联合查询

    List<Attachment> imgList = (from a in ZQSDWEBEntities.Attachment                               ...

  7. logstash 根据type 判断输出

    # 更多ELK资料请访问 http://devops.taobao.com 一.配置前需要注意: 1.Use chmod to modify nginx log file privilege. E.g ...

  8. zip命令

    常用示例: (1)zip -r myfile.zip ./*    ----将当前目录下的所有文件和文件夹全部压缩成myfile.zip文件, -r表示递归压缩子目录下所有文件. (2)unzip - ...

  9. 打造 通用的 支持多数据库 操作的 DBHelper

    闲来无事,写一个通用的直持多数据库的DBHelper,支持单连接批量执行SQL 因为用了TransactionScope所以请引用System.TransactionScope.dll 代码尚未测试, ...

  10. left join 和 left outer join 的区别

    left join 和 left outer join 的区别 通俗的讲:    A   left   join   B   的连接的记录数与A表的记录数同    A   right   join   ...