簡體   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