Блокирует ли ruby ​​IO.read ()? - PullRequest
3 голосов
/ 01 сентября 2009

У меня есть метод веб-сервиса, который читает фотографию и возвращает ее байтовые данные. В настоящее время я делаю следующее:

@photo_bytes = IO.read("/path/to/file")
send_data(@photo_bytes, :filename => "filename", :type => "filetype", :disposition => "inline")

У меня странное поведение, когда я так много называю ... иногда send_data возвращает ноль. Я думаю, что, возможно, я получаю утверждение о прочтении, если файл еще не был закрыт. Нужно ли явно закрывать файл после открытия его с помощью IO.read? Как я могу использовать read_nonblock для этого и стоит ли это того?

UPDATE:

Итак, я сделал еще несколько записей, и иногда IO.read возвращает значение, например, 1800 байт, когда оно обычно возвращает ~ 5800 байт для изображения. Когда он возвращает 1800 байт, изображение не отображается на клиенте. Это происходит довольно случайно, когда два пользователя вызывают веб-сервис.

Спасибо

Tom

1 Ответ

4 голосов
/ 01 сентября 2009

Метод IO.read не выполняет какой-либо принудительной блокировки файлов, поэтому другие параллельные программы чтения не должны на него влиять. Однако, если у вас в приложении есть код, который записывает по тому же пути, вам необходимо убедиться, что вы обновляете файл атомарно. Открытие файла в режиме записи (не добавления) немедленно обрезает файл до нуля байтов, поэтому до тех пор, пока не будет записана новая версия, вы могли хорошо видеть пустые ответы, генерируемые из приведенного выше фрагмента.

Предполагая, что вы на платформе * NIX, такой как Linux или OS X, вы можете атомарно обновить файл, используя такой код:

require 'tempfile'
require 'fileutils'

def safe_write(path, data)
  tmp = Tempfile.new
  tmp.write(data)
  tmp.close
  FileUtils.mv(tmp.path, path)
end

При этом данные будут записываться во временный файл, а затем атомарно перемещаться в местоположение "/path/to/file", при этом читатели не увидят усеченную версию нулевой длины.

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