读/写JAR文件内的属性文件

3

我已经4年没有写Java了,所以请原谅任何“新手”错误。

我需要一个属性文件来存储我的应用程序的一些简单数据。应用程序本身的数据不会驻留在此处,但我将存储信息,如上次使用数据存储的文件路径、其他设置等。

我设法连接到属性文件,该文件存在于尝试连接到它的类文件的同一包中,我可以读取该文件,但我无法将更改写回文件中。我相当确定我的代码有效(至少没有抛出任何错误),但是在Netbeans中运行应用程序后,更改在文件本身中未反映出来。

enter image description here

在上面的图像中,您可以看到问题的mainProperties.properties文件和尝试调用它的类(prefManagement.java)。因此,这是加载文件的代码:

Properties mainFile = new Properties();
try {

    mainFile.load(prefManagement.class.getClass().getResourceAsStream("/numberAdditionUI/mainProperties.properties"));


} catch (IOException a) {

    System.out.println("Couldn't find/load file!");

}

这个可以正常工作,我可以检查并确认一个现有的关键字(defaultXMLPath)。

我要添加到这个文件中的代码是:

String confirmKey = "defaultXMLPath2";

String propKey = mainFile.getProperty(confirmKey);

if (propKey == null) {

    // Key is not present so enter the key into the properties file
    mainFile.setProperty(confirmKey, "testtest");


    try{

        FileOutputStream fos = new FileOutputStream("mainProperties.properties");
        mainFile.store(fos, "testtest3");
        fos.flush();

    }catch(FileNotFoundException e ){
        System.out.println("Couldn't find/load file3!");
    }catch(IOException b){
        System.out.println("Couldn't find/load file4!");
    }



} else {

    // Throw error saying key already exists
    System.out.println("Key " + confirmKey + " already exists.");

}

如我之前提到的,一切都没有出现错误,我可以尝试添加现有密钥并抛出预期的错误。但是当尝试添加新的键/值对后,它不会在属性文件中显示出来。为什么?

3个回答

3

您不应该试图写入位于jar文件内部的“文件”。实际上,技术上讲,jar文件不保存“文件”,而是保存“资源”,并且出于实际目的,它们是只读的。如果您需要读取和写入属性文件,则应将其放在jar文件之外。


感谢您的快速回复!那么,“最佳实践”方面,存储“历史”类型项目和设置的最佳方法是什么,以便用户每次启动应用程序时都不必重新连接所有数据和首选文件?例如,我应该将主属性文件的文件路径存储在哪里?硬编码似乎会导致问题,如果用户的文件路径没有按照“标准”方式设置。 - BenW301
@BenW301:你的代码用于写入属性文件,是否会在jar文件之外创建一个文件?看起来应该是这样的。 - Hovercraft Full Of Eels
2
@BenW301 有许多选项可供选择,请查看此处了解其中一些的简要说明。通常,您会希望将这些设置存储在user.home目录中,确切的位置取决于平台,例如,在Linux下,它可能是{user.home}/.YouAppName/...,在Windows下,它可能是{user.home}/AppData/Roaming/YouAppName/... - MadProgrammer
@Hovercraft 这本来不是我的初衷,但在尝试了20多个在线代码块后,它可能已经相当混乱了。最终,我的应用程序将在用户计算机上的XML文件中存储数据,我只想找到一种方法来存储这些文件路径,以便用户不必每次都输入它们。所以说,这可能甚至不是最好的方法。 - BenW301

2

您的代码将属性写入本地文件mainProperties.properties

执行代码后,您会发现一个名为mainProperties.properties的文件已在本地创建。

FileOutputStream fos = new FileOutputStream("mainProperties.properties");

为了不混淆两个文件,您可以将指定的本地文件改用其他名称,例如mainAppProp.properties

  • 读取资源mainProperties.properties的完整内容。
  • 将所有必要的属性写入到local文件mainAppProp.properties中。

 FileOutputStream fos = new FileOutputStream("mainAppProp.properties");

如果文件存在,则将切换到本地文件,如果不存在,则创建文件mainAppProp.properties并将所有属性写入其中。

  • 测试本地是否存在文件mainAppProp.properties
  • 将属性读入新的“probs”变量中。
  • 从现在开始只使用此文件。

在任何情况下都不能将属性写回.jar文件。

测试如下:

    [...]
    if (propKey == null) {
    // Key is not present so enter the key into the properties file
    mainFile.setProperty(confirmKey, "testtest");


    [...]
    Reader reader = null;
    try
    {
    reader = new FileReader( "mainAppProp.properties" );
    Properties prop2 = new Properties();
    prop2.load( reader );
    prop2.list( System.out );
    }
    catch ( IOException e )
    {
    e.printStackTrace();
    }
    finally
    {
    if (reader != null) {
    reader.close(); 
    }
    }
    }
    [...]
   }

输出: 使用 prop2.list( System.out );

-- 列出属性 --
defaultXMLPath2=testtest

文件 mainAppProp.properties 的内容

#testtest3
#Mon Jul 14 14:33:20 BRT 2014
defaultXMLPath2=testtest


谢谢moskito-x,我想通过这一切发现了我正在寻找并需要使用的首选项。虽然我很感激你的帮助。 - BenW301
@BenW301:很高兴你找到了路。:-)。不客气。 - moskito-x

1
挑战: 读取jar文件中的属性文件位置 读取属性文件 将变量写入系统变量
public static void loadJarCongFile(Class Utilclass )
    {
       try{         
             String path= Utilclass.getResource("").getPath();
             path=path.substring(6,path.length()-1);
             path=path.split("!")[0];
             System.out.println(path);
             JarFile jarFile = new JarFile(path);

               final Enumeration<JarEntry> entries = jarFile.entries();
               while (entries.hasMoreElements()) {
                   final JarEntry entry = entries.nextElement();
                   if (entry.getName().contains(".properties")) {
                       System.out.println("Jar File Property File: " + entry.getName());
                       JarEntry fileEntry = jarFile.getJarEntry(entry.getName());
                       InputStream input = jarFile.getInputStream(fileEntry);
                       setSystemvariable(input);      
                       InputStreamReader isr = new InputStreamReader(input); 
                       BufferedReader reader = new BufferedReader(isr);
                       String line;

                       while ((line = reader.readLine()) != null) {
                           System.out.println("Jar file"+line);
                       }
                       reader.close();
                   }
               }
       }
       catch (Exception e)
       {
          System.out.println("Jar file reading Error");
       }
    }
    public static void setSystemvariable(InputStream input)
    {
    Properties tmp1 = new Properties();
       try {
             tmp1.load(input);

       for (Object element : tmp1.keySet()) {
             System.setProperty(element.toString().trim(),
                           tmp1.getProperty(element.toString().trim()).trim());
             }      
       } catch (IOException e) {
             System.out.println("setSystemvariable method failure");
       }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接