588. Design In-Memory File System

class FileSystem {

    
    public List<String> ls(String path) { // find to path, if there is a sons
        
        List<String> result = new ArrayList<>();
        
        TrieNode node = findPath(path);
        if (node.isFile) {
            result.add(node.fileName);
        } else {
            result.addAll(node.sons.keySet());
        }
        Collections.sort(result);
        return result;
    }
    
    
    public void mkdir(String path) { // build trie
        findPath(path);
    }
    
    public void addContentToFile(String filePath, String content) { //If filePath does not exist, creates that file containing given content.
        TrieNode node = findPath(filePath);
        node.isFile = true;
        node.content += content;
    }
    
    public String readContentFromFile(String filePath) {
        TrieNode node = findPath(filePath);
        return node.content;
    }
    
    // --------use trie to build file nodes
    class TrieNode {
        Map<String, TrieNode> sons;
        boolean isFile;
        String content;
        String fileName;
        TrieNode(String name) {
            this.sons = new HashMap<>();
            this.content = "";
            this.fileName = name;
        }
    }
    
    TrieNode root;
    public FileSystem() {
        root = new TrieNode("");
    }
    
    private TrieNode findPath(String path) {
        String[] dirs = path.split("/");
        TrieNode node = root;
        for (String dir : dirs) {
            // System.out.println("[" + dir+"]");
            if (dir.length() == 0) { // key point, dir maybe ""
                continue;
            }
            node.sons.putIfAbsent(dir, new TrieNode(dir));
            node = node.sons.get(dir);
        }
        return node;
    }
}

/**
 * Your FileSystem object will be instantiated and called as such:
 * FileSystem obj = new FileSystem();
 * List<String> param_1 = obj.ls(path);
 * obj.mkdir(path);
 * obj.addContentToFile(filePath,content);
 * String param_4 = obj.readContentFromFile(filePath);
 
 if use trie
 
        mkdir
        
        axy
       /
      bxx
      /
     cqq
     /
     d "hello"



the same names will not exist in the same directory.
     
You can assume that all operations will be passed valid parameters, and users will not attempt to retrieve file content or list a directory or file that does not exist.
 */

new version

```java
class FileSystem {

    class File {
        Map<String, File> children;
        boolean isDir;
        String fileName;
        String content;
        File(boolean isDir, String fileName, String content) {
            children = new HashMap<>();
            this.isDir = isDir;
            this.fileName = fileName;
            this.content = content;
        }
    }
    //private Map<String, File> fileSystem;
    private File root;
    public FileSystem() {
        //fileSystem = new HashMap<>();
        root = new File(true, "", "");
    }
    
    public List<String> ls(String path) {
        List<String> result = new ArrayList<>();
        File node = buildOrfindFileNode(path, true);
        if (!node.isDir) {
            result.add(node.fileName);
        } else {
            result.addAll(node.children.keySet());
        }
        Collections.sort(result); //for lexicographic order
        return result;
    }
    private File buildOrfindFileNode(String path, boolean isDir) {
        File node = root;
        String[] paths = path.split("/");
        for (String p : paths) {
            if ("".equals(p)) {
                continue;
            }
            String fileName = "";
            if (!isDir) {
                fileName = p;
            }
            node.children.putIfAbsent(p, new File(isDir, fileName, "")); 
            node = node.children.get(p);
        }
        return node;
    }
    
    public void mkdir(String path) {
        buildOrfindFileNode(path, true);
    }
    
    public void addContentToFile(String filePath, String content) {
        File node = buildOrfindFileNode(filePath, false);
        node.content += content; // content is appending
    }
    
    public String readContentFromFile(String filePath) {
        File node = buildOrfindFileNode(filePath, false);
        if (!node.isDir) {
            return node.content;
        }
        return "";
    }
}


/**
File {
    Map<String, File>
    isDir;
    String content;
}
Map<String, File>>>


a<b<c isDir = true>>
 */

/**
 * Your FileSystem object will be instantiated and called as such:
 * FileSystem obj = new FileSystem();
 * List<String> param_1 = obj.ls(path);
 * obj.mkdir(path);
 * obj.addContentToFile(filePath,content);
 * String param_4 = obj.readContentFromFile(filePath);
 */
```

Last updated