adm-zip doesn't compress data - node.js

I'm trying to use adm-zip to add files from memory to a zip file also in memory. It seems that the zip file is created correctly (the result of saving zipData can be unzipped in Windows), but the compression ratio is always zero.
This is a model of the code that I expected to work but doesn't. As can be seen from the output, "compressedData" is null and "size" and "compressedSize" are the same whatever value is passed as the file content.
var admzip = require("adm-zip")
var zip = new admzip();
zip.addFile("tmp.txt", "aaaaaaaaaaaaaaaaaaaa");
var zipData = zip.toBuffer();
console.log(zip.getEntries()[0].toString());
https://runkit.com/embed/pn5kaiir12b0
How do I get it to compress the files as well as just zipping?

This is an old question but to anyone who is also experiencing this issue, the reason is that the adm-zip does not compress the data until the compressedData field is accessed for the first time.
Quote from the docs
[Buffer] Buffer compressedData When setting compressedData, the LOC
Data Header must also be present at the beginning of the Buffer. If
the compressedData was set for a ZipEntry anf no other change was made
to its properties (comment, extra etc), reading this property will
return the same value. If changes had been made, reading this property
will recompress the data and recreate the entry headers.
If no compressedData was specified, reading this property will
compress the data and create the required headers.
The output of the compressedData Buffer contains the LOC Data Header

Related

nodejs write files which do not open

let dataCer = '0�\u0007\u00060�\u0006��\u0003\u0002\u0001\u0002\u0002\u0010Q��\u0000����K��Z�Q��0\n\u0006\b*�\u0003\u0007\u0001\u0001\u0003\u00020�\u0001l1\u001e0\u001c\u0006\.............'
fs.writeFile('111.cer', dataCer);
let dataPdf = '%PDF-1.4\r\n1 0 obj\r\n<< \r\n/Length 9947\r\n/Filter /FlateDecode\r\n>>\r\nstream\r\nX��]�n#9p}���\u000f���\u0005\b\u0002X��<\'X \u001f�\u001b\u0010 \u0001���H�,6�R�Z�\u0014�N`�\n�T�t�ڼT\u0015���?ԋz��_�{IN_Bz�����O.............'
fs.writeFile('111.pdf', dataPdf);
The data dataCer and dataPdf I get from the application using the GET requests. I can only get this data in this encoding.
And now I need to save them as files.
Also, I will need to then save any data to the file in the same way (zip, rar, png, jpeg, ...).
When i use fs.writeFile, I get files that do not open.
fs.writeFile, can not keep the original state data, ignoring the encoding does not give me the desired result.
Please tell me how to get around this error?
Or which library can save data to any file in node.js, while ignoring the encoding?

nodejs - change contents of zip file without re-generating the whole archive

I'm using node-zip (which uses JSZip under the hood). I need to modify the contents of a zip file, and I'd love to be able to modify it without generating the entire zip again, because it can take a long time for large archives. Here's an example:
var zip = new JSZip()
// Add some files to the zip
zip.file('file1', "file 1 contents\n")
zip.file('file2', "file 2 contents\n")
zip.file('file3', "file 3 contents\n")
// Generate the zip file
buffer = zip.generate()
// Make some changes
zip.file('file1', "changed file contents\n")
// Now I have to generate the entire zip again to get the buffer
buffer = zip.generate()
How can I do something like
updatedBuffer = zip.updateFile(buffer, 'file1', 'changed file contents\n')
Where I get an updated archive buffer but I only have to spend CPU cycles updating the one file
Assuming JSZip v2 here (zip.generate()):
You can get the buffer with asNodeBuffer(), modify it and update the content for your file:
var buffer = zip.file("file1").asNodeBuffer();
// change buffer
zip.file("file1", buffer);
Edit: if you mean editing in place a zip file stored on disk: no, JSZip can't do that.

reading zip file header efficiently in node.js

There are various zip modules for node. Generally they seem to follow a pattern like this:
// Creating a zipfile object
var zf = new zipfile.ZipFile('./test/data/world_merc.zip');
// the zipfile has a list of names:
// zf.names[0] === 'world_merc.prj'
The snippet above was lifted from the node-zipfile README here https://github.com/mapbox/node-zipfile, but for example a similar example exists for the AdmZip package: https://github.com/cthackers/adm-zip.
So this struck me as odd, because it appears both of these libraries assume synchronous code (at the very least, you need to open the file to read the header, which is blocking, right)?
So I dug into the implementation of AdmZip and it turns out you can pass a buffer to the AdmZip constructor, e.g. you can do this:
fs.readFile('./my_file.zip', function(err, buffer) {
var zip = new AdmZip(buffer);
var zipEntries = zip.getEntries();
});
But that's only marginally better, because it appears AdmZip expects that I want to read the whole file in just to access the header. I read the zip spec and my understanding is that the file "central directory file header" which lists the contents is at the end of the file anyway.
So that was a super long lead in to the question, does there exist a node library which will efficiently and asynchronously read the zip contents (e.g. not realize the entire zip file in memory if all I'm going to do is look at the central directory header)?
After much searching I found a suitable implementation that efficiently reads the header async:
https://github.com/antelle/node-stream-zip

How to add zip file without compression using node.js?

I am converting docx to epub using pandoc. After converting epub, i do changes with zip file and converting epub also. At that time,
I got the following issue after converting zip file to epub on mimetype file.
Mimetype contains wrong type (application/epub+zip expected).
I am searching a lot and get two logic
First one e.g., extra spaces, new line characters but it was going vain(there is no extra spaces, new line).
Add the mimetype file without compression in zip.
I am getting struck with second point. How to add mimetype file without compression in zip using node.js coding.
var archiver = require('archiver');
var archive = archiver('zip');
archive.file('d:\\xxxx'+'\\mimetype', { name:'mimetype'});
What is the problem in the above code and any attribute for zip?
Can any one assist me for adding file without compression in zip?
Thanks in advance.
add the zip option {store:true} for without compression
https://www.npmjs.com/package/archiver#store-boolean

File much larger after copying with it.bytes

I wanted to copy a file from one location to another using a Groovy script. I found that the copied files was orders of magnitude larger than the original file after copying.
After some trial and error I found the correct way to copy but am still puzzled as to why it should be bigger.
def existingFile = new File("/x/y/x.zip")
def newFile1 = new File("/x/y/y.zip")
def newFile2 = new File("/x/y/z.zip")
new File(newFile1) << new File(existingFile).bytes
new File(newFile2).bytes = new File(existingFile).bytes
If you run this code, newFile1 will be much larger than existingFile, while newFile2 will be the same size as existingFile.
Note that both zip files are valid afterwards.
Does anyone know why this happens? Am I use the first copy incorrectly? Or is it something odd in my setup?
If the file already exists before this code is called then you'll get different behaviour from << and .bytes = ...
file << byteArray
will append the contents of byteArray to the end of the file, whereas
file.bytes = byteArray
will overwrite the file with the specified content. When the byteArray is ZIP data, both versions will give you a result that is a valid ZIP file, because the ZIP format can cope with arbitrary data prepended to the beginning of the file before the actual ZIP data without invalidating the file (typically this is used for things like self-extracting .exe stubs).

Resources