最近闲暇时间开始写点通用基础类在写到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. 轻松搞定javascript变量(闭包,预解析机制,变量在内存的分配 )

    变量:  存储数据的容器     1.声明        var   2.作用域       全局变量. 局部变量. 闭包(相对的全局变量):   3.类型         a.基本类型(undefi ...

  2. Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Chinese_PRC_CI_AS" in the equal to operation.

    Scenario : 这个问题是我的存储过程中用到临时表时发生的. 应该是sql server 服务器的排序规则 (SQL_Latin1_General_CP1_CI_AS ) 与数据库的排序规则(C ...

  3. 如何利用多核CPU来加速你的Linux命令 — awk, sed, bzip2, grep, wc等

    http://blog.chinaunix.net/uid-20662820-id-4023733.html http://www.faqs.org/faqs/snmp-faq/part2/ http ...

  4. 适应多行长文本的Android TextView

    适应多行长文本的Android TextView

  5. JQuery window、document、 body

    我电脑屏幕分辨率:1440 * 900   最大化浏览器,刷新浏览器 alert($(window).width() + "---" + $(window).height()); ...

  6. Spring、Hello AOP

    AOP 概念:http://blog.csdn.net/moreevan/article/details/11977115 AOP 所使用到的jar 包: aspectjrt.jar common-a ...

  7. 在magento中定义static block

    在magento中如何调用static block?(系统面板内CMS---->static block) 解答:若想在站点页面的某个地方放点静态的内容,比如广告,或者是促销信息之类的,这样的东 ...

  8. Android不规则瀑布流照片墙的实现+LruCache算法

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZnJhbmNpc3NoaQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  9. java于23设计模式

    详情请参阅23设计模式 版权声明:本文博主原创文章,博客,未经同意不得转载.

  10. js 小练习之indexOf

    闲来无事~ 写点小练习 function zz(arr, item) { var a=arr.join("") var b=a.indexOf(item) alert(b) } z ...