简体   繁体   English

拒绝访问写入ApplicationResources.properties文件

[英]Access is denied for writing to ApplicationResources.properties file

For bilingual support in an application I am working on, we are using Spring messaging which uses two files, ApplicationResources.properties and ApplicationResources_fr.properties. 为了在我正在处理的应用程序中提供双语支持,我们正在使用Spring消息传递,该消息传递使用两个文件ApplicationResources.properties和ApplicationResources_fr.properties。 This works well. 这很好。

Now I am trying to expand on this by making it a little more dynamic. 现在,我尝试通过使其更具动态性来对此进行扩展。 The application will read key value pairs from the database and insert them, which gives me the following error: 该应用程序将从数据库中读取键值对并将其插入,这给了我以下错误:

 java.io.FileNotFoundException: \ApplicationResources.properties (Access is denied)

I am able to check on the key value pairs so I know the path I am using is correct. 我能够检查键值对,因此我知道我使用的路径是正确的。 I have also checked the files in Eclipse properties by right clicking, and by visiting the actual file on my system, and they are not read-only. 我还通过右键单击并访问系统上的实际文件来检查Eclipse属性中的文件,它们不是只读的。 I do not believe they are encrypted because I am able to open and view with notepad++. 我不相信它们是加密的,因为我能够使用notepad ++打开和查看它们。

Here is my testing code which shows I can view them 这是我的测试代码,显示我可以查看它们

 Properties test_prop = null;
        InputStream is = null;
        try {
            test_prop = new Properties();

            is = this.getClass().getResourceAsStream(en_path);
            test_prop.load(is);
            Set<Object> keys = test_prop.keySet();
            boolean key_found = false;
            for(Object k:keys) {
                String key = (String)k;
                if(key.equals("f12345"))    
                {
                    key_found=true;
                    break;
                }
            }
System.out.println("Language Properties Test in DAO:" + (key_found? "Key Found" : "Key not found"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

Here is where I try to write to the file, and get the error: 这是我尝试写入文件并得到错误的地方:

ResultSet rs = null;
try ( 
    Connection connection = jdbcTemplate.getDataSource().getConnection();
    CallableStatement callableStatement = connection.prepareCall(test_prod_cur);
    )
    {
        callableStatement.registerOutParameter(1, OracleTypes.CURSOR);
        callableStatement.executeUpdate();
        rs = (ResultSet) callableStatement.getObject(1);
        while (rs.next())
        {
              String thead = rs.getString(1);
//System.out.println(thead + " " + rs.getString(2) + " " + rs.getString(3));
              en_prop.setProperty(keyheader+thead, rs.getString(2));
              fr_prop.setProperty(keyheader+thead, rs.getString(3));
          }
      }
      catch (SQLException e)
      {
          System.out.println("SQLException - bilingual values - CLUDAOImpl");
          System.out.println(e.getMessage());
      }

    //add to properties files
      //*       
      try (OutputStream en_os = new FileOutputStream(en_path);)
      {
            en_prop.store(en_os, null);
        } catch (IOException e) {
            e.printStackTrace();
        }

      try(OutputStream fr_os = new FileOutputStream(en_path);)
      {
            fr_prop.store(fr_os, null);
        } catch (IOException e) {
            e.printStackTrace();
      }

So the database query is successful, that was tested with the commented out system.out.println. 因此,数据库查询成功,并使用注释掉的system.out.println进行了测试。 It is the following lines that end up throwing the error: 以下几行最终引发错误:

 en_prop.store(en_os, null);
 fr_prop.store(fr_os, null);

Update: I did a search on the java.util.Properties which lead me to the javadocs on it and wow does that simplify many things. 更新:我对java.util.Properties进行了搜索,这使我找到了关于它的javadocs,并且哇,这简化了很多事情。 I can now grab a property value or check if the key exists in 6 lines of code (not counting try catch). 现在,我可以获取属性值或检查键是否存在于6行代码中(不计算try catch)。

 Properties prop = null;
 InputStream is = null;
 this.prop = new Properties();
 is = this.getClass().getResourceAsStream(path);
 prop.load(is);
 this.prop.getProperty("key name"); //returns value of key, or null
 this.prop.containsKey("key name"); //returns true if key exists

Update2: There is an issue using java.util.Properties and that is you lose all formatting of the original file, so white-space, comments, and ordering are all lost. Update2:使用java.util.Properties时遇到了一个问题,那就是您丢失了原始文件的所有格式,因此空白,注释和排序都丢失了。 In another answer someone suggested using Apache's Commons Configuration API. 在另一个答案中,有人建议使用Apache的Commons Configuration API。 I plan on trying it out. 我计划尝试一下。

So I ended up creating a class to handle interactions with the ApplicationResources(_fr).properties files instead of doing it in the DAO. 因此,我最终创建了一个类来处理与ApplicationResources(_fr).properties文件的交互,而不是在DAO中进行。 This was because I plan on using it in more places. 这是因为我计划在更多地方使用它。 I also started using methods from the java.util.Properties Javadocs which proved very helpful and simplified many areas. 我还开始使用java.util.Properties Javadocs中的方法,这些方法被证明非常有用,并简化了许多领域。

Below is my new file write/properties store code. 以下是我的新文件写入/属性存储代码。

try (
        OutputStream en_os = new FileOutputStream(getClass().getResource(en_path).getFile(),false);
        OutputStream fr_os = new FileOutputStream(getClass().getResource(fr_path).getFile(), false);
    )
    {
        en_prop.store(en_os, null);
        fr_prop.store(fr_os, null);
    } catch (IOException e) {
        e.printStackTrace();
    }

Lets compare the new and original OutputStreams: 让我们比较新的和原始的OutputStreams:

OutputStream en_os = new FileOutputStream(getClass().getResource(en_path).getFile(),false); //new
OutputStream en_os = new FileOutputStream(en_path); //original, Access is Denied

This answer is incomplete for the following reasons . 由于以下原因,此答案不完整

I am unable to explain why the original method failed and resulted in a "Access is denied error". 我无法解释为什么原始方法失败并导致“访问被拒绝错误”。

More concerning reason to me, this doesnt actually alter the file I am expecting or wanting. 与我有关的原因更多,这实际上并不会更改我期望或想要的文件。 I expected to alter the file that appears in my project navigator, but when viewed changes are not observed. 我希望更改项目导航器中显示的文件,但是在查看时不会看到更改。 If I use an absolute path (C:\\...) and overwrite the file then I can alter it as expected, but this path would have to be changed as servers are changed and its bad programming and dangerous. 如果我使用绝对路径(C:\\ ...)并覆盖文件,则可以按预期进行更改,但是随着服务器的更改及其不良编程和危险性,必须更改此路径。 This working method is altering some kind of temp or running file (as confirmed via the path as the file that shows the new values is in the tmp0 folder). 此工作方法正在更改某种临时文件或正在运行的文件(通过路径确认,显示新值的文件位于tmp0文件夹中)。 After some testing, this temporary file is overwritten on startup only when the original file has been changed, otherwise the new values persist across application starting. 经过一些测试,仅当原始文件已更改时,此临时文件才会在启动时被覆盖,否则新值将在应用程序启动期间持续存在。

I am also unsure as to the scope of this file. 我也不确定此文件的范围。 I am unable to tell if all users interacting with the website would cause changes to the same file. 我无法确定是否所有与该网站进行交互的用户都会导致对同一文件的更改。 If all users are interacting with the file, then potential leakage across sessions could occur. 如果所有用户都在与文件进行交互,则可能在会话之间发生潜在的泄漏。 It is also possible that each session has isolated values and could lead to missing information. 每个会话也可能具有孤立的值,并可能导致信息丢失。 I suspect that all users are interacting with the same resource but have not performed the testing required to be absolutely positive about this. 我怀疑所有用户都在与同一个资源进行交互,但是没有执行绝对肯定要进行的测试。 UPDATE: I have confirmed that all users interact with the same temporary file. 更新:我已经确认所有用户都与同一个临时文件进行交互。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM