Доступ запрещен для записи в файл ApplicationResources.properties - PullRequest
0 голосов
/ 04 февраля 2019

Для двуязычной поддержки в приложении, над которым я работаю, мы используем обмен сообщениями Spring, который использует два файла: ApplicationResources.properties и ApplicationResources_fr.properties.Это хорошо работает.

Теперь я пытаюсь расширить это, сделав его немного более динамичным.Приложение будет считывать пары ключ-значение из базы данных и вставлять их, что дает мне следующую ошибку:

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

Я могу проверить пары ключ-значение, поэтому я знаю, что путь, который я использую, является правильным,Я также проверил файлы в свойствах Eclipse, щелкнув правой кнопкой мыши и посетив реальный файл в моей системе, и они не доступны только для чтения.Я не верю, что они зашифрованы, потому что я могу открыть и просмотреть с помощью блокнота ++.

Вот мой тестовый код, который показывает, что я могу просматривать их

 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Свойства и это означает, что вы теряете все форматирование исходного файла, поэтому пропускаются все пробелы, комментарии и порядок.В другом ответе кто-то предложил использовать API конфигурации Apache Commons.Я планирую попробовать.

1 Ответ

0 голосов
/ 08 февраля 2019

Итак, я создал класс для обработки взаимодействий с файлами 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).После некоторого тестирования этот временный файл перезаписывается при запуске только после изменения исходного файла, в противном случае новые значения сохраняются при запуске приложения.

Я также не уверен относительно объема этого файла.Я не могу сказать, будут ли все пользователи, взаимодействующие с сайтом, вносить изменения в один и тот же файл.Если все пользователи взаимодействуют с файлом, может произойти потенциальная утечка между сеансами.Также возможно, что каждый сеанс имеет изолированные значения и может привести к отсутствию информации.Я подозреваю, что все пользователи взаимодействуют с одним и тем же ресурсом, но не провели тестирование, необходимое для того, чтобы быть абсолютно уверенным в этом.

...