Index: prelude.rb =================================================================== --- prelude.rb (revision 31125) +++ prelude.rb (working copy) @@ -29,3 +29,84 @@ } end end + + +class IO +# +# call-seq: +# IO.write(name, string, [offset] ) => fixnum +# IO.write(name, string, [offset], open_args ) => fixnum +# +# Opens the file, optionally seeks to the given offset, writes +# string, then returns the length written. +# write ensures the file is closed before returning. +# If offset is not given, the file is truncated. Otherwise, +# it is not truncated. +# +# If the last argument is a hash, it specifies option for internal +# open(). The key would be the following. open_args: is exclusive +# to others. +# +# encoding: string or encoding +# +# specifies encoding of the read string. encoding will be ignored +# if length is specified. +# +# mode: string +# +# specifies mode argument for open(). it should start with "w" or "a" or "r+" +# otherwise it would cause error. +# +# perm: fixnum +# +# specifies perm argument for open(). +# +# open_args: array of strings +# +# specifies arguments for open() as an array. +# +# IO.write("testfile", "0123456789") #=> "0123456789" +# IO.write("testfile", "0123456789", 20) #=> "This is line one\nThi0123456789two\nThis is line three\nAnd so on...\n" +# + def self.write name, string, offset=nil, open_args = nil + # 3rd param could be offset or open_args + if !open_args && offset.is_a?(Hash) + open_args = offset + offset = nil + end + if offset + open_args ||= (File::RDWR|File::CREAT) + else + open_args ||= 'w' + end + open(name, open_args || 'w') do |f| + if offset + f.seek offset + end + f.write string + end + end + +# call-seq: +# IO.binwrite(name, string, [offset] ) => fixnum +# +# Opens the file, optionally seeks to the given offset, write +# string then returns the length written. +# binwrite ensures the file is closed before returning. +# The open mode would be "wb:ASCII-8BIT". +# If offset is not given, the file is truncated. Otherwise, +# it is not truncated. +# +# IO.binwrite("testfile", "0123456789") #=> "0123456789" +# IO.binwrite("testfile", "0123456789", 20) #=> "This is line one\nThi0123456789two\nThis is line three\nAnd so on...\n" +# + def self.binwrite name, string, offset = nil + open_args = offset ? (File::RDWR|File::CREAT|File::BINARY) : 'wb' + open(name, open_args) do |f| + if offset + f.seek offset + end + f.write string + end + end +end \ No newline at end of file Index: test/ruby/test_io.rb =================================================================== --- test/ruby/test_io.rb (revision 31125) +++ test/ruby/test_io.rb (working copy) @@ -1809,4 +1809,52 @@ Process.waitpid2(pid) end end + + + def test_s_write + t = Tempfile.new("foo") + path = t.path + t.close(false) + File.write(path, "foo\nbar\nbaz") + assert_equal("foo\nbar\nbaz", File.read(path)) + File.write(path, "FOO", 0) + assert_equal("FOO\nbar\nbaz", File.read(path)) + File.write(path, "BAR") + assert_equal("BAR", File.read(path)) + File.write(path, "\u{3042}", mode: "w", encoding: "EUC-JP") + assert_equal("\u{3042}".encode("EUC-JP"), File.read(path, encoding: "EUC-JP")) + File.delete t + assert_equal(6, File.write(path,'string',2)) + File.delete t + assert_raise(Errno::EINVAL) { File.write('/tmp/nonexisting','string',-2) } + assert_equal(6, File.write(path, 'string')) + assert_equal(3, File.write(path, 'sub', 1)) + assert_equal("ssubng", File.read(path)) + t.unlink + end + + def test_s_binwrite + t = Tempfile.new("foo") + path = t.path + t.close(false) + File.binwrite(path, "foo\nbar\nbaz") + assert_equal("foo\nbar\nbaz", File.read(path)) + File.binwrite(path, "FOO", 0) + assert_equal("FOO\nbar\nbaz", File.read(path)) + File.binwrite(path, "BAR") + assert_equal("BAR", File.read(path)) + File.binwrite(path, "\u{3042}") + assert_equal("\u{3042}".force_encoding("ASCII-8BIT"), File.binread(path)) + File.delete t + assert_equal(6, File.binwrite(path,'string',2)) + File.delete t + assert_equal(6, File.binwrite(path, 'string')) + assert_equal(3, File.binwrite(path, 'sub', 1)) + assert_equal("ssubng", File.binread(path)) + assert_equal(6, File.size(path)) + assert_raise(Errno::EINVAL) { File.binwrite('/tmp/nonexisting','string',-2) } + assert_raise(TypeError) { File.binwrite(path, "string", mode: "w", encoding: "EUC-JP") } + t.unlink + end + end