Zip file and save to specific folder - python

this might be a silly question but I'm struggling a lot finding solution to it.
So I have a file in the given folder:
Output\20190101_0100\20190101_0100.csv
Now I want to zip the file and save it to same location. So here's my try:
zipfile.ZipFile('Output/20190101_0100/20190101_0100_11.zip', mode='w', compression=zipfile.ZIP_DEFLATED).write('Output/20190101_0100/20190101_0100_11.csv')
But it's making a folder insider zip folder and saving it, as shown below:
Output\20190101_0100\20190101_0100_11.zip\Output\20190101_0100\20190101_0100_11.csv
Can someone tell me how can I save my file directly in the same location or location mentioned below:
Output\20190101_0100\20190101_0100_11.zip\20190101_0100_11.csv

Rephrasing of question
The question is slightly confusing because Output\20190101_0100\20190101_0100_11.zip\Output\20190101_0100\20190101_0100_11.csv won't be a file, but rather Output\20190101_0100\20190101_0100_11.csv will be a file within the zip file Output\20190101_0100\20190101_0100_11.zip (if I am not mistaken)
Just to restate your problem (if I understood it correctly):
You have a file Output\20190101_0100\20190101_0100.csv (a file 20190101_0100.csv in the Output -> 20190101_0100 sub directory)
You want to create the zip file Output/20190101_0100/20190101_0100_11.zip (20190101_0100_11.zip in the Output -> 20190101_0100.zip directory)
You want to add the aforementioned CSV file Output\20190101_0100\20190101_0100.csv but without the leading path, i.e. as 20190101_0100_11.csv rather than Output\20190101_0100\20190101_0100.csv.
Or to not get confused with too many similar directories, let's simplify it as:
You have a file test.csv in the sub directory sub-folder
You want to create the zip file test.zip
You want to add the aforementioned CSV file test.csv but without the leading path, i.e. as test.csv rather than sub-folder/test.csv.
Answer
From the ZipFile.write documentation:
Write the file named filename to the archive, giving it the archive
name arcname (by default, this will be the same as filename, but
without a drive letter and with leading path separators removed).
That means that arcname will default to the passed in filename (it doesn't have a drive letter or leading path separator).
If you want to remove the sub folder part, just pass in arcname as well. e.g.:
import zipfile
with zipfile.ZipFile('path-to-zip/test.zip', 'w') as zf:
zf.write('sub-folder/test.csv', arcname='test.csv')

You could try using a raw path:
zipfile.ZipFile('Output/20190101_0100/20190101_0100_11.zip', mode='w', compression=zipfile.ZIP_DEFLATED).write(r'C:\...\Output\20190101_0100\20190101_0100_11.csv')

Related

How to add a password and output directory using Zipfile module in Python?

I got below code from online and I am trying to add a password and I want to change the result directory to be "C:#SFTPDWN" (Final Zip file should be in this folder).
I try to change it like below, it did not work.
with ZipFile('CC-Data.zip', 'w', 'pass word') as zip:
Can anybody please tell how to change this code to add password and change result folder?
One last thing, currently it will zip #SFTPDWN folder, I just want to zip everything inside (Right now it will create two folders (CC-Data.zip and inside it #SFTPDWN )). Can anybody please tell me how to zip everything inside #SFTPDWN folder?
Code
from zipfile import ZipFile
import os
def get_all_file_paths(directory):
file_paths = []
for root, directories, files in os.walk(directory):
for filename in files:
filepath = os.path.join(root, filename)
file_paths.append(filepath)
return file_paths
def main():
# path to folder which needs to be zipped
directory = 'C:\#SFTPDWN'
file_paths = get_all_file_paths(directory)
print('Following files will be zipped:')
for file_name in file_paths:
print(file_name)
with ZipFile('CC-Data.zip', 'w') as zip:
# writing each file one by one
for file in file_paths:
zip.write(file)
print('Zipped successfully!')
if __name__ == "__main__":
main()
For the password question: from the documentation:
This module [...] supports decryption of encrypted files in ZIP archives, but it currently cannot create an encrypted file. Decryption is extremely slow as it is implemented in native Python rather than C.
https://docs.python.org/3/library/zipfile.html
You would need to use a 3rd party library to create an encrypted zip, or encrypt the archive some other way.
For the second part, in ZipFile.write the documentation also mentions:
ZipFile.write(filename, arcname=None, compress_type=None, compresslevel=None)
Write the file named filename to the archive, giving it the archive name arcname (by default, this will be the same as filename, but without a drive letter and with leading path separators removed). [...]
Note: Archive names should be relative to the archive root, that is, they should not start with a path separator.
https://docs.python.org/3/library/zipfile.html#zipfile.ZipFile.write
So you would need to strip off whatever prefix of your file variable and pass that as the arcname parameter. Using os.path.relpath may help, e.g. (I'm on Linux, but should work with Windows paths under Windows):
>>> os.path.relpath("/folder/subpath/myfile.txt", "/folder/")
'subpath/myfile.txt'
Sidebar: a path like "C:\Something" is an illegal string, as it has the escape \S. Python kinda tolerates this (I think in 3.8 it will error) and rewrites them literally. Either use "C:\\Something", r"C:\Something", or "C:/Something" If you attempted something like "C:\Users" it would actually throw an error, or "C:\nothing" it might silently do something strange...

How to Write to File in Subdirectory Python 2.7?

I can write to a file in current directory.
I cannot write to a file in a subdirectory.
I checked online but the posts and previous questions didn't really help.
I have the code below, it should write to File.txt which is inside Subfolder. However, instead of this, I get a new File called "SubFolder\File.txt" in my current directory.
Any help?
PATH = os.getcwd()
PATH+= 'SubFolder\File.txt'
fileInput = open(PATH, "w")
fileOutput = open("SubFolder\File.txt", "w")
I expect a file in a subfolder.
I get a file with the desired path as a file name. Can you help? Thanks!
use double escape for file paths.
fileOutput = open("SubFolder\\File.txt", "w")
Opening a file for writing doesn't create any intervening subfolders that don't yet exist. You have to create them yourself first, using os.mkdir() (for one level) or os.makedirs() (for multiple levels).

Extracting all file names in python

I have a application that converts from one photo format to another by inputting in cmd.exe following: "AppConverter.exe" "file.tiff" "file.jpeg"
But since i don't want to input this every time i want a photo converted, i would like a script that converts all files in the folder. So far i have this:
def start(self):
for root, dirs, files in os.walk("C:\\Users\\x\\Desktop\\converter"):
for file in files:
if file.endswith(".tiff"):
subprocess.run(['AppConverter.exe', '.tiff', '.jpeg'])
So how do i get the names of all the files and put them in subprocess. I am thinking taking basename (no ext.) for every file and pasting it in .tiff and .jpeg, but im at lost on how to do it.
I think the fastest way would be to use the glob module for expressions:
import glob
import subprocess
for file in glob.glob("*.tiff"):
subprocess.run(['AppConverter.exe', file, file[:-5] + '.jpeg'])
# file will be like 'test.tiff'
# file[:-5] will be 'test' (we remove the last 5 characters, so '.tiff'
# we add '.jpeg' to our extension-less string
All those informations are on the post I've linked in the comments o your original question.
You could try looking into os.path.splitext(). That allows you to split the file name into a tuple containing the basename and extension. That might help...
https://docs.python.org/3/library/os.path.html

How to exclude ".DS_Store" path when compressing files in Python

I have a python script that compresses specific files into a zip file. However I have noticed that a file ".DS_Store" is produced within this zip file. Is there a way I can remove this from the zip file or avoid it being created in the first place in my python script. From what I have found online I think on a windows machine this hidden file appears as "macosx" file.
I've tested the zip file with and without the ".DS_Store" hidden file (I manually deleted it). When I remove it, the zip file is able to be processed correctly and when I leave it in, errors are thrown.
This is how I create the zip file in my python script:
#Create zip file of all necessary files
zipf = zipfile.ZipFile(new_path+zip_file_name, 'w', zipfile.ZIP_DEFLATED)
create_zip(new_path,zipf)
zipf.close()
Any advice how to approach removing this hidden file would be appreciated.
Your code uses a function, create_zip, but you haven't shared the code of that function. Presumably, it loops through the contents of a directory and calls the .write method of the ZipFile instance in order to write each file into the archive. If this is the case, just add some logic to that function to exclude any files called .DS_Store.
def create_zip(path, zipfile):
files = os.listdir(path)
for file in files:
if file != '.DS_Store':
zipfile.write(file)

How to Write a File to the Root Directory of a Zip File in Python

I'm trying to replace a file in a zipped archive with a script using zipfile. The file is one directory, the archive is in another. To do this, I copy everything from the original archive into another, excluding the file I want to replace. Then I write the new version of the file to replace into the new archive, close it, and delete the old archive and rename the new one. Should be easy, right? Wrong.
For whatever reason, the zipfile.write() method has this silly thing it does where it assumes that the second (optional) argument, arcname is the same as your file name, unless you specify it. So, if I have the following:
fileName = "C:\\Documents\\file"
archive.write(fileName)
I will get an archive with a subarchive called "Documents", and within that will be the file. I want the file to be in the root directory of the archive (sidenote: is 'root directory' the right term for what I'm refering to?)
Thing's I've Tried:
archive.write(fileName,'') This produced a weird file in the archive, which could not be opened.
archive.write(fileName, archive) I really thought this would work, but the system really didn't like it.
archive.write(fileNameWithoutPath) This one returned an error, since Python could no longer find the file.
So how do I specify that I want to put the file in the root directory of the archive and still specify its path so Python can find it?
Minor, and semi-related question: Is there a way to create the new archive such that it is hidden in windows explorer?
I am assuming you want a entry in the zipfile called file containin the contents of C:\Documents\file
From python docs
ZipFile.write(filename[, arcname[, compress_type]])
Write the file named filename to the archive, giving it the archive name arcname
so you want
archive.write(fileName, fileNameWithoutPath)
The first argument is the file that goes in the zip and the second is the name that is to be used in the archive, as it contains no path separators it will not create any directories.

Categories