Нет ничего плохого в использовании файла состояния. Единственный улов будет в том, что вам нужно убедиться, что вы полностью зафиксировали свои изменения в файле состояния, прежде чем ваша программа войдет в раздел, где она может быть прервана. Обычно это делается с помощью сброса IO #.
Например, вот простой класс отслеживания состояний, работающий построчно:
class ProgressTracker
def initialize(filename)
@filename = filename
@file = open(@filename)
@state_filename = File.expand_path(".#{File.basename(@filename)}.position", File.dirname(@filename))
if (File.exist?(@state_filename))
@state_file = open(@state_filename, File::RDWR)
resume!
else
@state_file = open(@state_filename, File::RDWR | File::CREAT)
end
end
def each_line
@file.each_line do |line|
mark_position!
yield(line) if (block_given?)
end
end
protected
def mark_position!
@state_file.rewind
@state_file.puts(@file.pos)
@state_file.flush
end
def resume!
if (position = @state_file.readline)
@file.seek(position.to_i)
end
end
end
Вы используете это с IO-подобным вызовом блока:
test = ProgressTracker.new(__FILE__)
n = 0
test.each_line do |line|
n += 1
puts "%3d %s" % [ n, line ]
if (n == 10)
raise 'terminate'
end
end
В этом случае программа считывает сама себя и останавливается через десять строк из-за имитированной ошибки. При втором запуске он должен отобразить следующие десять строк, если их так много, или просто выйти, если нет дополнительных данных для извлечения.
Одно предостережение: вам нужно удалить файл .position, связанный с входными данными, если вы хотите, чтобы файл был повторно обработан, или если файл был сброшен. Также невозможно отредактировать файл и удалить более ранние строки, иначе будет отключено отслеживание смещения. Пока вы просто добавляете данные в файл или перезапускаете его, все будет хорошо.