InputStream 读取后无法加载属性

Properties cannot be loaded after InputStream read

代码如下:

Properties prop = new Properties();

FileInputStream fis = new FileInputStream("src/prop.txt");

//Read the content
byte[] bys = new byte[1024];
int len;
while((len=fis.read(bys))!=-1) {
  System.out.println(new String(bys));
}

//Load the properties and print
prop.load(fis);
fis.close();
System.out.println(prop);

src/prop.txt 很简单:

city=LA
country=USA

它在 prop 中什么也没有打印出来,这意味着 prop 是空的:

{}

但是如果我去掉阅读的部分,prop可以加载为:

{country=USA, city=LA}

为什么看了prop.txt的内容后还是无法兑现道具?

最好使用 ResourceBundle 加载属性文件。假设您使用的是 Maven,您可以将属性文件名 application.properties 放在文件夹“src/main/resources”中,然后加载并使用以下代码:

    ResourceBundle resourceBundle = ResourceBundle.getBundle("application");
    String value = resourceBundle.getString("key");

详情请参考ResourceBundle的javadoc。

更多示例位于 https://mkyong.com/java/java-resourcebundle-example/ or https://www.baeldung.com/java-resourcebundle

读取流后,流指针指向流的末尾。在那之后,当 prop.load() 尝试从流中读取时,没有更多可用的。在再次阅读之前,您必须在流上调用 reset()

Properties prop = new Properties(); 
BufferedInputStream fis = new BufferedInputStream(new FileInputStream("src/prop.txt"));

fis.mark(fis.available())  //set marker at the begining


//Read the content
byte[] bys = new byte[1024];
int len;
while((len=fis.read(bys))!=-1) {
  System.out.println(new String(bys));
}

fis.reset(); //reset the stream pointer to the begining

//Load the properties and print
prop.load(fis);
fis.close();
System.out.println(prop);

It prints out nothing in the prop, meaning the prop is empty:

因为您已经通过 fis.read(bys) 在您的 while 条件下查看了输入流 fis 中可用的数据(请参阅实际 read​(byte[] b) does), 当你把它加载到你的属性中时,什么也没有留下。

FileInputStream 不是持久保存数据的类型;它更像是一个对象,表示一个管道,一个 连接 到文件描述符,数据从文件逐字节流出,只要你继续调用 .read(..)它。

另请阅读Oracle docs

FileInputStream is meant for reading streams of raw bytes such as image data. For reading streams of characters, consider using FileReader