通过从另一个文件逐行读取来加载属性文件

时间:2011-11-21 05:58:07

标签: java properties

我正在读取一个名为abc.txt的文件,abc.txt的每一行都是一个属性文件。例如: -

label.properties
label_ch.properties
label_da.properties
label_de.properties
label_en.properties

因此,在读取每一行后,我在String行中获取属性文件,之后我尝试加载该属性文件,但它没有被加载。我的实施有什么问题吗?

这是我的代码 -

package testing.project;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Properties;

public class Project {

    public static void main(String[] args) {
    BufferedReader br = null;
    HashMap<String, String> hashMap = new LinkedHashMap<String, String>();
    try {
        br = new BufferedReader(new FileReader("C:\\apps\\apache\\tomcat7\\webapps\\examples\\WEB-INF\\classes\\abc.txt"));
        StringBuilder sb = new StringBuilder();
        String line = br.readLine();
        loadProperties(line);

        while (br.readLine() != null) {
            sb.append(line);
            sb.append("\n");
            line = br.readLine();
        }
        String everything = sb.toString();
        System.out.println(everything);
    } catch (FileNotFoundException e1) {
        e1.printStackTrace();
    }
     catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }



    }

    private static void loadProperties(String line) {
        Properties prop = new Properties();
        InputStream in = Project.class.getResourceAsStream(line);
        try {
//As soon as it gets into prop.load(in), cursor goes to br.close that is in main method.
                prop.load(in);
                for(Object str: prop.keySet()) {
                    Object value = prop.getProperty((String) str);
                    System.out.println(str+" - "+value);
                }
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }


        }

    }

我收到错误 -

Exception in thread "main" java.lang.NullPointerException
    at java.util.Properties$LineReader.readLine(Unknown Source)
    at java.util.Properties.load0(Unknown Source)

4 个答案:

答案 0 :(得分:4)

通过你的代码看起来一切都很好,除了上面提到的那些。 而不是写

    String line = br.readLine();
    loadProperties(line);

    while (br.readLine() != null) {
        sb.append(line);
        sb.append("\n");
        line = br.readLine();
    }

更喜欢写

String line = null;
while ((line = br.readLine()) != null) 
{
    loadProperties(line);
    sb.append(line);
    sb.append("\n");
    line = br.readLine();
}

此外,由于它是一个java代码,所以更喜欢在描述文件路径时提出斜杠(/)而不是两个反斜杠(\)。

例如:

BufferedReader br = new BufferedReader(new FileReader("C:/Apache/tomcat/webapps/GaganIsOnline/WEB-INF/classes/names.txt"));

请检查,如果文件路径正确,意思是说,所述文件abc.txt确实存在于该给定位置。

问候。

答案 1 :(得分:1)

编辑:如果您在NullPointerException内获得prop.load(in),则可能

Project.class.getResourceAsStream(line)

返回null。您应该检查它(并且还关闭finally块中的输入流)。您确定label.properties实际存在且可用于类加载器吗?你是如何运行这段代码的?如果您正在使用Eclipse或类似的东西,您可能忘记告诉它您的label.properties文件是应该复制到输出目录的资源。


这里有一个问题:

while (br.readLine() != null) {
    sb.append(line);
    sb.append("\n");
    line = br.readLine();
}

那将会跳过其他所有行。通常我会使用:

while ((line = br.readLine()) != null) {
    sb.append(line);
    sb.append("\n");
}

请注意,只有文件的 first 行用于加载属性文件 - 其余文件只是转储到System.out。此外,您 加载的属性文件将被丢弃 - 之后您不会对prop执行任何操作。 (并且您应该在in块中关闭finally,假设它不为空。)

答案 2 :(得分:1)

一旦你修复了上面提到的bug。以下是问题的解决方案:

enum PathType {RESOURCE, ABSOLUTE}

private static void loadProperties(String line, PathType pathType) {
    Properties prop = new Properties();
    InputStream in = null;
    if (pathType == PathType.RESOURCE)
        in = PropertyTest.class.getResourceAsStream(line);
    else {
        try {
            in = new FileInputStream(line);
        } catch (FileNotFoundException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }

    try {
//As soon as it gets into prop.load(in), cursor goes to br.close that is in main method.
        prop.load(in);
        for (Object str : prop.keySet()) {
            Object value = prop.getProperty((String) str);
            System.out.println(str + " - " + value);
        }
        in.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

调用它的代码。有各种各样的方式。

  • 如果要从类加载器的基础加载属性。例如,如果我使用eclipse中的main函数运行我的应用程序,我的基础将是<some_path>/classes。所以文件label.properties就在那里。此外,如果您从Tomcat运行,label.properties位于<your_web_app>/classes。请使用以下代码:

    loadProperties("/" + line, PathType.RESOURCE); // Load from base path of class loader

  • 如果要从类加载器的包文件夹加载属性。例如,如果我使用eclipse中的main函数运行我的应用程序,我的基础将是<some_path>/classes。文件label.properties位于<some_path>/classes/testing/project。此外,如果您从Tomcat运行并且label.properties位于<your_web_app>/classes/testing/project,请使用以下代码:

    loadProperties(line, PathType.RESOURCE); // Load from base path of class loader + the package path

  • 如果您想要硬盘驱动器上任何绝对路径的加载属性。使用以下代码:

    loadProperties("C:\\apps\\apache\\tomcat7\\webapps\\examples\\WEB-INF\\classes\\" + line, PathType.ABSOLUTE);

注意:请根据您的需要处理例外情况。我刚刚更新了您的代码。

答案 3 :(得分:0)

在代码中调用方法br.readLine()两次。

 while (line != null) {
   loadProperties(line);
   sb.append(line);
   sb.append("\n");
   line = br.readLine();
 }