{"record":{"id":"a29aed0f98caeea8","repo":"shwenzhang/AndResGuard","slug":"directoryexception","errorCode":null,"errorMessage":"DirectoryException","messagePattern":"DirectoryException","errorType":"exception","errorClass":"DirectoryException","httpStatus":null,"severity":"error","filePath":"AndResGuard-core/src/main/java/com/tencent/mm/directory/FileDirectory.java","lineNumber":53,"sourceCode":"    if (!dir.isDirectory()) {\n      throw new DirectoryException(\"file must be a directory: \" + dir);\n    }\n    mDir = dir;\n  }\n\n  @Override\n  protected AbstractDirectory createDirLocal(String name) throws DirectoryException {\n    File dir = new File(generatePath(name));\n    dir.mkdir();\n    return new FileDirectory(dir);\n  }\n\n  @Override\n  protected InputStream getFileInputLocal(String name) throws DirectoryException {\n    try {\n      return new FileInputStream(generatePath(name));\n    } catch (FileNotFoundException e) {\n      throw new DirectoryException(e);\n    }\n  }\n\n  @Override\n  protected OutputStream getFileOutputLocal(String name) throws DirectoryException {\n    try {\n      return new FileOutputStream(generatePath(name));\n    } catch (FileNotFoundException e) {\n      throw new DirectoryException(e);\n    }\n  }\n\n  @Override\n  protected void loadDirs() {\n    loadAll();\n  }\n\n  @Override","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/shwenzhang/AndResGuard/blob/e4df245d82f27d9a2d0dd108260a3510cbaba849/AndResGuard-core/src/main/java/com/tencent/mm/directory/FileDirectory.java#L35-L71","documentation":"FileDirectory.getFileInputLocal wraps a java.io.FileNotFoundException thrown by new FileInputStream(...) into a DirectoryException. It means the named entry could not be opened for reading inside this on-disk directory.","triggerScenarios":"Calling getFileInput(name) on a FileDirectory for a name that does not map to an existing file on disk, or the file was deleted between listing and reading.","commonSituations":"Reading a resource entry that a prior obfuscation step renamed or removed; name mismatch after mapping changes; TOCTOU races in build pipelines.","solutions":["Verify the file exists before reading: containsFile(name) or new File(dir, name).exists().","Catch DirectoryException and inspect the cause (FileNotFoundException) to fall back to a default resource.","Re-list the directory (loadDirs) to get current valid names instead of using cached names."],"exampleFix":"// before\nInputStream in = fileDir.getFileInput(\"res/values/strings.xml\");\n// after\nif (fileDir.containsFile(\"res/values/strings.xml\")) {\n  InputStream in = fileDir.getFileInput(\"res/values/strings.xml\");\n} else {\n  throw new IOException(\"missing resource: res/values/strings.xml\");\n}","handlingStrategy":"try-catch","validationCode":"if (!fileDir.containsFile(name)) { /* skip or default */ }","typeGuard":null,"tryCatchPattern":"try { return fileDir.getFileInput(name); } catch (DirectoryException e) { if (e.getCause() instanceof FileNotFoundException) return null; throw e; }","preventionTips":["Refresh directory listings before reading (entries may have changed)","Use containsFile for optional resources","Catch and unwrap the cause FileNotFoundException for clearer diagnostics"],"tags":["io","file-read","wrapped-exception"],"backgroundTag":"file-not-found","analyzedSha":"e4df245d82f27d9a2d0dd108260a3510cbaba849","analyzedAt":"2026-09-12T17:49:07.798Z","contentChangedAt":"2026-09-12T17:49:07.798Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}