2013-05-24 2 views
2

Мне всегда интересно, как катится файл в журналах.Реализация исполняемого файла

Как можно даже начать создавать класс записи файлов на любом языке, чтобы гарантировать, что размер файла не будет превышен.

Единственное возможное решения я могу думать так:

write method: 
    size = file size + size of string to write 
    if(size > limit) 
     close the file writer 
     open file reader 
     read the file 
     close file reader 
     open file writer (clears the whole file) 
     remove the size from the beginning to accommodate for new string to write 
     write the new truncated string 
    write the string we received 

Это кажется ужасной реализацией, но я не могу придумать ничего лучшего.

В частности, я хотел бы увидеть решение в java.

EDIT: Удалив размер с начала, допустим, у меня есть 20-байтовая строка (это предел), я хочу написать еще 3 байтовую строку, поэтому я удаляю 3 байта с начала и оставляю конец 17 байт, и добавив новую строку, у меня есть 20 байтов.

+1

В рамках ведения журнала это немного сложнее, потому что у них разные политики для выполнения опрокидывания. Загрузите исходный код, например, для 'logback' и посмотрите классы' RollingFileAppender' и 'FixedWindowRollingPolicy', в частности метод' rollover() '. –

+0

Спасибо, это интересно, но что, если я хочу создать что-то, что просто расширяет PrintWriter, и я хочу, чтобы это было как можно проще и элегантнее? – Quillion

+1

То, что вы опубликовали, имеет смысл, но что вы подразумеваете под _размерным размером с начала?? –

ответ

2

Поскольку ваш вопрос заставлял меня заглянуть в него, вот пример из фреймворка регистрации logback. Метод RollingfileAppender#rollover() выглядит следующим образом:

public void rollover() { 
    synchronized (lock) { 
     // Note: This method needs to be synchronized because it needs exclusive 
     // access while it closes and then re-opens the target file. 
     // 
     // make sure to close the hereto active log file! Renaming under windows 
     // does not work for open files 
     this.closeOutputStream(); 

     try { 
      rollingPolicy.rollover(); // this actually does the renaming of files 
     } catch (RolloverFailure rf) { 
      addWarn("RolloverFailure occurred. Deferring roll-over."); 
      // we failed to roll-over, let us not truncate and risk data loss 
      this.append = true; 
     } 

     try { 
      // update the currentlyActiveFile   
      currentlyActiveFile = new File(rollingPolicy.getActiveFileName()); 

      // This will also close the file. This is OK since multiple 
      // close operations are safe. 
      // COMMENT MINE this also sets the new OutputStream for the new file 
      this.openFile(rollingPolicy.getActiveFileName()); 
     } catch (IOException e) { 
      addError("setFile(" + fileName + ", false) call failed.", e); 
     } 
    } 
} 

Как вы можете видеть, логика очень похожа на то, что вы вывесили. Они закрывают ток OutputStream, выполняют опрокидывание, затем открывают новый (openFile()). Очевидно, что все это делается в блоке synchronized, так как многие потоки используют регистратор, но только один опрос должен происходить одновременно.

A RollingPolicy - это политика о том, как выполнить опрокидывание, а TriggeringPolicy - это когда выполнить опрокидывание. С помощью logback вы обычно основываете эти политики на размере или времени файла.

+0

Это кажется ужасно неэффективным, хотя нет? Используют ли все записи? Открытие и закрытие потока очень дорого, и как только вы нажмете на потолок, это часто звучит ужасно. – Quillion

+1

Закрытие одного потока? Нет, не совсем. Очевидно, вы не установили бы политику триггеров, чтобы каждый раз открывать новый файл (хотя вы могли бы). Вот как это делают фреймворки регистрации. Если вы собираетесь писать в файл, вам нужно открыть его поток. Таким образом, выполняя скользящую реализацию, это потребует от нее никакого отношения. –

+2

Я не думаю, что это неэффективно, так как обычно это спорадическая операция. Говоря конкретно о журналах, если это происходит слишком часто, это может означать, что либо вы отправляете слишком много информации в журналы, либо размер журнала слишком мал, я думаю. – jambriz