繁体   English   中英

拒绝访问写入ApplicationResources.properties文件

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

为了在我正在处理的应用程序中提供双语支持,我们正在使用Spring消息传递,该消息传递使用两个文件ApplicationResources.properties和ApplicationResources_fr.properties。 这很好。

现在,我尝试通过使其更具动态性来对此进行扩展。 该应用程序将从数据库中读取键值对并将其插入,这给了我以下错误:

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

我能够检查键值对,因此我知道我使用的路径是正确的。 我还通过右键单击并访问系统上的实际文件来检查Eclipse属性中的文件,它们不是只读的。 我不相信它们是加密的,因为我能够使用notepad ++打开和查看它们。

这是我的测试代码,显示我可以查看它们

 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();
        }

这是我尝试写入文件并得到错误的地方:

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();
      }

因此,数据库查询成功,并使用注释掉的system.out.println进行了测试。 以下几行最终引发错误:

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

更新:我对java.util.Properties进行了搜索,这使我找到了关于它的javadocs,并且哇,这简化了很多事情。 现在,我可以获取属性值或检查键是否存在于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:使用java.util.Properties时遇到了一个问题,那就是您丢失了原始文件的所有格式,因此空白,注释和排序都丢失了。 在另一个答案中,有人建议使用Apache的Commons Configuration API。 我计划尝试一下。

因此,我最终创建了一个类来处理与ApplicationResources(_fr).properties文件的交互,而不是在DAO中进行。 这是因为我计划在更多地方使用它。 我还开始使用java.util.Properties Javadocs中的方法,这些方法被证明非常有用,并简化了许多领域。

以下是我的新文件写入/属性存储代码。

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();
    }

让我们比较新的和原始的OutputStreams:

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

由于以下原因,此答案不完整

我无法解释为什么原始方法失败并导致“访问被拒绝错误”。

与我有关的原因更多,这实际上并不会更改我期望或想要的文件。 我希望更改项目导航器中显示的文件,但是在查看时不会看到更改。 如果我使用绝对路径(C:\\ ...)并覆盖文件,则可以按预期进行更改,但是随着服务器的更改及其不良编程和危险性,必须更改此路径。 此工作方法正在更改某种临时文件或正在运行的文件(通过路径确认,显示新值的文件位于tmp0文件夹中)。 经过一些测试,仅当原始文件已更改时,此临时文件才会在启动时被覆盖,否则新值将在应用程序启动期间持续存在。

我也不确定此文件的范围。 我无法确定是否所有与该网站进行交互的用户都会导致对同一文件的更改。 如果所有用户都在与文件进行交互,则可能在会话之间发生潜在的泄漏。 每个会话也可能具有孤立的值,并可能导致信息丢失。 我怀疑所有用户都在与同一个资源进行交互,但是没有执行绝对肯定要进行的测试。 更新:我已经确认所有用户都与同一个临时文件进行交互。

暂无
暂无

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

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