如何使用C#压缩文件,不使用第三方API?

时间:2009-06-02 16:41:27

标签: c# compression zip download

我很确定这不是重复,所以请耐心等待一分钟。

如何在不使用任何第三方库的情况下以编程方式(C#)压缩文件(在Windows中)?我需要一个原生的Windows调用或类似的东西;我真的不喜欢开始一个过程的想法,但如果我绝对不得不这样做。 PInovke呼叫会好得多。

如果做不到这一点,让我告诉你我真正想要实现的目标:我需要能够让用户在一个请求中下载一组文档。关于如何实现这一目标的任何想法?

8 个答案:

答案 0 :(得分:268)

  

如何在不使用的情况下以编程方式(C#)压缩文件(在Windows中)   任何第三方图书馆?

如果使用4.5+框架,现在有ZipArchiveZipFile类。

using (ZipArchive zip = ZipFile.Open("test.zip", ZipArchiveMode.Create))
{
    zip.CreateEntryFromFile(@"c:\something.txt", "data/path/something.txt");
}

您需要添加对以下内容的引用:

  • System.IO.Compression
  • System.IO.Compression.FileSystem

对于.NET Core定位net46,您需要为

添加依赖项
  • System.IO.Compression
  • System.IO.Compression.ZipFile

示例project.json:

"dependencies": {
  "System.IO.Compression": "4.1.0",
  "System.IO.Compression.ZipFile": "4.0.1"
},

"frameworks": {
  "net46": {}
}

对于.NET Core 2.0,只需添加一个简单的using语句即可:

  • 使用System.IO.Compression;

答案 1 :(得分:84)

您使用的是.NET 3.5吗?您可以使用ZipPackage类和相关类。它不仅仅是压缩文件列表,因为它需要为您添加的每个文件添加MIME类型。它可能会做你想要的。

我目前正在使用这些类来解决类似的问题,将几个相关文件存档到一个文件中进行下载。我们使用文件扩展名将下载文件与我们的桌面应用相关联。我们遇到的一个小问题是,不可能只使用像7-zip这样的第三方工具来创建zip文件,因为客户端代码无法打开它 - ZipPackage添加了一个描述内容类型的隐藏文件每个组件文件,如果缺少该内容类型文件,则无法打开zip文件。

答案 2 :(得分:11)

我遇到了同样的情况,想要.NET而不是第三方库。正如上面提到的另一张海报,仅仅使用ZipPackage类(在.NET 3.5中引入)还不够。存档中必须包含一个附加文件,以便ZipPackage正常工作。如果添加了此文件,则可以直接从Windows资源管理器打开生成的ZIP包 - 没问题。

您所要做的就是将[Content_Types] .xml文件添加到存档的根目录中,并为您希望包含的每个文件扩展名添加“默认”节点。添加后,我可以从Windows资源管理器中浏览包或以编程方式解压缩并读取其内容。

有关[Content_Types] .xml文件的更多信息,请访问:http://msdn.microsoft.com/en-us/magazine/cc163372.aspx

以下是[Content_Types] .xml(必须准确命名)文件的示例:

<?xml version="1.0" encoding="utf-8" ?>
<Types xmlns=
    "http://schemas.openxmlformats.org/package/2006/content-types">
  <Default Extension="xml" ContentType="text/xml" /> 
  <Default Extension="htm" ContentType="text/html" /> 
  <Default Extension="html" ContentType="text/html" /> 
  <Default Extension="rels" ContentType=
    "application/vnd.openxmlformats-package.relationships+xml" /> 
  <Default Extension="jpg" ContentType="image/jpeg" /> 
  <Default Extension="png" ContentType="image/png" /> 
  <Default Extension="css" ContentType="text/css" /> 
</Types>

用于创建ZIP文件的C#:

var zipFilePath = "c:\\myfile.zip"; 
var tempFolderPath = "c:\\unzipped"; 

    using (Package package = ZipPackage.Open(zipFilePath, FileMode.Open, FileAccess.Read)) 
    { 
        foreach (PackagePart part in package.GetParts()) 
        { 
            var target = Path.GetFullPath(Path.Combine(tempFolderPath, part.Uri.OriginalString.TrimStart('/'))); 
            var targetDir = target.Remove(target.LastIndexOf('\\')); 

            if (!Directory.Exists(targetDir)) 
                Directory.CreateDirectory(targetDir); 

            using (Stream source = part.GetStream(FileMode.Open, FileAccess.Read)) 
            { 
                source.CopyTo(File.OpenWrite(target)); 
            } 
        } 
    } 

注意:

答案 3 :(得分:7)

    private static string CompressFile(string sourceFileName)
    {
        using (ZipArchive archive = ZipFile.Open(Path.ChangeExtension(sourceFileName, ".zip"), ZipArchiveMode.Create))
        {
            archive.CreateEntryFromFile(sourceFileName, Path.GetFileName(sourceFileName));
        }
        return Path.ChangeExtension(sourceFileName, ".zip");
    }

答案 4 :(得分:4)

对于.NET 2.0应用程序,我使用了SharpZipLib。易于使用和开源。

答案 5 :(得分:1)

根据Simon McKenzie的回答to this question,我建议使用这样的一对方法:

    public static void ZipFolder(string sourceFolder, string zipFile)
    {
        if (!System.IO.Directory.Exists(sourceFolder))
            throw new ArgumentException("sourceDirectory");

        byte[] zipHeader = new byte[] { 80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

        using (System.IO.FileStream fs = System.IO.File.Create(zipFile))
        {
            fs.Write(zipHeader, 0, zipHeader.Length);
        }

        dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
        dynamic source = shellApplication.NameSpace(sourceFolder);
        dynamic destination = shellApplication.NameSpace(zipFile);

        destination.CopyHere(source.Items(), 20);
    }

    public static void UnzipFile(string zipFile, string targetFolder)
    {
        if (!System.IO.Directory.Exists(targetFolder))
            System.IO.Directory.CreateDirectory(targetFolder);

        dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
        dynamic compressedFolderContents = shellApplication.NameSpace(zipFile).Items;
        dynamic destinationFolder = shellApplication.NameSpace(targetFolder);

        destinationFolder.CopyHere(compressedFolderContents);
    }
}

答案 6 :(得分:0)

看起来Windows可能会让你this ...

不幸的是,除非你去第三方组件,否则我认为你不会开始一个单独的过程。

答案 7 :(得分:0)

将这4个功能添加到您的项目中:

$ truffle migrate
⚠️  Important ⚠️
If you're using an HDWalletProvider, it must be Web3 1.0 enabled or your migration will hang.


Starting migrations...
======================
> Network name:    'development'
> Network id:      10
> Block gas limit: 3758096384


1_initial_migration.js
======================

   Deploying 'Migrations'
   ----------------------
   > transaction hash:    0x0a55cd010bb30247c3ae303e54be8dd13177b520af5967728cf77e07ca9efe76
- Blocks: 0            Seconds: 0
   > Blocks: 0            Seconds: 0
   > contract address:    0x1932c48b2bF8102Ba33B4A6B545C32236e342f34
   > account:             0xed9d02e382b34818e88B88a309c7fe71E65f419d
   > balance:             1000000000
   > gas used:            245462
   > gas price:           0 gwei
   > value sent:          0 ETH
   > total cost:          0 ETH


- Saving migration to chain.
   > Saving migration to chain.
   > Saving artifacts
   -------------------------------------
   > Total cost:                   0 ETH


2_deploy_simplestorage.js
=========================

   Deploying 'SimpleStorage'
   -------------------------
Error:  *** Deployment Failed ***

"SimpleStorage" -- Invalid number of parameters for "undefined". Got 2 expected 1!.

    at C:\Users\dany.vandermeij\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\truffle-deployer\src\deployment.js:364:1
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)
Truffle v5.0.1 (core: 5.0.1)
Node v8.11.4

并像这样使用它们:

var SimpleStorage = artifacts.require("SimpleStorage");

module.exports = function(deployer) {
  deployer.deploy(SimpleStorage, 42)
};