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.
Related
in the error output message I have the .json file in a streamed tweets folder. The data exists im not sure what is wrong with my path
import json
import os, os.path
# counter keeps track of the unique tweet ids and is used later when
# prepending the ElasticSearch compatibility
counter = 1
# find all files in folderPath, does not include subdirectories or directories
folderPath = r"c:/Users/Katherine/Downloads/Final Project-.zip/Final
Project/122_finalproject_part2/streamed_tweets";
files = next(os.walk(folderPath))[2]
# filecount is keeps track of how many files are in the streamedtweets folder
filecount = len(files) - 1
print(filecount)
ctr = 0
for ctr in range(filecount):
inFileName = open('streamedtweets/tweet_data_' + str(filecount) + '.json', 'r')
outFileName = open('elastic_data/elastictwitter_data_' + str(filecount) + '.json', 'w')
ERROR
File "add_elastic.py", line 16, in <module>
inFileName = open('streamedtweets/tweet_data_' + str(filecount) + '.json', 'r')
IOError: [Errno 2] No such file or directory: 'streamedtweets/tweet_data_32.json'
You expected tweet_data_ to be appended with 0, 1, 2, 3... but in actuality you're always appending 32 which doesn't seem to exist. A better way would be to loop directly through the files you have instead of guessing its name.
Try doing this instead:
folderPath = r"c:/Users/Katherine/Downloads/Final Project-.zip/Final
Project/122_finalproject_part2/streamed_tweets"
files = next(os.walk(folderPath))[2]
for i, file in enumerate(files):
if file.startswith('tweet_data_') and file.endswith('.json'):
inFileName = open(file, 'r')
outFileName = open('elastic_data/elastictwitter_data_' + str(i) + '.json', 'w')
And even better way would be to use the with statement to manage your files opening and closing:
for i, file in enumerate(files):
if file.startswith('tweet_data_') and file.endswith('.json'):
with open(file, 'r') as inFileName, open('elastic_data/elastictwitter_data_' + str(i) + '.json', 'w') as outFileName:
# do something with inFileName / outFileName
Just getting back into Python and am trying to build a script that will match file names, rename, zip them, and then ultimately build a control file off them (this I haven't written yet). It works on the files placed in the directory, but at the end I get the error: FileNotFoundError: [WinError 2] The system cannot find the file specified: 'A20190331.txt' -> 'B20190530.txt'. Is it rerunning my txt_files for loop in the beginning after renaming? Code is probably not optimal at this point.
import os
import zipfile
try:
import zlib
compression = zipfile.ZIP_DEFLATED
except:
compression = zipfile.ZIP_STORED
path = 'mypath'
txt_files = []
for root, dirs, files in os.walk(path):
for file in files:
txt_files.append(file)
def create_zip(data_dt):
for files in txt_files:
if '.py' in files:
continue
elif 'A' in files:
file_name = 'A' + data_dt + '.txt'
name_full_path = path +'\\'+ file_name
os.rename(files, file_name)
zf = zipfile.ZipFile('A' + data_dt+ '.zip', mode='w')
zf.write(name_full_path, file_name, compress_type=compression)
zf.close()
elif 'B' or 'C' in files:
file_name = 'B' + data_dt + '.txt'
name_full_path = path +'\\'+ file_name
os.rename(files, file_name)
zf = zipfile.ZipFile('B' + data_dt +'.zip', mode='w')
zf.write(name_full_path, file_name, compress_type=compression)
zf.close()
else:
break
create_zip('20190530')
Christopher.
I see your problem immediately:
txt_files = []
for root, dirs, files in os.walk(path):
for file in files:
txt_files.append(file)
I believe you want to keep the path:
for root, dirs, files in os.walk(path):
for file in files:
txt_files.append(os.path.join(os.path.get_cwd(), file))
Let os.path handle the path for you -- it is portable across platforms and less error prone.
hth
i did some modification, can you try this please , but using your way, the code will overwrite the files.
so try this script, and tell me if you want to overwrite or just rename and zip
def create_zipe(data_dt):
for files in txt_files:
if '.py' in files:
continue
elif 'ASS' in files:
file_name = 'A' + data_dt + '.txt'
name_full_path = path +'/'+ file_name
os.rename(files, file_name)
zf = zipfile.ZipFile('A' + data_dt+ '.zip', mode='w')
zf.write(name_full_path, file_name, compress_type=compression)
zf.close()
elif 'C' in files or 'B' in files:
file_name = 'B' + data_dt + '.txt'
print(file_name)
name_full_path = path +'/'+ file_name
print(name_full_path)
os.rename(files, file_name)
zf = zipfile.ZipFile('B' + data_dt+ '.zip', mode='w')
zf.write(name_full_path, file_name, compress_type=compression)
zf.close()
There are text files of various names in the folder 'a'. I want to read all of these text files and add the letter 'b' to each text file. What should I do?
cwd = os.getcwd()
input_dir = os.path.join(cwd, "my .txt files dir")
sorts = sorted(glob(input_dir), key = lambda x:(len(x) , x))
for f in sorts :
f = open(input_dir, 'a')
data = "add text"
f.write(data)
f.close()
Append data to file:
- first: get all file in folder a.
- second: find extension with .txt.
- third: open it and do something('append', or 'rewrite').
Demo:
import os
# your .txt files dir
path = 'a'
# append data what you want
appendData = 'b'
fileNames = list(os.walk(path))[0][2]
fileNames.sort(key=len)
fileNums = len(fileNames)
# your dst file extension
fileExt = '.txt'
# # Extract extension from filename
# fileExt = os.path.splitext(fileNames[0])[1]
for fileName in fileNames:
if fileName.endswith(fileExt):
fileFullPath = os.path.join(path, fileName)
with open(fileFullPath, 'a') as f:
f.write(appendData)
Like the others said, this is an easy question that could easily be find on google. Anyway here's how to do it:
from os import listdir
from os.path import isfile, isdir, join
files = [file for file in listdir("files") if isfile(join("files", file))]
directories = [directory for directory in listdir("files") if isdir(join("files", directory))]
print(files)
for file_name in files:
try:
file = open("files/" + file_name, "a")
file.write("b")
file.close()
except IOError as err:
print("Could not open file because : ", err)
Replace "file" with the directory where your files are or the path to that directory like "directory0/directory1/directory_with_files"
Avoid to open files with
f = open(input_dir, 'a')
f.close()
Instead
with open(input_dir, 'a') as inputFile:
Do something
Also what you want is
import os
import glob # We will use this module to open only .txt files
path = 'your/path'
for filename in glob.glob(os.path.join(path, '*.txt'))
with open(filename, 'a') as inputFile:
inputFile.write('b')
Using python how can I combine all the text file in the specified directory into one text file and rename the output text file with the same filename.
For example: Filea.txt and Fileb_2.txt is in root directory, and it output generated file is Filea_Fileb_2.txt
Filea.txt
123123
21321
Fileb_2.txt
2344
23432
Filea_Fileb_2.txt
123123
21321
2344
23432
my script:
PWD1 = /home/jenkins/workspace
files = glob.glob(PWD1 + '/' + '*.txt')
with open(f, 'r') as file:
for line in (file):
outputfile = open('outputfile.txt', 'a')
outputfile.write(line)
outputfile.close()
Here's another way to combine text files.
#! python3
from pathlib import Path
import glob
folder_File1 = r"C:\Users\Public\Documents\Python\CombineFIles"
txt_only = r"\*.txt"
files_File1 = glob.glob(f'{folder_File1}{txt_only}')
new_txt = f'{folder_File1}\\newtxt.txt'
newFile = []
for indx, file in enumerate(files_File1):
if file == new_txt:
pass
else:
contents = Path(file).read_text()
newFile.append(contents)
file = open(new_txt, 'w')
file.write("\n".join(newFile))
file.close()
This is a working solution which stores both file names and file contents in a list, then joins the list filenames and creates a "combined" filename and then adds the contents of all the files to it, because lists append in order that the data is read this is sufficient (my example filenames are filea.txt and fileb.txt but it will work for the filenames you've used):
import os
import sys
path = sys.argv[1]
files = []
contents = []
for f in os.listdir(path):
if f.endswith('.txt'): # in case there are other file types in there
files.append(str(f.replace('.txt', ''))) #chops off txt so we can join later
with open(f) as cat:
for line in cat:
contents.append(line) # put file contents in list
outfile_name = '_'.join(x for x in files)+'.txt' #create your output filename
outfile = open(outfile_name, 'w')
for line in contents:
outfile.write(line)
outfile.close()
to run this on a specific directory just pass it on the commandline:
$python3.6 catter.py /path/to/my_text_files/
output filename:
filea_fileb.txt
contents:
123123
21321
2344
23432
I have a folder with a list of files without extensions, I need to rename or create an extension to each file ".text"
This is my code, but there is a small bug, the second time I run the code the files renamed again with a long name ,, for example
The file name : XXA
after first run : XXA.text
second : XXAXXA.text.text
import os
def renamefiles():
filelist = os.listdir(r"D:\")
print(filelist)
os.chdir(r"D:\")
path = os.getcwd()
for filename in filelist:
print("Old Name - "+filename)
(prefix, sep, sffix) = filename.rpartition(".")
newfile = prefix + filename + '.text'
os.rename(filename, newfile)
print("New Name - "+newfile)
os.chdir(path)
rename_files()
Where you have
newfile = prefix + '.text'
You can have
if not file_name.contains(".text"):
newfile = prefix + file_name + '.text'
Note where you have newfile = prefix + file_name + '.text', I changed it to newfile = prefix + '.text'. If you think about it, you don't need filename when you have already extracted the actual file name into prefix.
for file in os.listdir(os.curdir):
name, ext = os.path.splitext(file)
os.rename(file, name + ".text")
Don't do the partitioning that way, use os.path.splitext:
file_name, extension = os.path.splitext(filename)
if not extension:
newfile = file_name + '.text'
os.rename(filename, newfile)
If the file has no extension splitext returns '' which is Falsy. The file extension can then be changed.
import os
def renamefiles():
filelist = os.listdir(r"D:\")
print(filelist)
os.chdir(r"D:\")
path = os.getcwd()
for filename in filelist:
print("Old Name - "+filename)
(prefix, sep, sffix) = filename.rpartition(".")
newfile = prefix + filename + '.text'
if not filename.endswith(".text"):
os.rename(filename, newfile)
print("New Name - "+newfile)
os.chdir(path)
renamefiles()
You need to check if the filename ends with .text, and skip those