2012-01-19 9 views
14

Używam Ruby 1.9, aby otworzyć kilka plików i skopiować je do archiwum. Teraz jest kilka plików binarnych, ale niektóre nie. Ponieważ Ruby 1.9 nie otwiera automatycznie plików binarnych jako plików binarnych, czy istnieje sposób ich automatycznego otwarcia? (Tak więc ".class" będzie binarny, ".txt" nie)Automatycznie otwórz plik jako plik binarny z Ruby

Odpowiedz

30

W rzeczywistości, poprzednia odpowiedź Alexa D jest niekompletna. Prawdą jest, że nie ma trybu „tekst” w systemach plików Unix, Ruby robi różnicy między otwierania plików w formacie binarnym i nie-binarnym trybie:

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

różni się od (uwaga "rb")

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

Ta ostatnia, jak mówi docs, ustaw zewnętrzne kodowanie na ASCII-8BIT, co nakazuje Ruby, aby nie próbowała interpretować wyniku w UTF-8. Możesz osiągnąć to samo, ustawiając kodowanie jawnie za pomocą s.force_encoding('ASCII-8BIT'). Jest to kluczowe, jeśli chcesz odczytywać plik binarny w ciągu znaków i przenosić je (na przykład zapisywać je w bazie danych itp.).

2

Na platformach uniksopodobnych nie ma różnicy między otwieranymi plikami w trybach "binarnym" i "tekstowym". W systemie Windows tryb "tekstowy" konwertuje podział linii na styl DOS, a tryb "binarny" nie.

Jeśli nie potrzebujesz konwersji linebreak na platformach Windows, po prostu otwórz wszystkie pliki w trybie "binarnym". Nie ma nic złego w czytaniu pliku tekstowego w trybie "binarnym".

Jeśli naprawdę chcesz się wyróżnić, będziesz musiał dopasować File.extname (filename) do listy znanych rozszerzeń, takich jak ".txt" i ".class".

+2

Pamiętaj, że ta odpowiedź jest błędna. Ruby odczytuje ciąg znaków, a od 1.9 ten ciąg ma skojarzone z nim kodowanie. Zobacz więcej wysoko modded odpowiedź dla szczegółów i zignoruj ​​to. Jeśli Alex może go skasować, byłoby to lepsze. –

+0

Jeśli tylko go usunę, istniejąca odpowiedź nie będzie miała sensu ("odpowiedź AlexD ..."). Byłoby lepiej, gdyby informacje zawarte w tej odpowiedzi (wspominając o wpływie flagi "b" na konwersję linebreaku) zostały skonsolidowane z informacjami w drugiej w pierwszej kolejności. –

9

Od Ruby 1.9.1 istnieje odrębna metoda binarny czytania (IO.binread) i od 1.9.3 jest jedna na piśmie (IO.binwrite), a także:

do odczytu:

content = IO.binread(file) 

do pisania:

IO.binwrite(file, content) 

od IO jest klasą dominującą File, można również wykonać następujące czynności WH ich jest prawdopodobnie bardziej wyrazisty:

content = File.binread(file) 
File.binwrite(file, content) 
+2

File.binread (plik) jest również możliwy – peter

+1

Tak, ponieważ rodzicem klasy 'File' jest klasa' IO'. –