def get_download_sizes_list(self): # no of bytes per thread size_per_thread = self.filesize // ConfigHandler.get_threads(self) # stores size to be downloaded by each thread sizes_list = [size_per_thread] * ConfigHandler.get_threads(self) # remaining size not assigned to any thread rem = self.filesize % ConfigHandler.get_threads(self) # loop to equally assign sizes to download, to each thread index = 0 while rem != 0: sizes_list[index] += 1 rem -= 1 index += 1 return sizes_list
def merge_multithreaded_download_parts(self): # merging parts with open(self.filepath, 'wb') as wfd: for f in range(ConfigHandler.get_threads(self)): tempfilepath = ConfigHandler.get_temp_dir( self) + "/temp" + str(f) with open(tempfilepath, "rb") as fd: shutil.copyfileobj(fd, wfd) # delete copied segment FileHandler.delete_file(self, tempfilepath)
def multithreaded_download(self, ranges_list): # downloading each segment for f in range(ConfigHandler.get_threads(self)): # calling seg_handler() for each thread t = threading.Thread(target=self.seg_handler, kwargs={ 'tempfilepath': ConfigHandler.get_temp_dir(self) + "/temp" + str(f), 'range_left': ranges_list[f][0], 'range_right': ranges_list[f][1] }) t.setDaemon(True) t.start() # except main_thread, calling join() for each thread # it ensures that merging of parts occur only after each thread has completed downloading main_thread = threading.current_thread() for t in threading.enumerate(): if t is main_thread: continue t.join()