Node Zlib incorrect header check
The file is gzipped, so you need to use zlib.Gunzip
instead of zlib.Inflate
.
Also, streams are very efficient in terms of memory usage, so if you want to perform the retrieval without storing the .gz file locally first, you can use something like this:
request('https://wiki.mozilla.org/images/f/ff/Example.json.gz')
.pipe(zlib.createGunzip())
.pipe(fs.createWriteStream('example.json'));
Otherwise, you can modify your existing code:
var gunzip = zlib.createGunzip();
readstream.pipe(gunzip).pipe(writestream);
ZlibDecompressor throws incorrect header check exception
The problem reported is that there is no valid zlib header in the first two bytes. The problem with the data is that it does not appear to have any deflate-compressed data anywhere in it, regardless of whether such data could be zlib wrapped, gzip wrapped, or raw.
Reconstructing zlib stream
To assure that you can start decompression at some point with no history, you must either use Z_FULL_FLUSH
or simply end the stream and start a new one.
For the former you could do a Z_SYNC_FLUSH
followed by a Z_FULL_FLUSH
in order to insert two markers resulting in the nine bytes 00 00 ff ff 00 00 00 ff ff
, which would be unlikely to be seen randomly in the compressed data. You can do the same for the latter, simply inserting a large-enough marker between the end of the previous zlib stream and the start of the next zlib stream.
Handling Haskell zlib decompression errors
The function from zlib
you need to use here is called decompressWithErrors
. Its value is the recursive DecompressStream
data structure that you can fold to a ByteString
using v:fromDecompressStream
Here's a full example of how to write the function you asked for:
import Data.Either
import Codec.Compression.Zlib.Internal
import qualified Data.ByteString.Lazy.Char8 as LB
-- | Convert & unfold the custom DecompressStream
-- error format from zlib to a Either
decompressStreamToEither :: DecompressStream -> Either String LB.ByteString
decompressStreamToEither (StreamError _ errmsg) = Left errmsg
decompressStreamToEither stream@(StreamChunk _ _) = Right $ fromDecompressStream stream
decompressStreamToEither StreamEnd = Right $ ""
-- | Decompress with explicit error handling
safeDecompress :: LB.ByteString -> Either String LB.ByteString
safeDecompress bstr = decompressStreamToEither $ decompressWithErrors gzipOrZlibFormat defaultDecompressParams bstr
-- | Decompress gzip, if it fails, return uncompressed String
decompressIfPossible :: LB.ByteString -> LB.ByteString
decompressIfPossible bstr =
let conv (Left a) = bstr
conv (Right a) = a
in (conv . safeDecompress) bstr
Note that this example uses gzipOrZlibFormat
which automatically detects if the header is a zlib or a gzip header.
Zlib is unable to extract a compress String in java, compression is done in python
That is a gzip stream, not a zlib stream. Use GZIPInputStream
.
Related Topics
Multithreaded Blas in Python/Numpy
Python Pip Specify a Library Directory and an Include Directory
Serialize Python Dictionary to Xml
Python: Load Variables in a Dict into Namespace
What Version of Visual Studio Is Python on My Computer Compiled With
How to Convert a Numpy Array to Pil Image Applying Matplotlib Colormap
How to Use Opencv's Connectedcomponentswithstats in Python
Runtimeerror: Main Thread Is Not in Main Loop
How to Convert a String to Utf-8 in Python
Python Readlines() Usage and Efficient Practice for Reading
Take Screenshot of Full Page with Selenium Python with Chromedriver
Add Column to Dataframe with Constant Value
How to Change a Module Variable from Another Module
Checking If All Elements in a List Are Unique
Solving "Dll Load Failed: %1 Is Not a Valid Win32 Application." for Pygame