最近闲暇时间开始写点通用基础类在写到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. sulime运行 java 和 php

    执行php脚本 1. 先配置好php环境变量 2. Tools -> Build System -> New Build System.... {      "cmd" ...

  2. NET Core开发-读取配置文件Configuration

    ASP.NET Core开发-读取配置文件Configuration   ASP.NET Core 是如何读取配置文件,今天我们来学习. ASP.NET Core的配置系统已经和之前版本的ASP.NE ...

  3. Linux08--Shell程序设计03 shell script

    第一个Shell脚本——HelloWorld [root@localhost ~]# vi sh01.sh #!/bin/bash #!表明使用哪种shell # this is my first s ...

  4. Matlab.NET混编技巧之——找出Matlab内置函数

    原文 http://www.cnblogs.com/asxinyu/p/3295309.html Matlab与.NET的混合编程,掌握了基本过程,加上一定的开发经验和算法基础,肯 定不难.反之,有时 ...

  5. javascript预加载和延迟加载

    延迟加载javascript,也就是页面加载完成之后再加载javascript,也叫on demand(按需)加载,一般有一下几个方法: What can your tired old page, o ...

  6. Python学习笔记8-类的继承 、深度优先、广度优先

    Python 类声明 语法: class 类名: 类体 例: #--encoding:utf-8-- # class AddressBookEntity: myVersion=0.1 def __in ...

  7. javascript第三课underfind和类型获取

    1.underfind一般发生于变量定义之后未赋值,因此变量的值就为underfind 2.var obj=new object(); 此时使用obj点,可以获取到obj对象的一些方法,使用alert ...

  8. jQuery源码笔记——准备

    将变量局部化 作为一个库首要解决的问题就是防止影响全局的变量.自执行匿名函数可以很好的实现这一点. 传入window,undefiend是将全局变量改为局部变量,根据作用域链访问原理,访问更快一些,. ...

  9. EF 6.0使用小计

    ---恢复内容开始--- 最近尝试了下EF Extended,但是居然需要EF6.0以上,没办法,只能安装了,打开解决方案,选择库程序包管理下的程序包管理控制台(或者直接右击你需要使用扩展的解决方案选 ...

  10. R语言初涉

    R语言简单的函数的使用: “<-”表示赋值,也可以用“=”. c()为连接函数,连接中间的数据表示向量,连接中间的数据表示向量,X1 <- c()表示用一组数据为变量X1赋值. mean( ...