2012-01-19 3 views
14

Я использую Ruby 1.9, чтобы открыть несколько файлов и скопировать их в архив. Теперь есть несколько двоичных файлов, но некоторые нет. Поскольку Ruby 1.9 не открывает двоичные файлы автоматически как двоичные файлы, есть ли способ открыть их автоматически в любом случае? (Так что «.class» будет двоичным, «.txt» не)Автоматически открывать файл как двоичный с Ruby

ответ

30

Собственно, предыдущий ответ Alex D является неполным. Хотя это правда, что нет режима «Текст» в файловых системах Unix, Ruby делает разницу между открытием файлов в двоичном и не двоичном режиме:

s = File.open('/tmp/test.jpg', 'r') { |io| io.read } 
s.encoding 
=> #<Encoding:UTF-8> 

отличается от (обратите внимание на "rb")

s = File.open('/tmp/test.jpg', 'rb') { |io| io.read } 
s.encoding 
=> #<Encoding:ASCII-8BIT> 

Последний, как говорят docs, устанавливает внешнюю кодировку в ASCII-8BIT, которая сообщает Ruby не пытаться интерпретировать результат в UTF-8. Вы можете добиться того же, установив кодировку явно s.force_encoding('ASCII-8BIT'). Это ключ, если вы хотите читать двоичные файлы в строке и перемещать их (например, сохранять их в базу данных и т. Д.).

2

На Unix-подобных платформах нет разницы между открытием файлов в «двоичном» и «текстовом» режимах. В Windows режим «текст» преобразует разрывы строк в стиль DOS, а «двоичный» режим - нет.

Если вам не нужна конверсия строк на платформах Windows, просто откройте все файлы в «двоичном» режиме. Нет никакого вреда при чтении текстового файла в «двоичном» режиме.

Если вы действительно хотите отличить, вам нужно будет сопоставить File.extname (filename) со списком известных расширений, таких как «.txt» и «.class».

+2

Обратите внимание, что этот ответ неверен. Ruby читает в строку, а с версии 1.9 эта строка имеет связанную с ней кодировку. См. Более высокомодифицированный ответ для деталей и игнорируйте это. Если Алекс может удалить его, что было бы предпочтительнее. –

+0

Если я просто удалю его, существующий ответ не будет иметь смысла («ответ от AlexD ...»). Было бы лучше, если бы информация, содержащаяся в этом ответе (упоминание о влиянии флага «b» на преобразование строк), сначала сводится к информации в другой. –

9

Так как рубин 1.9.1 существует отдельный метод бинарного чтения (IO.binread) и так как 1.9.3 есть один для записи (IO.binwrite), а также:

для чтения:

content = IO.binread(file) 

Для написания:

IO.binwrite(file, content) 

Поскольку IO является родительским классом File, вы можете также сделать следующее ВГ ich, вероятно, более выразителен:

+2

Файл.binread (файл) также возможен – peter

+1

Да, поскольку родительский класс 'File' является классом' IO'. –

Смежные вопросы