588. Design In Memory File System - cocoder39/coco39_LC GitHub Wiki

588. Design In-Memory File System

capabilities to demonstrate:

  • able to use data structure to model real world problem
  • clarify requirements. EG. if file/directory not exists, should ls create file or throw exception

First idea was using a trie-like data structure EG, each node has a field telling it is a file or directory. Modeling file and directory separately makes the code easy to write and understand.

class Directory:
    def __init__(self):
        self.files = collections.defaultdict(str) # file name -> file content
        self.subDirectories = collections.defaultdict(Directory) # sub directory name -> sub directory

class FileSystem:

    def __init__(self):
        self.root = Directory()
        
    def ls(self, path: str) -> List[str]:
        strs = path.split('/')
        curDirectory = self.root
        for i, name in enumerate(strs):
            # skip root directory and '/' appended to deeppest directory
            if name == '': 
                continue
            if i == len(strs)-1 and name in curDirectory.files:
                return [name]
            elif name in curDirectory.subDirectories:
                curDirectory = curDirectory.subDirectories[name]
            else:
                raise Exception("No such file or directory")
                
        fileNames = list(curDirectory.files.keys())
        subDirectoryNames = list(curDirectory.subDirectories.keys())
        return sorted(fileNames + subDirectoryNames)
        
    def mkdir(self, path: str) -> None:
        strs = path.split('/')
        curDirectory = self.root
        for name in strs:
            # skip root directory or '/' appended to the deeppest directory
            if name == '': 
                continue
            curDirectory = curDirectory.subDirectories[name]
        
    def addContentToFile(self, filePath: str, content: str) -> None:
        strs = filePath.split('/')
        curDirectory = self.root
        for i, name in enumerate(strs):
            # skip root directory or '/' appended to the deeppest directory
            if name == '': 
                continue
            if i == len(strs) - 1:
                curDirectory.files[name] += content
                return
            curDirectory = curDirectory.subDirectories[name]
            
    def readContentFromFile(self, filePath: str) -> str:
        strs = filePath.split('/')
        curDirectory = self.root
        for i, name in enumerate(strs):
            # skip root directory or '/' appended to the deeppest directory
            if name == '': 
                continue
            if i == len(strs) - 1:
                return curDirectory.files[name]
            curDirectory = curDirectory.subDirectories[name]