Файл Java исчезает из пути / tmp / hsperfdata_ * username * / - PullRequest
0 голосов
/ 14 марта 2019

Это очень запутанная проблема.

У нас есть Java-приложение (Java8, работающее на JBoss 6.4), которое зацикливает определенное количество объектов и записывает несколько строк в файл в каждом раунде.

В каждом раунде, который мы проверяем, принимаем ли мы объект File в качестве параметра, а если нет, мы создаем новый объект и создаем физический файл:

if (file == null){
   File file = new File(filename);
   try{
        file.createNewFile();
   } catch (IOException e) {e.printStackTrace();}}

Таким образом, идея заключается в том, что файл get создается только один раз, и после этого шаг пропускается, и мы приступаем прямо к записи. Переменная filename не является путем, это просто имя файла без пути, поэтому файл создается по пути jboss_root / tmp / hsperfdata_ username /

edit1. Я добавлю сюда также методы, используемые при написании, если они окажутся актуальными:

fw = new FileWriter(indeksiFile, true); // append = true
bw = new BufferedWriter(fw);
out = new PrintWriter(bw);
.
.
out.println(..)
.
.
out.flush();
out.close(); // this flushes as well -> line above is useless

Так что теперь проблема в том, что иногда, очень редко, физический файл исчезает с пути в середине процесса. Ссылка на java-объект никогда не теряется, но кажется, что сам объект исчезает, потому что код автоматически создает файл снова по тому же пути и продолжает записывать вещи в него. Этого не произойдет, если файл условия == null не будет иметь значение true. В результате очевидно, что мы теряем строки, которые были записаны в предыдущий файл. Приложение Java не замечает никаких ошибок и продолжает работать.

Итак, у меня было бы три вопроса, которые тесно связаны между собой, и я не смог найти ответ от Google.

  1. Если мы вызываем метод File.CreateNewFile (), является ли полученный файл постоянным файлом в файловой системе или каким-либо JVM-прокси-файлом?
  2. Если это постоянный файл, знаете ли вы, почему он исчезает? Поведение по умолчанию в нашем случае таково, что в какой-то момент файл всегда удаляется из пути. Я предполагаю, что тот же механизм удаляет файл слишком рано. Я просто не знаю, как управлять этим механизмом.
  3. Мое лучшее предположение состоит в том, что это связано с этим путем jboss_root / tmp / hsperfdata_ username /, который является некоторой папкой временных данных, созданной JVM, и, вероятно, существует некоторое поведение по умолчанию, которое очищает путь. Я даже близко?

Помощь приветствуется! Спасибо!

1 Ответ

0 голосов
/ 14 марта 2019

File.createNewFile Я никогда не использовал в своем коде: он не нужен. Когда впоследствии происходит запись в файл, он, вероятно, создает его заново или добавляет. В каждом случае в файловой системе происходит гонка. Кроме того, поскольку это не атомарные действия, у вас может получиться что-то нестабильное.

Итак, вы хотите записать в файл, либо добавив его в существующий файл, либо создав его. Для текста UTF-8:

Path path = Paths.get(filename);
try (PrintWriter out = new PrintWriter(
        Files.newBufferedWriter(path, StandardOpenOption.CREATE, StandardOpenOption.APPEND),
            false)) {
    out.println("Killroy was here");
}

После комментария Честно говоря, поскольку вы заинтересованы в причине, это трудно сказать. Перезапуск приложения или исключения ввода-вывода (?), Которые можно найти в журналах. Добавьте запись в определенный журнал для добавления к файлам и (регистрируйте) периодическую проверку существования этих файлов.


Safe-охранник Здесь мы делаем повторный физический доступ к файловой системе.

Чтобы предотвратить одновременное добавление к файлу дважды (из которых я бы ожидал исключения), можно сделать критический раздел в некоторой форме.

// For 16 semaphores:
final int semaphoreCount = 16;
final int semaphoreMask = 0xF;
Semaphore[] semaphores = new Semaphore[semaphoreCount];
for (int i = 0; i < semaphores.length; ++i) {
    semaphores[i] = new Semaphore(1, true); // FIFO
}

int hash = filename.hashcode() & semaphoreMask ; // toLowerCase on Windows
Semaphore semaphore = semaphores[hash];
try {
    semaphore.aquire();
    ... append
} finally {
    semaphore.release();
}

Блокировка файлов была бы более техническим решением, которое я не хотел бы предлагать.

Лучшее решение, которое, возможно, у вас уже есть, - очередь сообщений на файл .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...