Forum Discussion
Failure to extract file from ZIP
- 6 years agoHave you tried the implementation I posted here: https://community.powerbi.com/t5/Power-Query/How-to-connect-Azure-DevOps-REST-API-in-to-power-bi/m-p/895318/highlight/true#M30599
- 6 years ago
Here is a version that should work with all of your ZIP files. It ignores the local file entries and grabs the data from the central directory instead. Please test it out.
// expects full path to the ZIP file, only extracts the first data file after getting its size from the central directory // https://en.wikipedia.org/wiki/Zip_(file_format)#Structure (ZIPFile) => let //read the entire ZIP file into memory - we'll use it often so this is worth it Source = Binary.Buffer(File.Contents(ZIPFile)), // get the full size of the ZIP file Size = Binary.Length(Source), //Find the start of the central directory at the sixth to last byte Directory = BinaryFormat.Record([ MiscHeader=BinaryFormat.Binary(Size-6), Start=BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger32, ByteOrder.LittleEndian) ]) , Start = Directory(Source)[Start], //find the first entry in the directory and get the compressed file size FirstDirectoryEntry = BinaryFormat.Record([ MiscHeader=BinaryFormat.Binary(Start+20), FileSize=BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger32, ByteOrder.LittleEndian), UnCompressedFileSize=BinaryFormat.Binary(4), FileNameLen=BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger16, ByteOrder.LittleEndian), ExtrasLen=BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger16, ByteOrder.LittleEndian) ]) , //figure ou where the raw data starts Offset = 30+FirstDirectoryEntry(Source)[FileNameLen]+FirstDirectoryEntry(Source)[ExtrasLen], Compressed = FirstDirectoryEntry(Source)[FileSize]+1, //get the raw data of the compressed file Raw = BinaryFormat.Record([ Header=BinaryFormat.Binary(Offset), Data=BinaryFormat.Binary(Compressed) ]) // unzip it in Binary.Decompress(Raw(Source)[Data], Compression.Deflate)Name it unzip and and then call it like this
let Source = unzip("C:\downloads\doesnotwork.zip"), #"Imported CSV" = Csv.Document(Source,[Delimiter=",", Encoding=1252, QuoteStyle=QuoteStyle.None]) in #"Imported CSV"
You may want to share some more details. I also wrote a blog entry on this very topic if you are interested.
Thanks lbendlin, I'd love to see your blog. Can you please share the link?
I tried using Mark White's solution to access this zip file but I receive the following error:
His custom function works for other zip files on the same website (using the Web.Contents function as the source) however it doesn't work on the zip file linked above. My guess is that the file size is too large (1.52 GB compressed, >10 GB uncompressed). The .csv in the .zip folder is so large that Zip64 is used. Perhaps that's why Mark's solution doesn't work.
I tried your function but when I invoke it, Power BI gives me the following error message:
I'm not familiar enough with M code to find out what's going wrong in your function. I should note that I receive the same error for all zip files on the website linked above, including the smaller zip files not using Zip64.
Thanks!
Rob
- lbendlin5 years agoSuper User
Here's the blog
https://community.powerbi.com/t5/Community-Blog/Working-With-Zip-Files-in-Power-Query/ba-p/1190186
but your file sizes may be the actual issue. I only tested with files up to 600 MB.