如何在 FSharp 中压缩文件?

发布于 2024-10-09 08:16:57 字数 628 浏览 4 评论 0原文

粗略的谷歌搜索没有返回任何简单到可以理解的内容(我对函数式编程还很陌生)。

如果我有一个文件数组,我如何压缩每个文件,然后创建所有压缩文件的 zip?

到目前为止我有这样的事情:

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?

编辑:这是我到目前为止所拥有的,但我遇到了一些奇怪的行为。一旦我弄清楚奇怪的行为到底是什么:

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

更新:我不认为“奇怪的行为”与 zip 模块有关。我感谢所有的帮助!

Cursory Google search didn't return anything simple enough to understand (i'm pretty new to functional programming).

if I have an array of files, how can i zip each file and then create a zip of all zipped files?

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. I appreciate all the help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

明月夜 2024-10-16 08:16:57

您是否正在尝试创建 zip 压缩的独立实现?

我会使用 http://dotnetzip.codeplex.com/ 中的 DotNetZip ——它是一个单一的、托管的代码 (C#) 汇编。从 F# 使用它应该与从项目中引用程序集一样简单。

使用方法很简单。对于 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");
}

如果您想要压缩 zip 文件的集合(为什么?),可以通过多种方法使用 DotNetZip 来实现这一点(例如,您可以将 zip 文件保存到流中,或者将流添加到 zip 文件中)文件)。

希望这有帮助!


编辑注意: DotNetZip 曾经住在 Codeplex。 Codeplex 已关闭。旧存档仍然[可在 Codeplex 上找到][1]。代码似乎已迁移到 Github:


Are you trying to create an independent implementation of zip compression?

I'd use DotNetZip from http://dotnetzip.codeplex.com/ -- it's a single, managed code (C#) assembly. Using it from F# should be pretty much as simple as referencing the assembly from your project.

Usage is simple. For 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).

Hope this helps!


Edited To Note: DotNetZip used to live at Codeplex. Codeplex has been shut down. The old archive is still [available at Codeplex][1]. It looks like the code has migrated to Github:


落日海湾 2024-10-16 08:16:57

我没有使用 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)

如果 zipfile_name 过载,您可能还需要将类型信息添加到其中。

此函数可用于创建各个文件的 zip 文件,然后用于创建包含所有较小 zip 文件的大 zip 文件。这是一个示例,尽管您实际上并不希望像它那样在各处重复文件名。

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"

I haven't used the zip library that Nicholas mentioned, but this may be the F# version of what you want.

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.

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. 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"
兔姬 2024-10-16 08:16:57

从 .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

As of .NET 4.6.2, there is ZipArchive class available:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文