简体   繁体   English

如何在FSharp中压缩文件?

[英]How to zip files in FSharp?

Cursory Google search didn't return anything simple enough to understand (i'm pretty new to functional programming). Cursory Google搜索没有返回任何简单到足以理解的内容(对于函数式编程我还是很陌生)。

if I have an array of files, how can i zip each file and then create a zip of all zipped files? 如果我有一个文件数组,如何压缩每个文件,然后为所有压缩文件创建一个zip文件?

I have something like this so far: 到目前为止,我有这样的事情:

let zip f = 
    f.zip //this is where I need the most direction

let zipAllAttachments f =
    f
    |> Seq.map zip   //do I need to create another function to create a single zip of all zips?

EDIT: this is what I have so far, but I'm getting some strange behavior. 编辑:这是我到目前为止,但是我得到一些奇怪的行为。 More to come once I figure out what the strange behavior IS exactly: 一旦我弄清楚了奇怪的行为到底是什么,就会有更多的事情发生:

use zipfile = new ZipFile()
for fileObj in files do
    zipfile.AddFile(sprintf "%s%s" path  fileObj.Filename) |> ignore
    zipfile.Save("C:\\temp\\Compliance.zip")

UPDATE: I don't think the "strange behavior" is related to the zip module. 更新:我不认为“奇怪的行为”与zip模块有关。 I appreciate all the help! 我感谢所有的帮助!

Are you trying to create an independent implementation of zip compression? 您是否要创建一个独立的zip压缩实现?

I'd use DotNetZip from http://dotnetzip.codeplex.com/ -- it's a single, managed code (C#) assembly. 我会使用来自http://dotnetzip.codeplex.com/的 DotNetZip,它是一个单一的托管代码(C#)程序集。 Using it from F# should be pretty much as simple as referencing the assembly from your project. 从F#中使用它应该与从项目中引用程序集一样简单。

Usage is simple. 用法很简单。 For C#: 对于C#:

using (ZipFile zip = new ZipFile())
{
  // add this map file into the "images" directory in the zip archive
  zip.AddFile("c:\\images\\personal\\7440-N49th.png", "images");
  // add the report into a different directory in the archive
  zip.AddFile("c:\\Reports\\2008-Regional-Sales-Report.pdf", "files");
  zip.AddFile("ReadMe.txt");
  zip.Save("MyZipFile.zip");
}

If you want to zip a collection of zip files (why?), there's a number of ways to do that with DotNetZip (you can, for instance, save your zip file to a stream, or add a stream to a zip file). 如果要压缩zip文件的集合(为什么?),则可以通过多种方式使用DotNetZip进行压缩(例如,可以将zip文件保存到流中,或将流添加到zip文件中)。

Hope this helps! 希望这可以帮助!


Edited To Note: DotNetZip used to live at Codeplex. 编辑要注意: DotNetZip曾经居住在Codeplex。 Codeplex has been shut down. Codeplex已关闭。 The old archive is still [available at Codeplex][1]. 仍旧存档[可从Codeplex获得] [1]。 It looks like the code has migrated to Github: 看起来代码已迁移到Github:


I haven't used the zip library that Nicholas mentioned, but this may be the F# version of what you want. 我没有使用Nicholas提到的zip库,但这可能是您想要的F#版本。

let create_zip_file (files: seq<string>) zipfile_name = 
    use zipfile = new ZipFile()
    files
    |> Seq.iter (fun f -> zip.AddFile(f))

    zipfile.Save(zipfile_name)

You may need to add type information to zipfile_name too, if it is overloaded. 如果过载,您可能还需要向zipfile_name添加类型信息。

This function could be used to create the zip files of the individual files, and then used to create a big zip file containing all of the smaller zip files. 此功能可用于创建单个文件的zip文件,然后用于创建包含所有较小zip文件的大zip文件。 Here is an example, although you wouldn't actually want to duplicate the file names all over the place like it does. 这是一个示例,尽管您实际上并不希望像在整个地方一样重复文件名。

create_zip_file ["first_file"] "first_file.zip"
create_zip_file ["second_file"] "second_file.zip"
create_zip_file ["first_file.zip"; "second_file.zip"] "big_file.zip"

As of .NET 4.6.2, there is ZipArchive class available: 从.NET 4.6.2开始,有可用的ZipArchive类:

namespace FSharpBasics

module ZipThis =

    open System.IO
    open System.IO.Compression
    open System.Reflection
    open System

    let create (zipName: string) (files: seq<FileInfo>) =
        use s = File.Create(zipName)
        use z = new ZipArchive(s, ZipArchiveMode.Create)
        files
            |> Seq.map (fun item -> (item.FullName, item.Name))
            |> Seq.iter (fun (path, name) -> z.CreateEntryFromFile (path, name) |> ignore)

    [<EntryPoint>]
    let main argv =
        let di = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory)
        printfn "Creating test.zip on current directory"
        create "test.zip" (di.GetFiles "*.dll")
        printfn "Created"
        0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM