# file-system **Repository Path**: MineLX/file-system ## Basic Information - **Project Name**: file-system - **Description**: easier, more natural and functional api for general filesystems interacting. - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-09-28 - **Last Updated**: 2026-04-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # File System [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0) [![Java](https://img.shields.io/badge/java-8+-orange.svg)](https://www.oracle.com/java/) 一个更简单、更自然、更功能化的通用文件系统交互 API。 ## ✨ 特性 - 🎯 **链式调用** - 流畅的 API 设计,让路径导航和资源定位变得极其简单 - 🔧 **OpenPolicy 策略模式** - 统一的访问控制策略,适用于所有文件和目录操作 - 🛡️ **类型安全** - 明确区分 File、Directory 和 Path,编译期即可发现错误 - 🔄 **自动资源管理** - TempPath 实现 AutoCloseable,确保临时文件自动清理 - 🌐 **可扩展架构** - 支持多种文件系统后端,轻松扩展自定义文件系统 ## 🚀 快速开始 ### Maven 依赖 ```xml io.gitee.minelx file-system 1.0.1 ``` ### 基础示例 ```java import io.gitee.minelx.filesystem.*; import io.gitee.minelx.filesystem.init.OpenPolicy; import io.gitee.minelx.filesystem.provider.FS; import java.nio.charset.StandardCharsets; // 简单的文件读写 Directory root = FS.workingDir() .child().dir("data", OpenPolicy.CREATE_IF_NOT_EXISTED); File file = root.child().file("hello.txt", OpenPolicy.CREATE_IF_NOT_EXISTED); file.write("Hello, World!", StandardCharsets.UTF_8); String content = file.read(StandardCharsets.UTF_8); System.out.println(content); // 输出: Hello, World! ``` ## 🎯 核心设计理念 ### 1. 链式调用 - 让路径导航如丝般顺滑 传统的文件操作需要拼接路径字符串,容易出错且难以阅读。File System 通过 **Locator** 和 **链式调用** 让路径导航变得直观优雅: ```java // ❌ 传统方式 - 路径拼接易出错 String path = "/home/user/projects/myapp/config/database.yml"; File file = new File(path); // ✅ File System 方式 - 清晰的链式调用 File configFile = FS.workingDir() .child().dir("home", OpenPolicy.EXISTS) .child().dir("user", OpenPolicy.EXISTS) .child().dir("projects", OpenPolicy.EXISTS) .child().dir("myapp", OpenPolicy.EXISTS) .child().dir("config", OpenPolicy.EXISTS) .child().file("database.yml", OpenPolicy.CREATE_IF_NOT_EXISTED); ``` **链式调用的优势:** - 📖 **可读性强** - 每一步操作都清晰可见 - 🔍 **易于调试** - 可以在任何环节断点检查 - 🛠️ **灵活组合** - 轻松构建复杂的路径逻辑 - ⚡ **IDE 友好** - 完整的代码提示和自动补全 更多链式调用示例: ```java // 目录遍历和处理 FS.workingDir() .child().dir("logs", OpenPolicy.EXISTS) .children() .filter(path -> path.name().endsWith(".log")) .forEach(path -> { System.out.println("找到日志文件: " + path.name()); }); // 快速定位深层资源 Directory deepDir = FS.local() .dir("var", OpenPolicy.EXISTS) .child().dir("lib", OpenPolicy.EXISTS) .child().dir("docker", OpenPolicy.EXISTS); // 路径导航 Path currentPath = file.path(); Path siblingPath = currentPath.sibling("backup.txt"); // 兄弟文件 Directory parentDir = currentPath.container(); // 父目录 Path renamedPath = currentPath.rename("new_name.txt"); // 重命名 ``` ### 2. OpenPolicy - 一套策略,处处适用 **OpenPolicy** 是 File System 的核心创新之一。它提供统一的访问控制策略,适用于所有文件和目录操作,让你能够精确控制资源的打开行为: ```java public enum OpenPolicy { EXISTS, // 要求资源必须存在且类型匹配 CREATE, // 创建新资源(已存在则报错) CREATE_IF_NOT_EXISTED, // 不存在则创建,存在则验证类型 __ // 无检查(自由模式) } ``` #### 策略详解 **EXISTS** - 严格模式,确保资源已存在 ```java // 读取配置文件,如果不存在立即失败 File config = dir.child().file("config.json", OpenPolicy.EXISTS); String content = config.read(StandardCharsets.UTF_8); // 打开已有目录 Directory logs = dir.child().dir("logs", OpenPolicy.EXISTS); ``` **CREATE** - 创建模式,确保资源是新创建的 ```java // 创建新文件,如果已存在会抛出异常(防止意外覆盖) File newFile = dir.child().file("report.txt", OpenPolicy.CREATE); newFile.write("报告内容", StandardCharsets.UTF_8); // 创建新目录 Directory output = dir.child().dir("output", OpenPolicy.CREATE); ``` **CREATE_IF_NOT_EXISTED** - 智能模式,最常用 ```java // 最常用的策略:不存在就创建,存在就验证类型 File dataFile = dir.child().file("data.json", OpenPolicy.CREATE_IF_NOT_EXISTED); Directory cacheDir = dir.child().dir("cache", OpenPolicy.CREATE_IF_NOT_EXISTED); // 适合初始化场景 Directory appDir = FS.workingDir() .child().dir("myapp", OpenPolicy.CREATE_IF_NOT_EXISTED) .child().dir("config", OpenPolicy.CREATE_IF_NOT_EXISTED); ``` **__** - 自由模式,不做任何检查 ```java // 用于特殊场景,完全由开发者控制 Path anyPath = dir.child().path("anything", OpenPolicy.__); ``` #### OpenPolicy 的通用性 **所有资源操作都使用相同的策略接口**,无论是文件还是目录: ```java // ✅ 文件操作 File file1 = dir.child().file("a.txt", OpenPolicy.CREATE_IF_NOT_EXISTED); File file2 = dir.child().file("b.txt", OpenPolicy.EXISTS); File file3 = dir.child().file("c.txt", OpenPolicy.CREATE); // ✅ 目录操作 - 使用完全相同的策略 Directory dir1 = dir.child().dir("folder1", OpenPolicy.CREATE_IF_NOT_EXISTED); Directory dir2 = dir.child().dir("folder2", OpenPolicy.EXISTS); Directory dir3 = dir.child().dir("folder3", OpenPolicy.CREATE); // ✅ Locator 统一接口 Locator locator = dir.child(); File f = locator.file("test.txt", OpenPolicy.CREATE_IF_NOT_EXISTED); Directory d = locator.dir("test_dir", OpenPolicy.CREATE_IF_NOT_EXISTED); ``` **策略带来的好处:** - 🎯 **一致性** - 文件和目录使用相同的策略语义 - 🛡️ **安全性** - 在打开时就验证状态,避免后续操作失败 - 💡 **意图明确** - 代码即文档,一眼看出资源预期状态 - 🔧 **灵活性** - 根据不同场景选择合适的策略 ## 📚 完整使用指南 ### 文件操作 ```java // 创建和写入 File file = root.child().file("example.txt", OpenPolicy.CREATE_IF_NOT_EXISTED); file.write("Hello, File System!", StandardCharsets.UTF_8); // 读取内容 String content = file.read(StandardCharsets.UTF_8); // 流式操作 try (InputStream input = file.inputStream()) { // 处理输入流 } try (OutputStream output = file.outputStream(StandardOpenOption.CREATE)) { output.write("数据".getBytes(StandardCharsets.UTF_8)); } // 文件判断 boolean isEmpty = file.empty(); boolean isJson = file.isExtensionOf("json"); // 获取路径信息 Path path = file.path(); String name = path.name(); String absolutePath = path.absolutePath(); ``` ### 目录操作 ```java // 创建目录 Directory dir = root.child().dir("mydir", OpenPolicy.CREATE_IF_NOT_EXISTED); // 列出子项 String[] names = dir.childrenNames(); Stream children = dir.children(); // 目录管理 boolean isEmpty = dir.empty(); dir.clear(); // 清空目录 // 获取定位器继续导航 Locator childLocator = dir.child(); File subFile = childLocator.file("sub.txt", OpenPolicy.CREATE); ``` ### 临时文件管理 ```java // 自动清理的临时文件(推荐) try (TempPath tempPath = TempPath.random()) { File tempFile = tempPath.file(); tempFile.write("临时数据", StandardCharsets.UTF_8); // 退出 try 块后自动删除 } // 带初始内容的临时文件 try (TempPath tempPath = TempPath.random("初始内容")) { // 文件已包含"初始内容" } // 指定名称的临时文件 try (TempPath tempPath = TempPath.of("my_temp.txt")) { File tempFile = tempPath.file(); // 使用临时文件... } ``` ### 实战示例 #### 示例 1:配置文件管理器 ```java public class ConfigManager { private Directory configDir; public ConfigManager() { this.configDir = FS.workingDir() .child().dir("config", OpenPolicy.CREATE_IF_NOT_EXISTED); } public void saveConfig(String key, String value) throws IOException { File configFile = configDir.child() .file(key + ".json", OpenPolicy.CREATE_IF_NOT_EXISTED); configFile.write(value, StandardCharsets.UTF_8); } public String loadConfig(String key) throws IOException { File configFile = configDir.child() .file(key + ".json", OpenPolicy.EXISTS); return configFile.read(StandardCharsets.UTF_8); } public boolean hasConfig(String key) { return configDir.child().path(key + ".json").exists(); } } ``` #### 示例 2:日志文件处理器 ```java public class LogProcessor { private Directory logDir; public LogProcessor() { this.logDir = FS.workingDir() .child().dir("logs", OpenPolicy.CREATE_IF_NOT_EXISTED); } public void writeLog(String level, String message) throws IOException { String date = LocalDate.now().toString(); File logFile = logDir.child() .file(date + ".log", OpenPolicy.CREATE_IF_NOT_EXISTED); String logEntry = String.format("[%s] %s: %s%n", LocalDateTime.now(), level, message); try (OutputStream os = logFile.outputStream(StandardOpenOption.APPEND)) { os.write(logEntry.getBytes(StandardCharsets.UTF_8)); } } public List readLogs(LocalDate date) throws IOException { File logFile = logDir.child() .file(date.toString() + ".log", OpenPolicy.EXISTS); String content = logFile.read(StandardCharsets.UTF_8); return Arrays.asList(content.split("\n")); } public void cleanupOldLogs(int daysToKeep) { LocalDate cutoff = LocalDate.now().minusDays(daysToKeep); logDir.children() .filter(path -> { try { String fileName = path.name().replace(".log", ""); LocalDate fileDate = LocalDate.parse(fileName); return fileDate.isBefore(cutoff); } catch (Exception e) { return false; } }) .forEach(Path::delete); } } ``` #### 示例 3:批量文件转换 ```java public class FileConverter { public void convertAllTxtToJson(Directory sourceDir, Directory targetDir) throws IOException { sourceDir.children() .filter(path -> path.name().endsWith(".txt")) .forEach(path -> { try { File txtFile = File.create(path, OpenPolicy.EXISTS); String content = txtFile.read(StandardCharsets.UTF_8); String jsonName = path.name().replace(".txt", ".json"); File jsonFile = targetDir.child() .file(jsonName, OpenPolicy.CREATE); String jsonContent = convertToJson(content); jsonFile.write(jsonContent, StandardCharsets.UTF_8); System.out.println("转换完成: " + path.name()); } catch (IOException e) { System.err.println("转换失败: " + path.name()); e.printStackTrace(); } }); } private String convertToJson(String text) { // 转换逻辑... return "{\"content\":\"" + text + "\"}"; } } ``` ## 🏗️ 架构设计 ### 核心类关系 ``` FS (文件系统接口) └─ Locator (路径定位器) ├─ Path (路径抽象) │ ├─ File (文件操作) │ └─ Directory (目录操作) └─ TempPath (临时文件管理) OpenPolicy (访问策略) ├─ EXISTS ├─ CREATE ├─ CREATE_IF_NOT_EXISTED └─ __ ``` ### 扩展文件系统 ```java // 实现自定义文件系统 public class MyCustomFS implements FS { @Override public String schemaAndAuthority() { return "myfs://"; } @Override public PathMethodProvider provider(PathDescription description) { return new MyCustomPathMethodProvider(description); } } // 使用自定义文件系统 FS customFS = new MyCustomFS(); Directory dir = customFS.locate() .dir("/path", OpenPolicy.CREATE_IF_NOT_EXISTED); ``` ## 📊 API 速查 ### FS - 文件系统入口 ```java FS.LOCAL_FS // 本地文件系统 FS.local() // 获取本地定位器 FS.workingDir() // 获取工作目录 FS.of(javaFileSystem) // 包装 Java NIO FileSystem ``` ### OpenPolicy - 访问策略 ```java OpenPolicy.EXISTS // 要求存在 OpenPolicy.CREATE // 创建新的 OpenPolicy.CREATE_IF_NOT_EXISTED // 智能创建 OpenPolicy.__ // 无检查 ``` ### Path - 路径操作 ```java path.uri() // 获取 URI path.exists() // 判断存在 path.name() // 获取名称 path.absolutePath() // 获取绝对路径 path.sibling(name) // 兄弟路径 path.container() // 父目录 path.rename(name) // 重命名 path.delete() // 删除 path.deleteIfExists() // 安全删除 ``` ### File - 文件操作 ```java File.create(path, policy) // 创建文件 file.read(charset) // 读取内容 file.write(content, charset) // 写入内容 file.write(inputStream) // 写入流 file.inputStream() // 获取输入流 file.outputStream(option) // 获取输出流 file.empty() // 判断是否为空 file.isExtensionOf(ext) // 判断扩展名 ``` ### Directory - 目录操作 ```java Directory.create(path, policy) // 创建目录 dir.childrenNames() // 获取子项名称 dir.children() // 获取子项流 dir.empty() // 判断是否为空 dir.clear() // 清空目录 dir.child() // 获取定位器 ``` ### TempPath - 临时文件 ```java TempPath.random() // 随机临时文件 TempPath.random(content) // 带内容的随机文件 TempPath.of(fileName) // 指定名称的临时文件 tempPath.file() // 获取文件对象 tempPath.dir() // 获取目录对象 tempPath.close() // 清理(AutoCloseable) ``` ## 🧪 测试 ```bash mvn test ``` ## 📄 许可证 本项目采用 [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0) 开源协议。 ## 🤝 贡献 欢迎提交 Issue 和 Pull Request! ## 📮 联系方式 - 作者: MineLX - 邮箱: 2647389011@qq.com - 项目地址: https://gitee.com/MineLX/file-system --- **享受简洁优雅的文件系统操作体验!** 🎉