I have a 3GB gz file that I am trying to break into chunks of smaller files which are not required to be gz (I tried to make files of 10000000 lines, this is not a requirement, the chunks could be of any size), but my method is taking ages to run (about 12 minutes). I have the requirement to not use any library such as Pandas, Spark, etc. I can only use pure Python. I tried profiling my code and the write seems to be the slowest thing. Here's my code :
import gzip
import os
class FileSplitter:
def __init__(self):
self.parse_args(sys.argv)
@staticmethod
def run():
splitter = FileSplitter()
#run to split the big file into smaller files
splitter.split()
def split(self):
file_number = 1
line_number = 0
print("Splitting %s into multiple files with %s lines" % (os.path.join(self.working_dir, self.file_base_name), str(self.split_size)))
out_file = self.get_new_file(file_number)
a_file = gzip.open(self.in_file, 'rt')
t = next(a_file)
with a_file as f:
for line in f:
out_file.write(line)
line_number += 1
if line_number == self.split_size:
out_file.close()
file_number += 1
line_number = 1
out_file = self.get_new_file(file_number)
out_file.close()
print("Created %s files." % (str(file_number)))
def get_new_file(self,file_number):
"""return a new file object ready to write to"""
new_file_name = "%s.%s" % (self.file_base_name, str(file_number))
new_file_path = os.path.join(self.working_dir, 'pychunks', new_file_name)
print ("creating file %s" % (new_file_path))
return open(new_file_path, 'w')
def parse_args(self,argv):
"""parse args and set up instance variables"""
try:
self.split_size = 10000000
if len(argv) > 2:
self.split_size = int(argv[2])
self.file_name = argv[1]
self.in_file = self.file_name
self.working_dir = os.getcwd()
self.file_base_name = os.path.basename(self.file_name)
except:
print(self.usage())
sys.exit(1)
def usage(self):
return """
Split a large file into many smaller files with set number of rows.
Usage:
$ python file_splitter.py <file_name> [row_count]
row_count is optional (default is 1000)"""
if __name__ == "__main__":
FileSplitter.run()
To run my code I call a .py file containing this code with the name of my gz file, example : python myprogfile.py test.gz
Would you do that differently? Would you use threading (i tried but I couldn't succeed yet as I don't have experience with that)? What would you change in this code?
I don't know if it is my laptop that's too weak in terms of memory and CPU ...