1

语境

我检测到File.separator在编译为可运行 jar 的一段代码中使用时的奇怪行为。

对于上下文,我有一个 xml 支持的数据库。然后程序与该数据库进行交互,在开始时解析整个文档,创建对象,修改它们,然后在程序结束时更新 xml 文件。

实际内容和/或文件类型实际上无关紧要,但我已经包含了一个简单的 Hello World txt 作为示例。无论哪种方式,该文件都被数据库读取为InputStream(唯一的区别是我从 that 解析实际的 xml InputStream)。

MWE

数据库.java

import java.io.File;
import java.io.InputStream;

public class Database {
    public InputStream getInputStreamDependentSeparator(String fileName) {
        return getClass().getResourceAsStream("/resources/" + fileName);
    }
    
    public InputStream getInputStreamIndependentSeparator(String fileName) {
        return getClass().getResourceAsStream("/resources" + File.separator + fileName);
    }
}

主.java

import java.io.InputStream;

public class Main {
    public static void main(String[] args) {
        Database db = new Database();
        
        InputStream is1 = db.getInputStreamDependentSeparator("HelloWorld.txt");
        
        InputStream is2 = db.getInputStreamIndependentSeparator("HelloWorld.txt");
        
        System.out.println(is1.toString());
        System.out.println(is2.toString());
    }
}

你好世界.txt

Hello World!

问题描述

  • is1用于/分隔目录,而is2使用File.separator
  • 通过 IDE (Eclipse) 运行,这两个语句都不会导致异常,并产生以下输出:
java.io.BufferedInputStream@5305068a
java.io.BufferedInputStream@1f32e575
  • 将代码编译为可运行的 jar(在 Eclipse 中,右键单击项目,左键单击导出,然后按照提示输入可运行的 jar),然后从命令行运行会导致NullPointerException抛出is2. 这是以下输出:
java -jar fileSeparator.jar
sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@85ede7b
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Object.toString()" because "is2" is null
        at Main.main(Main.java:12)
  • 请注意,该System.out.println();语句并不意味着实际给出HelloWorld.txt文件的内容,只是为了检查是否InputStream有效或触发异常

问题

  • 直接从Oracle引用:编辑:正如 Erwin Bolwidt 指出的,这是关于 atg 的,不适用于 jdk。很抱歉没有注意到这一点。

为文件属性指定值时,Nucleus 将正斜杠 (/) 转换为您平台的文件分隔符(例如,Windows 使用反斜杠 (\) 作为文件分隔符)。

  • 这意味着两者都File.separator应该/提供相同的结果。但是,MWE 显示前者在运行 jar 时不起作用,而后者在 IDE 和 jar 中都可以工作。这是一个错误吗?或者我错过了什么,这是实际的预期行为?
  • 我一直在使用File.separator,根据这篇文章,这是确保未来平台兼容性的最安全方法。无论这是错误还是实际预期的行为,我应该如何解决这个问题?(我可以只使用/,但我又会失去平台独立性......)
4

0 回答 0