粗略的谷歌搜索没有返回任何简单易懂的内容(我对函数式编程很陌生)。
如果我有一个文件数组,我如何压缩每个文件,然后创建所有压缩文件的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模块有关。我感谢所有的帮助!
答案 0 :(得分:8)
您是否尝试创建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:
答案 1 :(得分:3)
我没有使用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"
答案 2 :(得分:0)
从.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