diff --git a/spec/std/file_spec.cr b/spec/std/file_spec.cr index 24f8b292f4db..2c7d38627392 100644 --- a/spec/std/file_spec.cr +++ b/spec/std/file_spec.cr @@ -657,6 +657,28 @@ describe "File" do end File.delete(filename) end + + it "can create a new file in append mode" do + filename = Tempfile.tempname + begin + File.write(filename, "hello", mode: "a") + File.read(filename).should eq("hello") + ensure + File.delete(filename) + end + end + + it "can append to an existing file" do + filename = Tempfile.tempname + begin + File.write(filename, "hello") + File.read(filename).should eq("hello") + File.write(filename, " world", mode: "a") + File.read(filename).should eq("hello world") + ensure + File.delete(filename) + end + end end it "does to_s" do diff --git a/src/file.cr b/src/file.cr index b077ee36833a..ce6a4a1d06b5 100644 --- a/src/file.cr +++ b/src/file.cr @@ -664,18 +664,23 @@ class File < IO::FileDescriptor # Write the given *content* to *filename*. # - # An existing file will be overwritten, else a file will be created. + # The *mode* parameter can be used to change the file's `open` mode, e.g. to `"a"` for appending. + # + # By default, an existing file will be overwritten. + # + # *filename* will be created if it does not already exist. # # ``` # File.write("foo", "bar") + # File.write("foo", "baz", mode: "a") # ``` # # NOTE: If the content is a `Slice(UInt8)`, those bytes will be written. # If it's an `IO`, all bytes from the `IO` will be written. # Otherwise, the string representation of *content* will be written # (the result of invoking `to_s` on *content*). - def self.write(filename, content, perm = DEFAULT_CREATE_MODE, encoding = nil, invalid = nil) - open(filename, "w", perm, encoding: encoding, invalid: invalid) do |file| + def self.write(filename, content, perm = DEFAULT_CREATE_MODE, encoding = nil, invalid = nil, mode = "w") + open(filename, mode, perm, encoding: encoding, invalid: invalid) do |file| case content when Bytes file.write(content)