2011-12-05 13 views

Odpowiedz

0

Oto prosty sposób z tym, że za pomocą metod operacyjnych plików rubin:

source_file, destination_file = ARGV 
script = $0 

input = File.open(source_file) 
data_to_copy = input.read() # gather the data using read() method 

puts "The source file is #{data_to_copy.length} bytes long" 

output = File.open(destination_file, 'w') 
output.write(data_to_copy) # write up the data using write() method 

puts "File has been copied" 

output.close() 
input.close() 

Można również użyć File.exists? aby sprawdzić, czy plik istnieje, czy nie. Zwróciłoby to wartość logiczną prawda, jeśli to zrobi !!

+3

Możesz wyjaśnić cel: 'script = $ 0', również zabezpieczyć się przed odczytaniem pliku większego niż pamięć. –

6

Jako środek ostrożności Polecam stosując bufor o ile można zagwarantować cały plik zawsze pasuje do pamięci:

File.open("source", "rb") do |input| 
     File.open("target", "wb") do |output| 
     while buff = input.read(4096) 
      output.write(buff) 
     end 
     end 
    end 
+0

+1 Bardzo poprawne. Nawet w dzisiejszym świecie z pamięcią RAM o wielu gigabajtach ważne jest, aby zwracać uwagę na ilość pobieraną. Nie ma to jak brania dużego serwera na kolana po próbie odczytania pliku, który był większy niż dostępna pamięć. Ciężko jest bronić takiej akcji w przedsiębiorstwie. Polecam jednak użycie zagnieżdżonych bloków 'File.open' do automatycznego zamykania plików. –

+0

Dlaczego nie używać blokowej wersji 'open', która upewnia się, że plik jest zamknięty nawet w przypadku wyjątku? – qerub

+0

@Qerub Ponieważ zależy to od tego, jak zamierzasz przetworzyć taki wyjątek. Zamykanie strumienia nie zawsze jest właściwe, zwłaszcza gdy dotyczy to dwóch plików. –

18

Jest bardzo poręczny sposób na to - IO#copy_stream method - patrz wyjście ri copy_stream

Przykład użycia:

+0

Dlaczego nie używać blokowej wersji 'open', która upewnia się, że plik jest zamknięty nawet w przypadku wyjątku? – qerub

+0

Jeszcze lepiej: dlaczego nie używać "File.write (" src.txt "," Some text \ n ")'? – DNNX

+0

@DNNX Z dokumentów, 'File.write' zapisuje' string'. Jeśli zawartość jest inna niż pliki tekstowe, takie jak obrazy, nie będzie działać. Zamiast tego musisz użyć 'binread' i' binwrite'. – Alex

1

Oto szybkie i c dokładny sposób na zrobienie tego.

# Open first file, read it, store it, then close it 
input = File.open(ARGV[0]) {|f| f.read() } 

# Open second file, write to it, then close it 
output = File.open(ARGV[1], 'w') {|f| f.write(input) } 

Przykładem takiego działania będzie.

$ ruby this_script.rb from_file.txt to_file.txt 

ten biegnie this_script.rb i odbywa się w dwóch argumentów za pośrednictwem wiersza polecenia. Pierwszy z nich w naszym przypadku jest from_file.txt (tekst jest kopiowany z) i drugi argument second_file.txt (tekst jest kopiowany do).

3

Oto moja realizacja

class File 
    def self.copy(source, target) 
    File.open(source, 'rb') do |infile| 
     File.open(target, 'wb') do |outfile2| 
     while buffer = infile.read(4096) 
      outfile2 << buffer 
     end 
     end 
    end 
    end 
end 

Zastosowanie:

File.copy sourcepath, targetpath 
8

Dla tych, którzy są zainteresowani, oto odmianą IO#copy_stream, File#open + block odpowiedzi (S) (napisany przeciwko ruby ​​2.2.x, 3 lat za późno).

copy = Tempfile.new 
File.open(file, 'rb') do |input_stream| 
    File.open(copy, 'wb') do |output_stream| 
    IO.copy_stream(input_stream, output_stream) 
    end 
end 
+1

Po prostu komentowanie, że 'b' wskazuje' binmode' ([tryb pliku binarnego] (https://ruby-doc.org/core-2.2.0/IO.html#method-c-new-label-IO+Open + Tryb)). – Alex

0

Można również użycie File.binread i File.binwrite jeśli chcesz trzymać zawartości pliku do kawałka. (Inne odpowiedzi użyć natychmiast copy_stream zamiast.)

Jeśli zawartość schowka jest inne niż pliki tekstowe, takich jak obrazy, wykorzystując podstawowe File.read i File.write nie będzie działać.

temp_image = Tempfile.new('image.jpg') 
actual_img = IO.binread('image.jpg') 
IO.binwrite(temp_image, actual_img) 

Źródło: binread, binwrite.

Powiązane problemy