-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
write(filename::AbstractString, data) #14546
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) end See function open(f::Function, args...)
io = open(args...)
try
f(io)
finally
close(io)
end
end |
@@ -125,6 +125,9 @@ function write(s::IO, a::AbstractArray) | |||
end | |||
return nb | |||
end | |||
"""Write directly to a named file. Equivalent to `open(io->write(io,x), filename, "w")`.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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")
end But, 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 == xmlb Use 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
end Write 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).