3

私は ScheduledThreadPoolExecutor を使用して fileIntervalInSeconds 秒ごとにファイルを作成しています:

executorService = new ScheduledThreadPoolExecutor(1);
        executorService.scheduleAtFixedRate(new Runnable()
        {
            @Override
            public void run()
            {
                    File file = new File(fileName);
                    if (file.exists())
                    {
                        Log.debug("creating new file");
                        openFileWriter(file);
                    }

            }
        }, fileIntervalInSeconds, fileIntervalInSeconds, TimeUnit.SECONDS);
    }
private void openFileWriter() throws FileSystemNotificationException
{

        // 1 - close exist writer
        writer.close();
        // 2 - rename to backup file name
          ...
        // 3 - create new file      
        FileWriter writerFile = new FileWriter(fileName, true);
        writer = new PrintWriter(writerFile);

}

そして、私は常に警告メッセージをファイルに書き込んでいます:

private synchronized void writeLine(String line) throws InterruptedException
{
    writer.println(line);
}

私の問題は次のとおりです。

  1. 閉じていないときにライターを使用していることを確認するにはどうすればよいですか? (ライター.close())
  2. 書き込みを開始する前に、ScheduledThreadPoolExecutor がファイルの作成を完了するのを待つにはどうすればよいですか
4

4 に答える 4

4

ファイルに書き込む前に、ファイルが存在することを確認してください。バックグラウンド スレッドや同期は不要

private synchronized void writeLine(String line) {
    if (!file.exists())
       reopenWritingFile();
    writer.println(line);
}
于 2013-11-11T14:11:38.967 に答える
0

2 つの選択肢があります。

  1. 古いライターを閉じる前に、新しいライターを作成します。
  2. 書き込み時にチェックするライターを閉じる前にロックを確立します。

例:

volatile PrintWriter writer;
ReadWriteLock lock = new ReentrantReadWriteLock();
Lock writeLock = lock.writeLock();
Lock readLock = lock.readLock();

private void openFileWriterWithLock() throws IOException {

  if (writeLock.tryLock()) {
    try {
      // 1 - close exist writer
      writer.close();
      // 2 - rename to backup file name
      //...
      // 3 - create new file      
      FileWriter writerFile = new FileWriter(fileName, true);
      writer = new PrintWriter(writerFile);
    } finally {
      writeLock.unlock();
    }
  }

}

private synchronized void writeLineWithLock(String line) throws InterruptedException {
  readLock.lock();
  try {
    writer.println(line);
  } finally {
    readLock.unlock();
  }
}

private void openFileWriterWithoutLock() throws IOException {
  // 0. Note old file.
  PrintWriter oldWriter = writer;
  // 1. Create new file.
  FileWriter writerFile = new FileWriter(fileName, true);
  // 2. Swap the new one in.
  writer = new PrintWriter(writerFile);
  // 3 - close old writer
  oldWriter.close();
}

private synchronized void writeLineWithoutLock(String line) throws InterruptedException {
  writer.println(line);
}
于 2013-11-11T14:40:15.483 に答える
0

write メソッド内で 1 時間ごとに新しいファイルを作成するだけです。時間チェックのために多少のオーバーヘッドが発生しますが、それは無視できるはずです。以下の例では、ミリ秒単位の時間をファイル名の前に追加して、1 時間ごとに新しいログ ファイルを作成します。時間のフォーマットは自由に設定できます。

public class LogWriter {
    private long lastCreationTime;
    PrintWriter writer;
    String logFileName;

    public LogWriter(String logFileName) {
        this.logFileName = logFileName;
        createLogFile(logFileName);
    }

    private void createLogFile(String fileName) {
        if(writer != null) {
            writer.close();
        }
        lastCreationTime = System.currentTimeMillis();
        FileWriter writerFile;
        try {
            writerFile = new FileWriter(lastCreationTime + "_" + fileName, true);
            writer = new PrintWriter(writerFile);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private synchronized void writeLine(String line) {
        if(lastCreationTime < System.currentTimeMillis() - 3600000) {
            createLogFile(logFileName);
        }
        writer.write(line);
    }
}
于 2013-11-11T14:59:30.783 に答える