File input/output: Difference between revisions
Content added Content deleted
(→{{header|Java}}: Attempt at Java 7 (no compiler on my current system), I'll handle the exceptions when I can test it) |
(→{{header|Ruby}}: Show FileUtils.copy_file, FileUtils.copy_stream, a copy loop, and IO.copy_stream. There are now 6 ways to copy a file.) |
||
Line 1,493: | Line 1,493: | ||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
This task is easy, with 'fileutils' from the standard library. |
|||
<lang ruby> |
|||
⚫ | |||
<lang ruby>require 'fileutils' |
|||
file << File.read('input.txt') |
|||
FileUtils.copy_file 'input.txt', 'output.txt'</lang> |
|||
⚫ | |||
⚫ | |||
It also works with open IO handles. |
|||
<lang ruby>File.open('input.txt', 'rb') do |i| |
|||
⚫ | |||
FileUtils.copy_stream(i, o) |
|||
⚫ | |||
⚫ | |||
---- |
|||
We can also copy a file with only the core language. |
|||
<lang ruby>File.open('input.txt', 'rb') do |i| |
|||
File.open('output.txt', 'wb') do |o| |
|||
buf = "" |
|||
bufsiz = (i.stat.blksize or 16384) |
|||
while i.read(bufsiz, buf) do o.write(buf) end |
|||
end |
|||
end</lang> |
|||
* The best buffer size is <code>i.stat.blksize</code>. Some platforms return <code>nil</code> there, so we guess 16384 bytes. |
|||
The shortest way to copy a file, without coding any loops and without requiring any libraries, is to read the entire file into memory. |
|||
<lang ruby>irb(main):001:0> open('output.txt', 'w') {|f| f << IO.read('input.txt')} |
|||
=> #<File:output.txt (closed)></lang> |
|||
But this has disadvantages: |
|||
* There was no 'b' flag, so it might not work with binary files on some platforms. With a 'b' flag, the code would be <code>open('output.txt', 'wb') {|f| f << IO.read('input.txt', mode: 'rb')}</code> |
|||
* If the file is very large, we fail to allocate enough memory. |
|||
---- |
|||
Ruby 1.9 has a new core method, <code>IO.copy_stream</code>. With [[MRI]] 1.9, <code>IO.copy_stream</code> might use [[Linux]]'s [http://www.kernel.org/doc/man-pages/online/pages/man2/sendfile.2.html sendfile(2)] system call, or it might loop with a buffer of 16384 bytes. |
|||
{{works with|Ruby|1.9}} |
|||
<lang ruby>IO.copy_stream('input.txt', 'output.txt') |
|||
# It also works with open IO handles. |
|||
File.open('input.txt', 'rb') do |i| |
|||
File.open('output.txt', 'wb') do |o| |
|||
IO.copy_stream(i, o) |
|||
end |
|||
end</lang> |
|||
FileUtils knows about IO.copy_stream; so if you use FileUtils, then your program uses IO.copy_stream with Ruby 1.9, but still works with older Ruby versions. |
|||
=={{header|Scala}}== |
=={{header|Scala}}== |