4

Is there a trick to slurp a file with just one line of code?

("to slup" = to read entire file into a string.)

Usually I do the following:

local f = io.open("/path/to/file")
local s = f:read("*a")
f:close()

But I wonder if there's a shorter way.

I know that we can do (in Lua 5.2) the following:

local s = io.lines("/path/to/file", "*a")()

But the file would stay open for a while until the garbage collector kicks in (and gets rid of the closure io.lines returns; I believe this closure knows to explicitly close the file, but this could happen only after the second invocation of it, when it knows EOF has been reached).

So, is there a one-line solution I'm missing?

Niccolo M.
  • 3,363
  • 2
  • 22
  • 39
  • 2
    Why do you need a one-liner? – lhf Jul 21 '14 at 21:32
  • Possible duplicate of http://stackoverflow.com/questions/10386672/reading-whole-files-in-lua. – lhf Jul 21 '14 at 22:50
  • @lhf: I need a one-liner because the code is to appear in an article. Since I need to "waste" 5 extra lines on this task (there are also 2 empty lines around), or 9 lines with catwell's solution, it means that I'll have to split my code into two functions and my code will no longer be succinct :-( – Niccolo M. Jul 22 '14 at 06:37

2 Answers2

2

There is no such function in the standard library, but you can just define it yourself:

local function slurp(path)
    local f = io.open(path)
    local s = f:read("*a")
    f:close()
    return s
end

Alternatively there is such a function in Penlight.

999PingGG
  • 54
  • 1
  • 5
catwell
  • 6,770
  • 1
  • 23
  • 21
  • 2
    Some error handling is need. The lazy way is to write `f = assert(io.open(path))`. – lhf Jul 21 '14 at 22:49
  • Well, if f is nil then `f:read()` will raise an error anyway... But sure, there should be error handling. The Penlight version does it: https://github.com/stevedonovan/Penlight/blob/master/lua/pl/utils.lua#L117-L130 – catwell Jul 22 '14 at 08:56
0

So close() is not really needed you can 'Classic Online' it to...

local s = io.open("/path/to/file"):read("*a")

But in Lua you can always do Onliner in this way...

local f = io.open("/path/to/file") local s = f:read("*a") f:close()
koyaanisqatsi
  • 2,585
  • 2
  • 8
  • 15