Kotlin读取挂载的ConfigMap文件遇FileNotFoundException,TypeScript可正常读取
我有一个存储在ConfigMap中的test.json文件,TypeScript应用能正常读取,但Kotlin应用读取失败(触发FileNotFoundException),排除ConfigMap配置问题,怀疑是Kotlin的文件读取方式导致。相关实现如下:
ConfigMap配置
apiVersion: v1 kind: ConfigMap metadata: name: test-config data: test.json: |- { "default": { "test1": true, "test2": true } }
部署YAML配置
global: probe: false config: enabled: true configmap: "test-config" path: "/app/global" winPath: "c:\\app\\global" ... some other stuff
TypeScript读取实现(正常工作)
const configMapPath = path.join(path.sep, 'app', 'global', 'test.json'); const fileData = fs.readFileSync(configMapPath);
Kotlin读取实现(读取失败)
val configMapPath: Path = Paths.get("app", "global", "test.json") val fileData: String = File(configMapPath.toString()).readText()
请问Java/Kotlin与TypeScript读取ConfigMap文件的方式是否存在区别?
核心差异在于路径的绝对/相对性质:
TypeScript的路径生成逻辑
Node.js的path.join(path.sep, 'app', 'global', 'test.json')中,path.sep在Linux容器环境下是/,因此最终生成的是绝对路径/app/global/test.json,直接指向ConfigMap挂载的目录位置。Kotlin的路径生成逻辑
Paths.get("app", "global", "test.json")生成的是相对路径,它会基于当前应用的工作目录去查找文件,而容器中应用的工作目录通常不是根目录(比如可能是/home/app),因此实际查找的路径是/home/app/app/global/test.json,自然找不到挂载的文件。
修正后的Kotlin实现
只需生成绝对路径即可解决问题,有两种常见方式:
// 方式1:通过根路径拼接生成绝对路径 val configMapPath: Path = Paths.get("/", "app", "global", "test.json") val fileData: String = configMapPath.toFile().readText()
// 方式2:直接指定完整绝对路径字符串 val fileData: String = File("/app/global/test.json").readText()
额外说明
Java/Kotlin的Paths.get()方法,只有当第一个参数以路径分隔符(Linux下是/)开头时,才会生成绝对路径;否则默认生成相对当前工作目录的路径。而Node.js的path.join()只要第一个参数是路径分隔符,就会构建绝对路径,这是两者的关键区别。
内容的提问来源于stack exchange,提问作者sluggercook

