write(filename::AbstractString, data)#14546
write(filename::AbstractString, data)#14546samoconnor wants to merge 4 commits intoJuliaLang:masterfrom
Conversation
Convenience function to write directly to a named file (like `readall(filename)`)
I'm doing a cleanup of my local stash of convenience functions and thought that this might be generally useful.
I seem to use this very often.
```julia
write("/tmp/foo", "hello")
readall("/tmp/foo")
"hello"
```
|
|
?? open(io->write(io, data), filename, "w") === open(filename, "w") do io write(io,data) endSee function open(f::Function, args...)
io = open(args...)
try
f(io)
finally
close(io)
end
end |
base/io.jl
Outdated
There was a problem hiding this comment.
I'd support passing several values as for write since it's easy. I'd also follow the docs for write and say:
write(filename, x...)
Write the canonical binary representation of a value to file `filename`.
Returns the number of bytes written into the stream.
Equivalent to `open(io->write(io, x...), filename, "w")`.
There was a problem hiding this comment.
agreed the formatting should have the signature, was doing it quickly on a phone
|
sorry nevermind, was late. yeah the anonymous function is exactly equivalent to the do block form |
|
This seems to work ok for |
|
-1, IMO this is too magical. I think it'll clearer to write it out each time: |
|
I'm also inclined to feel that this is a bit too magical. |
|
Same amount of magic as I'm tempted to suggest a magic rootdir = fsdir()
settings = rootdir["/etc/settings"]
...
rootdir["/etc/settings"] = settings
d = fsdir(pwd())
d["my file"] = "Hello" |
|
It's pretty common to want to read all of the contents of a file and return it. How common is it to want to open a file, write exactly one binary value to it and then close it again? Can you propose some use cases? The "hello" example isn't very compelling. |
|
The aspect of this I'm most sympathetic to is that |
|
Note that creating a Dict-like object that behaves the way you propose is pretty easy, @samoconnor. |
|
Hi @StefanKarpinski, yes it would be easy. I've been playing with similar interfaces for XML and ZIP... https://github.com/samoconnor/XMLDict.jl, https://github.com/samoconnor/ZIP.jl |
|
I've been wondering what's your use case for that too while looking at ZIP.jl (which doesn't support creating an archive from files stored on disk). So far, I can't find any. |
|
Hi @nalimilan,
To create an archive from files stored on disk with my ZipFile.jl fork you can do: open_zip("foo.zip", "w") do z
z["foo.csv"] = readall("foo.csv")
endBut, since you've mentioned it I just added this... function create_zip(io::IO, files::Array)
create_zip(io::IO, files, [open(readbytes, f) for f in files])
end
e.g.
create_zip("foo.zip", ["file1.csv", "file2.csv", "subdir/file3.csv"])I think most times I've needed to do "files on disk" -> "zip on disk" I just shell out an call the "zip" program (my production code only ever has to run on OSX or Linux). But I can see why the above would be useful.
It seems that the more code I write for cloud deployment, the less I touch disk files. Data tends to come from a queue, or S3, or a database API, or a HTTP connection... A couple of recent examples are:
|
|
I'm still not seeing what the use cases for opening a file and writing a single binary value to it is... |
|
@StefanKarpinski, I don't want to waste anyones time here.
If it isn't generally useful I'll close the PR and move on. I guess to me it is completely obvious why I want to write the content of a variable to a file, so I'm having trouble articulating the reason. I apologise if this goes on too long... I've had a look through my code for places were I do I think there are two classes of use...
Run gnu plot... function gnuplot(cmd)
open ("$dir/$name.gnuplot", "w") do io
write(io, cmd)
end
run(`gnuplot $dir/$name.gnuplot`)
end(I have another version of this that pipes the command to gnuplot, but I often want to have the .gnuplot file left behind so I can tweak it by hand to adjust the plot without re-running the whole analysis.) Search and replace in a file... f = key_path("info.txt")
events = replace(readall(f), patient_id, anon_id, 1)
open(f, "w") do
io write(io, events)
end
vs
write(f, replace(readall(f), patient_id, anon_id, 1))If the xml is not identical after the reverse transform, run external diff tool... xmlb = dict_xml(xml_dict(xmla))
if xmla != xmlb
open("/tmp/a", "w") do io
write(io, xmla)
end
open("/tmp/b", "w") do io
write(io, xmlb)
end
run(`opendiff /tmp/a /tmp/b`)
end
@test xmla == xmlbUse command line function test_unzip(zip_data)
z = tempname()
try
open(z, "w") do io
write(io, zip_data)
end
[chomp(f) => readall(`unzip -qc $z $f`) for f in readlines(`unzip -Z1 $z `)]
finally
rm(z)
end
endWrite files from archive to disk... function unzip(archive, outputpath::AbstractString=pwd())
for (filename, data) in open_zip(archive)
filename = joinpath(outputpath, filename)
mkpath(dirname(filename))
open(filename, "w") do io
write(io, data)
end
end
end |
|
Thanks for providing examples, that makes this much more compelling. Maybe a |
|
I'm only tangentially following this, but it sounds a lot like FileIO.jl's load/save functions. |
|
Thinking about naming... I've tried to do a quick review of current
Looking at the
Related: BioJulia/Libz.jl#12 -- should probably be |
|
Nice, I like the survey. not sure why the "blocking" column exists since it's always "yes". |
Because it doesn't seem to be well documented. When I read this manual entry the number of bytes as return value made be suspicious that there might be some Also your suggestion of I now take it that to your knowledge, |
|
Everything in Julia always blocks the task it's called from until it's done. Under the hood it's all non-blocking, but that's exposed to the programmer via task-level concurrency. |
|
OK good. Should |
|
Probably yes, but there was some annoying reason we needed it. But definitely off-topic here. |
|
I also find the names |
@nalimilan, done. #14608 |
|
superseded by #14660? |
yes |
Convenience function to write directly to a named file.
I'm doing a cleanup of my local stash of convenience functions and thought that this might be generally useful.
I seem to use this very often.
See also JuliaIO/GZip.jl#45, gzreadall(filename) and gzwrite(filename, data).