Source code for FileHandler

from io import BytesIO, SEEK_END
import os
from enum import Enum

[docs]class FileMode(Enum): READONLY = 'r' WRITEONLY = 'w' READWRITE = 'r+' WRITEREAD = 'w+' READBYTES = 'rb' WRITEBYTES = 'wb' READWRITEBYTES = 'r+b' WRITEREADBYTES = 'w+b' APPENDONLY = 'a' APPENDANDREAD = 'a+' APPENDBYTES = 'ab' APPENDREADBYTES = 'a+b'
# Class to ease the process of handling files.
[docs]class FileHandler: # Class constructor # file_path: Path to a file. # file_mode: FileMode that determines the way we are accessing the file. # create: If set to True, will create any directories not existing in the specified file path recursively. # If create is set to False, the file and every subdirectory must exist. def __init__(self, file_path: str, file_mode: FileMode = FileMode.READWRITEBYTES, create: bool = False): try: if file_path is None: raise BadFilePathException(f"file_path was set to None type") if file_path == "": raise BadFilePathException(f"file_path string was empty") self.path = os.path.normpath(os.path.dirname(file_path)) self.fullfilename = os.path.basename(file_path) self.filename = os.path.splitext(self.fullfilename)[0] self.extension = os.path.splitext(self.fullfilename)[1][1:] if not create: if not os.path.exists(file_path): raise FileNotFoundException(f"The file handler could not find the specified file: {file_path}") if not os.path.isfile(file_path): raise NotAFileException(f"Attempting to open something that is not a file: {file_path}") if not os.access(os.path.dirname(file_path), os.R_OK): raise DirectoryLockedException(f"Could not access some of the firectories in {os.path.dirname} (Permission denied)") if not os.access(file_path, os.F_OK): raise FileLockedException(f"Could not access {file_path} (Permission denied)") else: path_tree = self.path.split(os.sep) curpath = "" for path in path_tree: curpath += path + os.sep if not os.path.exists(curpath): os.mkdir(curpath) else: if not os.access(curpath, os.W_OK): raise DirectoryLockedException(f"Could not access {curpath} (Permission denied)") if not os.path.exists(os.path.dirname(file_path)): os.mkdir(os.path.dirname(file_path)) self.file = open(file_path, file_mode.value) self.file_size = self.__get_file_size() self.buffer_size = 512 except Exception as exc: raise exc def __enter__(self): return self
[docs] def setBufferSize(self, bufferSize: int) -> int: self.buffer_size = bufferSize return self.buffer_size
[docs] def read(self, amount: int = None, readonly: bool = True) -> BytesIO or bytearray or None: if self.file is not None: try: if amount is None: amount = self.buffer_size buf_in = None if readonly: buf_in = BytesIO() else: buf_in = bytearray(amount) buf_in = self.file.read(amount) return buf_in except Exception as exc: raise exc else: return None
[docs] def readandrewind(self, amount: int = None, readonly: bool = True) -> BytesIO or bytearray or None: if self.file is not None: try: if amount is None: amount = self.buffer_size buf_in = None if readonly: buf_in = BytesIO() else: buf_in = bytearray(amount) buf_in = self.file.read(amount) self.rewind() return buf_in except Exception as exc: raise exc else: return None
[docs] def write(self, buffer_out: BytesIO or bytearray) -> int: if self.file is not None: try: w = self.file.write(buffer_out) return w except Exception as exc: raise exc else: return 0
[docs] def zero(self,length: int) -> int: if self.file is not None: try: c = self.file.tell() w = self.file.write(bytearray(length)) self.file.seek(c, 0) return w except Exception as exc: raise exc else: return 0
[docs] def printblock(self, offset: int, length: int): if self.file is not None: try: if length is None: length = self.buffer_size p = self.file.tell() self.file.seek(offset, 0) buf_in = self.file.read(length) self.file.seek(p,0) line = "" for i in range(0, len(buf_in)): line = str(f"{line} {buf_in[i]:02X}") if i % 16 == 0 or i == len(buf_in)-1: print(line) line = "" except Exception as exc: raise exc else: return None
[docs] def seek(self, destination: int, from_offset: int = 0) -> int: if self.file is not None: try: self.file.seek(int(destination), int(from_offset)) p = self.file.tell() return p except Exception as exc: raise exc else: return -1
[docs] def rewind(self) -> bool: if self.file is not None: try: self.file.seek(0) return True if self.file.tell() == 0 else False except Exception as exc: raise exc else: return False
[docs] def seek_end(self) -> bool: if self.file is not None: try: s = self.file.tell() self.file.seek(0, SEEK_END) e = self.file.tell() return True if s < e else False except Exception as exc: raise exc else: return False
def __get_file_size(self) -> int: if self.file is not None: try: self.seek_end() sz = self.file.tell() self.rewind() return sz except Exception as exc: raise exc else: return -1
[docs] def tell(self) -> int: if self.file is not None: try: return self.file.tell() except Exception as exc: raise exc else: return -1
[docs] def close(self) -> bool: if self.file is not None: try: if self.file.closed != True: self.file.close() self.file = None return True except Exception as exc: raise exc else: return False
[docs] def truncate(self, size: int = 0): if self.file is not None: try: return self.file.truncate(size) except Exception as exc: raise exc else: return
def __exit__(self, exc_type, exc_value, traceback): self.close() def __del__(self): self.close()
[docs]class FileHandlerError(Exception): """Generic file handler error""" pass
[docs]class BadFilePathException(FileHandlerError): """Raised when the file path has a wrong format""" pass
[docs]class FileNotFoundException(FileHandlerError): """Raised when the file does not exists""" pass
[docs]class NotAFileException(FileHandlerError): """Raised when attempting to open something that is not a file""" pass
[docs]class FileLockedException(FileHandlerError): """Raised when the FileHandler can not open the file for some reason, mostly due to permission errors or the file being in use""" pass
[docs]class DirectoryLockedException(FileHandlerError): """Raised when the FileHandler does not have access to a directory specified in the file path. Normally this is due to permission errors""" pass