I have a program that creates a zip file containing a couple of files using zipfile. It takes an output filename as argument, but if no file or - is given, it should write to STDOUT. But if I pass sys.stdout as file parameter to ZipFile, it gives me the following error:
File "/usr/lib/python2.7/zipfile.py", line 775, in __init__
self._start_disk = self.fp.tell()
IOError: [Errno 29] Illegal seek
Here's my code:
import zipfile, sys
def myopen(name, mode='r'):
if name is not None:
try: return open(name, mode)
except EnvironmentError as e:
print >> sys.stderr, '%s: %s' % (name, e.strerror)
sys.exit(3)
elif mode == 'r': return sys.stdin
elif mode in 'aw': return sys.stdout
else: return None
outfile = None
# build the files ...
files = {'file1': 'Here is an example file.\n', 'file2': 'Some more ...'}
with myopen(outfile, 'w') as f, zipfile.ZipFile(f, 'w', zipfile.ZIP_DEFLATED, True) as zf:
for name, content in files.iteritems(): zf.writestr(name, content)
How can I make this work?
Related
I'm trying to create a .csv file and then create a .gz file with the previous csv inside. The problem is that the .gz file is created with a file with the correct file name but without the .csv extension and I don't know how to solve it.
This is the relevant code:
new_file_name = 'test'
data = [['some','test'],['data','strings']]
csv_fname = '%s.csv' % new_file_name
tar_fname = '%s.gz' % new_file_name
with open(csv_fname, 'wb') as csvfile:
swriter = csv.writer(csvfile)
for row in data:
swriter.writerow(row)
print 'creating archive'
out = tarfile.open(tar_fname, 'w:gz')
try:
print 'adding %s' % csv_fname
out.add(csv_fname)
finally:
print 'closing'
out.close()
When I run this script in cmd (as admin) I get this error. When I run the same script against the same set of files in PowerShell it works fine with no errors. The file it's failing on doesn't have an illegal character.
C:\Windows\system32>python D:\Syncback\OurDocs\Darrick\MyPrograms\dbhf.py "C:\Us
ers\Darrick\Dropbox\Camera Uploads" "F:\Pictures\AndroidPics\Auto\"
looking for old files...
2015-06-05 15.33.18.jpg
moving C:\Users\Darrick\Dropbox\Camera Uploads\2015-06-05 15.33.18.jpg
Traceback (most recent call last):
File "D:\Syncback\OurDocs\Darrick\MyPrograms\dbhf.py", line 29, in <module>
shutil.move(filepath, destPath)
File "C:\Python27\lib\shutil.py", line 299, in move
copy2(src, real_dst)
File "C:\Python27\lib\shutil.py", line 128, in copy2
copyfile(src, dst)
File "C:\Python27\lib\shutil.py", line 83, in copyfile
with open(dst, 'wb') as fdst:
IOError: [Errno 22] invalid mode ('wb') or filename: 'F:\\Pictures\\AndroidPics\
\Auto"'
The script is pretty simple:
dropboxPath = sys.argv[1]
destPath = sys.argv[2]
while True:
bufferTime = time.time() - 6000
files = [(f) for f in os.listdir(dropboxPath) for t in filetypes if t in f]
print 'looking for old files...'
for fn in files:
print fn
filepath = dropboxPath+"\\"+fn
if os.path.isfile(filepath):
if os.stat(filepath).st_mtime < bufferTime:
print "moving "+filepath
shutil.move(filepath, destPath)
print "...Going to sleep for 100 minutes now"
time.sleep(6000)
You need to append the file's original name after the destPath
import os.path
dropboxPath = sys.argv[1]
destPath = sys.argv[2]
while True:
bufferTime = time.time() - 6000
files = [(f) for f in os.listdir(dropboxPath) for t in filetypes if t in f]
print 'looking for old files...'
for fn in files:
print fn
filepath = dropboxPath+"\\"+fn
if os.path.isfile(filepath):
if os.stat(filepath).st_mtime < bufferTime:
print "moving "+filepath
shutil.move(filepath, destPath + fn)
print "...Going to sleep for 100 minutes now"
time.sleep(6000)
I have a piece of code which runs well in Python 2.7.5 but doesn't work with Python 3.
The major problem is tee.write, which can not write to the file.
This piece of code suppose to write 20 letters a into the file /tmp/tee-test-1 and /tmp/tee-test-2 but it does not, the two files are empty…
Could any one give me some advice?
import sys
import os
import subprocess
#from netsa.util.shell import *
from string import Template
__author__ = 'Brandon Sandrowicz <brandon#sandrowicz.org>'
__version__ = '0.1'
valid_modes = ['a','w']
def create_tee(files, mode, buffer_size=128):
if mode not in valid_modes:
raise IOError("Only valid modes to create_tee() are: %s" % ', '.join(valid_modes))
tee_list = []
for file in files:
if type(file) == str:
fp = open(file, mode)
tee_list.append(fp)
else:
tee_list.append(file)
pipe_read, pipe_write = os.pipe()
pid = os.fork()
if pid == 0:
# Child -- Read bytes from the pipe and write them to the specified
# files.
try:
# Close parent's end of the pipe
os.close(pipe_write)
bytes = os.read(pipe_read, buffer_size)
print (bytes)
while(bytes):
for file in tee_list:
file.write(bytes)
file.flush()
# TODO maybe add in fsync() here if the fileno() method
# exists on file
bytes = os.read(pipe_read, buffer_size)
except:
pass
finally:
os._exit(255)
else:
# Parent -- Return a file object wrapper around the pipe to the
# child.
return os.fdopen(pipe_write,'w')
if __name__ == '__main__':
files = [ '/tmp/tee-test-1', '/tmp/tee-test-2' ]
num_chars = 100000
print("Writing %d chars to files (using create_tee):" % num_chars)
for file in files:
print(" %s" % file)
print()
tee = create_tee(files,mode='a')
#print("a" * num_chars, end=' ', file=tee)
tee.write("a" * 20)
tee.close()
os.wait()
for filename in files:
with open(filename, 'r') as fh:
chars = len(fh.read())
print("File '%s' has %d chars" % (filename, chars))
ok, I found that problem interesting and challenging, and finally found out what's wrong, it's said in that document:
One common problem is that the file is opened in the wrong mode. Make sure you open text files with the 't' flag and binary files with the 'b' flag and you have solved many problems.
so as you're writing data as b"" datatype, I tried the following:
for file in files:
if type(file) == str:
fp = open(file, mode+'b')
tee_list.append(fp)
else:
tee_list.append(file)
and it works well:
File '/tmp/tee-test-1' has 20 chars
File '/tmp/tee-test-2' has 20 chars
When I create a zip file and try to open it in the same python code, why do I get BadZipFile error?
zip_file = "C:/Temp/tst_data_1022.txt"
filePath, fileName = os.path.split(zip_file)
baseFileName, fileExt = os.path.splitext(fileName)
destFtpFile = filePath + "/" + baseFileName + ".zip"
# Create the zip file and write to it
zFile = zipfile.ZipFile(destFtpFile, 'w', compression=zipfile.ZIP_DEFLATED, allowZip64=True)
zFile.write(zip_file, arcname=fileName)
# Read Zip file
zfile = zipfile.ZipFile(destFtpFile, 'r')
for name in zfile.namelist():
(dirname, filename) = os.path.split(name)
print "Decompressing " + filename
filename = "C:/Temp/" + filename
fd = open(filename,"w")
fd.write(zfile.read(name))
fd.close()
The zip file is created correctly.
Error during reading:
BadZipfile: File is not a zip file
Thanks,
You are missing a call to zFile.close(), which will flush the remaining data that needs to be written to the zip file, and close the underlying file descriptor.
i wrote a small app that downloads a zip file (with a different extension) when provided by a link and extracts the file to a renamed folder.
For some reason its working for some of my zip files, but not for all of them.
I get a :
Traceback (most recent call last):
File "download_unzip.py", line 48, in <module>
main()
File "download_unzip.py", line 42, in main
shutil.move(unzip_file(temp_kmz),'temp_extracted/')
File "download_unzip.py", line 26, in unzip_file
fd = open(name, 'w')
IOError: [Errno 2] No such file or directory: 'models/model.dae'
My code is :
import sys , urllib , zipfile , os.path , argparse , shutil
parser = argparse.ArgumentParser(description="Download and Unzip")
parser.add_argument('url', help='The action to take (e.g. install, remove, etc.)')
args = parser.parse_args()
print args.url
url = args.url
temp_kmz="temp_kmz"
def unzip_file(path):
zfile = zipfile.ZipFile(path)
extracted_filename = zfile.infolist()[0].filename[:-1]
for name in zfile.namelist():
(dirname, filename) = os.path.split(name)
#print "Decompressing " + filename + " on " + dirname
if filename == '':
# directory
if not os.path.exists(dirname):
os.mkdir(dirname)
else:
# file
fd = open(name, 'w')
fd.write(zfile.read(name))
fd.close()
zfile.close()
return extracted_filename
def download_file():
urllib.urlretrieve (url, temp_kmz)
return True
def main():
if (download_file()):
print "Now deleting temp..."
shutil.rmtree('temp_extracted/')
print "unzipping.. and renaming folder"
shutil.move(unzip_file(temp_kmz),'temp_extracted/')
print "Finished!!"
else:
print "Error downloading file"
main()
my working downloaded file:
python download_unzip.py "http://dl.dropbox.com/u/2971439/dae.kmz"
The one that is not working:
python download_unzip.py
"http://dl.dropbox.com/u/2971439/rally_car_youbeq.kmz"
Please note that both files extract properly with my OS (Ubuntu)
fixed my problem with some heavy code changes:
import urllib2 ,argparse, shutil, urlparse , os , zipfile, os.path
from zipfile import ZipFile as zip
parser = argparse.ArgumentParser(description="Download and Unzip")
parser.add_argument('url', help='The action to take (e.g. install, remove, etc.)')
args = parser.parse_args()
print args.url
url = args.url
temp_kmz="temp_kmz"
def extractAll(zipName):
z = zip(zipName)
for f in z.namelist():
if f.endswith('/'):
os.makedirs(f)
else:
z.extract(f)
def download(url, fileName=None):
def getFileName(url,openUrl):
if 'Content-Disposition' in openUrl.info():
# If the response has Content-Disposition, try to get filename from it
cd = dict(map(
lambda x: x.strip().split('=') if '=' in x else (x.strip(),''),
openUrl.info()['Content-Disposition'].split(';')))
if 'filename' in cd:
filename = cd['filename'].strip("\"'")
if filename: return filename
# if no filename was found above, parse it out of the final URL.
return os.path.basename(urlparse.urlsplit(openUrl.url)[2])
r = urllib2.urlopen(urllib2.Request(url))
try:
fileName = fileName or getFileName(url,r)
with open(fileName, 'wb') as f:
shutil.copyfileobj(r,f)
finally:
r.close()
def main():
download(url,temp_kmz)
extractAll(temp_kmz)
main()