无法在 F# 中创建 ZipArchive

Cannot create ZipArchive in F#

我正在尝试在 F# 项目的 System.IO.Compression 中实例化一个 ZipArchive class:

open System.IO
open System.IO.Compression
open System.IO.Compression.FileSystem //this line errors, as expected

// Define your library scripting code here

let directoryPath = @"C:\Users\max\Downloads"

let dirInfo = new DirectoryInfo(directoryPath)

let zippedFiles = dirInfo.GetFiles() 
|> Array.filter (fun x -> x.Extension.Equals(".zip"))

let fileStream = new FileStream(((Array.head zippedFiles).FullName), System.IO.FileMode.Open)

//this line does not compile, because ZipArchive is not defined
let archive = new System.IO.Compression.ZipArchive(fileStream)

我可以在正确的命名空间中用 C# 创建相同的东西:

var unzipper = new System.IO.Compression.ZipArchive(null);

(这给出了一堆错误,因为我传递的是 null,但至少我可以尝试访问它)。

在我的 F# 项目中有 System.IO.Compression.FileSystem 引用(以及父名称空间 System.IO.Compression)。但是,加载 .FileSystem 命名空间,我收到一条错误消息 "the namespace 'FileSystem' is not defined"。

编辑

添加了我正在尝试执行的重现问题的完整脚本文件。

open 语句所示,我的项目引用了这两个库:

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

我 运行 在:

编辑 2:修复!

我在 F# 脚本文件中完成了所有这些工作,.fsx,这需要告诉交互式环境像这样加载 DLL:

#if INTERACTIVE
#r "System.IO.Compression.dll"
#r "System.IO.Compression.FileSystem.dll"
#endif

您可以使用 System.IO.Compression 从 .NET 4.5 操作 zip 文件。有关一些用法示例,请参阅 relevant docs.

您可以将 FileStream 包装到 ZipArchive 中,然后进一步操作它。 ExtractToDirectory 扩展方法非常方便。您可以创建一个 FileStream,实例化 ZipArchive,然后进一步操作它,例如通过使用 CreateEntryFromFile 扩展方法,理想情况下,您应该尝试在 writeZipFile 示例中对一次性使用 use

这是一个读取和写入 zip 文件的示例:

#if INTERACTIVE
#r "System.IO.Compression.dll"
#r "System.IO.Compression.FileSystem.dll"
#endif

open System.IO
open System.IO.Compression

let zipfile = @"c:\tmp\test.zip"
File.Exists zipfile //true

let readZipFile (x:string) = 
    let x = new FileStream(x,FileMode.Open,FileAccess.Read)
    new ZipArchive(x)

let z = readZipFile zipfile
z.ExtractToDirectory(@"c:\tmp\test")
File.Exists @"c:\tmp\test\test.txt" // true

let writeZipFile (x:string) =
    use newFile = new FileStream(@"c:\tmp\newzip.zip",FileMode.Create)
    use newZip =  new ZipArchive(newFile,ZipArchiveMode.Create)
    newZip.CreateEntryFromFile(@"c:\tmp\test.txt","test.txt")

writeZipFile @"c:\tmp\test.txt"
File.Exists @"c:\tmp\newzip.zip"  // true

您可能缺少对 System.IO.Compression.dll 的引用。

GZipStream 位于 System.IO.Compression 命名空间 ,但 System.dll 程序集 .

ZipArchive 也在 System.IO.Compression 命名空间 中,但是 System.IO.Compression.dll assembly默认情况下可能没有添加到您的 F# 项目中。