Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot create ZipArchive in F#

I am trying to instantiate a ZipArchive class in System.IO.Compression in an F# project:

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)

I can create the same thing in C# in the correct namespace:

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

(This gives a bunch of errors because I'm passing null, but at least I can try to access it).

I do have the System.IO.Compression.FileSystem reference in my F# project (as well as the parent namespace, System.IO.Compression. However, when loading the .FileSystem namespace, I get an error saying "the namespace 'FileSystem' is not defined".

EDIT

Added the full script file I am trying to execute that reproduces the problem.

As shown via the open statements, my project references both of these libraries:

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

I am running on:

  • F# 4.4
  • .NET 4.6.1
  • Visual Studio 2015
  • Windows 10 64 bit

EDIT 2: The Fix!

I was doing all of this in an F# script file, .fsx, which requires telling the interactive environment to load the DLLs like so:

#if INTERACTIVE
#r "System.IO.Compression.dll"
#r "System.IO.Compression.FileSystem.dll"
#endif
like image 952
Max Avatar asked Dec 14 '16 00:12

Max


People also ask

What is ZipArchive PHP?

ZipArchive method in PHP is used to add the file, new directory, and able to read the zip in PHP.

What is ZIP file in python?

Python's zipfile is a standard library module intended to manipulate ZIP files. This file format is a widely adopted industry standard when it comes to archiving and compressing digital data. You can use it to package together several related files.

How to identify a ZIP file?

You can identify compressed files by the file extension (. zip) and a zipper on the folder icon.

How are ZIP files structured?

The basic structure consists of a sequence of chunks comprising a "local file header" followed by the file data (after compression and/or encryption) followed by a chunk known as the "central directory," which lists the files in the package along with key metadata to support their extraction, decryption, etc.


2 Answers

You can use System.IO.Compression to manipulate zip files from .NET 4.5. For some useage examples please see the relevant docs.

You can just wrap the FileStream into ZipArchive, then manipulate it further. The ExtractToDirectory extension method is quite handy. You can create a FileStream, instantiate ZipArchive, then manipulate it further, for example by using the CreateEntryFromFile extension method, Ideally you should try using use on disposable as in the writeZipFile example.

Here's an example of reading and writing a zipfile:

#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
like image 63
s952163 Avatar answered Sep 30 '22 05:09

s952163


You are probably missing a reference to System.IO.Compression.dll.

GZipStream is in the System.IO.Compression namespace, but the System.dll assembly.

ZipArchive is also in the System.IO.Compression namespace, but the System.IO.Compression.dll assembly which may not have been added to your F# project by default.

like image 33
marklam Avatar answered Sep 30 '22 03:09

marklam