Reading from an empty file

classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

Reading from an empty file

Shmuel Zeigerman
I wonder why the first read from an empty file returns nil rather than
an empty string.
E.g. fp:read(10) --> nil

If the zero-sized file exists then it can be interpreted as a file
containing an empty string (IMHO).

--
Shmuel


Reply | Threaded
Open this post in threaded view
|

Re: Reading from an empty file

Roberto Ierusalimschy
> I wonder why the first read from an empty file returns nil rather
> than an empty string.
> E.g. fp:read(10) --> nil
>
> If the zero-sized file exists then it can be interpreted as a file
> containing an empty string (IMHO).

Yes, that is a valid interpretation. With that interpretation, all
reads after the last character would return an empty string, as there
are infinite empty strings between the last character and the end of
file.

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: Reading from an empty file

Francisco Olarte
In reply to this post by Shmuel Zeigerman
On Tue, Sep 5, 2017 at 3:13 PM, Shmuel Zeigerman <[hidden email]> wrote:
> I wonder why the first read from an empty file returns nil rather than an
> empty string.
> E.g. fp:read(10) --> nil
>
> If the zero-sized file exists then it can be interpreted as a file
> containing an empty string (IMHO).

It can, but "number: reads a string with up to this number of bytes,
returning nil on end of file. If number is zero, it reads nothing and
returns an empty string, or nil on end of file. "

It is positioned at end of file, so it returns nil. Note it does not
distinguish between first or subsequent reads, soif it returned the
empty string it will enter an inifnite loop at EOF.

Normally, when you want to be able to have  an empty string, you use
line separators, or other similar format for your datafiles, so i.e.,
"\n" is a file with just an empty string but "" is a file with no
strings on it.

Francisco Olarte.

Reply | Threaded
Open this post in threaded view
|

Re: Reading from an empty file

Javier Guerra Giraldez
On 5 September 2017 at 15:18, Francisco Olarte <[hidden email]> wrote:
> Normally, when you want to be able to have  an empty string, you use
> line separators, or other similar format for your datafiles, so i.e.,
> "\n" is a file with just an empty string but "" is a file with no
> strings on it.

i think what you're describing is "line terminators":
"" => no lines
"\n" => one (empty) line

as i understand it, "line separators" would be:
"" => one (empty) line
"\n" => two (empty) lines


--
Javier

Reply | Threaded
Open this post in threaded view
|

Re: Reading from an empty file

Francisco Olarte
On Tue, Sep 5, 2017 at 4:36 PM, Javier Guerra Giraldez
<[hidden email]> wrote:

> On 5 September 2017 at 15:18, Francisco Olarte <[hidden email]> wrote:
>> Normally, when you want to be able to have  an empty string, you use
>> line separators, or other similar format for your datafiles, so i.e.,
>> "\n" is a file with just an empty string but "" is a file with no
>> strings on it.
>
> i think what you're describing is "line terminators":
> "" => no lines
> "\n" => one (empty) line
>
> as i understand it, "line separators" would be:
> "" => one (empty) line
> "\n" => two (empty) lines

Yep, terminators, separators have exactly that problem ( I use tab
separated fields, newline terminated record, backslash escaped
contents as data format in many of my programs and I've had to define
a special "no fields" marker precisely for this, distinguishing no
fields from single empty field, no problem with records )

FOS

Reply | Threaded
Open this post in threaded view
|

Re: Reading from an empty file

Shmuel Zeigerman
In reply to this post by Roberto Ierusalimschy
On 05/09/2017 17:17, Roberto Ierusalimschy wrote:

>> I wonder why the first read from an empty file returns nil rather
>> than an empty string.
>> E.g. fp:read(10) --> nil
>>
>> If the zero-sized file exists then it can be interpreted as a file
>> containing an empty string (IMHO).
> Yes, that is a valid interpretation. With that interpretation, all
> reads after the last character would return an empty string, as there
> are infinite empty strings between the last character and the end of
> file.
>
With this logic we would have an infinite loop in the following case as
well:
     for k in (""):gmatch(".*") do print("-",k) end
But we don't.

--
Shmuel


Reply | Threaded
Open this post in threaded view
|

Re: Reading from an empty file

Dirk Laurie-2
In reply to this post by Shmuel Zeigerman
2017-09-05 15:13 GMT+02:00 Shmuel Zeigerman <[hidden email]>:
> I wonder why the first read from an empty file returns nil rather than an
> empty string.
> E.g. fp:read(10) --> nil
>
> If the zero-sized file exists then it can be interpreted as a file
> containing an empty string (IMHO).

fp:read"a" will get you an empty string.

Reply | Threaded
Open this post in threaded view
|

Re: Reading from an empty file

Duncan Cross
In reply to this post by Shmuel Zeigerman
On Tue, Sep 5, 2017 at 4:02 PM, Shmuel Zeigerman <[hidden email]> wrote:
> With this logic we would have an infinite loop in the following case as well:
>     for k in (""):gmatch(".*") do print("-",k) end
> But we don't.

Well, it's a bit more complicated than that because a gmatch iterator
will only let you step forward through the string, but a file object
will let you "rewind" or jump around arbitrarily with the :seek()
method. So, having that extra bit of state in the gmatch iterator that
guards against reading the empty string more than once does not add
the same kind of complexity that it would for the file object.

-Duncan

Reply | Threaded
Open this post in threaded view
|

Re: Reading from an empty file

Dirk Laurie-2
In reply to this post by Shmuel Zeigerman
2017-09-05 15:13 GMT+02:00 Shmuel Zeigerman <[hidden email]>:
> I wonder why the first read from an empty file returns nil rather than an
> empty string.
> E.g. fp:read(10) --> nil
>
> If the zero-sized file exists then it can be interpreted as a file
> containing an empty string (IMHO).
>
> --
> Shmuel

An empty file is an exceptional file in the sense that its beginning
and its end is the same: position 0. fp:seek"set" and fp:seek"end"
put you in the same place.

To have fp:read(10) return nil when you are at the end of the file
is clearly the right thing to do. It is so much the right thing that
the exceptional behaviour of fp:read"a" is specifically documented
in the manual.

To have fp:read(10) return non-nil when you are reading for the
first time from an empty file would require that Lua needs to
know whether you are reading for the first time, not merely
that the file position is 0. Otherwise

repeat rec=fp:read(10) until not rec

will produce an infinite loop on an empty file (but not on others).

Reply | Threaded
Open this post in threaded view
|

Re: Reading from an empty file

Soni "They/Them" L.


On 2017-09-05 03:58 PM, Dirk Laurie wrote:

> 2017-09-05 15:13 GMT+02:00 Shmuel Zeigerman <[hidden email]>:
>> I wonder why the first read from an empty file returns nil rather than an
>> empty string.
>> E.g. fp:read(10) --> nil
>>
>> If the zero-sized file exists then it can be interpreted as a file
>> containing an empty string (IMHO).
>>
>> --
>> Shmuel
> An empty file is an exceptional file in the sense that its beginning
> and its end is the same: position 0. fp:seek"set" and fp:seek"end"
> put you in the same place.
>
> To have fp:read(10) return nil when you are at the end of the file
> is clearly the right thing to do. It is so much the right thing that
> the exceptional behaviour of fp:read"a" is specifically documented
> in the manual.
>
> To have fp:read(10) return non-nil when you are reading for the
> first time from an empty file would require that Lua needs to
> know whether you are reading for the first time, not merely
> that the file position is 0. Otherwise
>
> repeat rec=fp:read(10) until not rec
>
> will produce an infinite loop on an empty file (but not on others).
>

That's what fp:seek"set"==-1 is for :P

--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.


Reply | Threaded
Open this post in threaded view
|

Re: Reading from an empty file

Oliver Kroth
In reply to this post by Shmuel Zeigerman


Am 05.09.2017 um 15:13 schrieb Shmuel Zeigerman:
> I wonder why the first read from an empty file returns nil rather than
> an empty string.
> E.g. fp:read(10) --> nil
>
> If the zero-sized file exists then it can be interpreted as a file
> containing an empty string (IMHO).
>
If you have a single \n in your file. the first fp:read("*l") will
return "", the second fp:read("*l") will return nil.
f you read from a file that contains some characters but no \n, you get nil.
So you get a non-nil for all \n-terminated lines.
and a nil for the rest, even if it contains some characters.

To me this is consistent
You may need to call fp:read("*a) if you get nil as result to get a
final line without \n (which may exist in some text files)
--
Oliver



Reply | Threaded
Open this post in threaded view
|

Re: Reading from an empty file

Gé Weijers

On Tue, Sep 5, 2017 at 9:29 PM, Oliver Kroth <[hidden email]> wrote:
 

If you have a single \n in your file. the first fp:read("*l") will return "", the second fp:read("*l") will return nil.
f you read from a file that contains some characters but no \n, you get nil.
So you get a non-nil for all \n-terminated lines.
and a nil for the rest, even if it contains some characters.

That's not what I am seeing on Lua 5.3.4 (macOS). If there's anything after the last \n it gets returned as a separate line.

Emacs by default does not append a \n at the end of the file, unless you explicitly add it, so files not ending in \n are easy to create.


--
--

Reply | Threaded
Open this post in threaded view
|

Re: Reading from an empty file

Dirk Laurie-2
2017-09-06 7:18 GMT+02:00 Gé Weijers <[hidden email]>:

>
> On Tue, Sep 5, 2017 at 9:29 PM, Oliver Kroth <[hidden email]> wrote:
>
>>>
>>>
>> If you have a single \n in your file. the first fp:read("*l") will return
>> "", the second fp:read("*l") will return nil.
>> f you read from a file that contains some characters but no \n, you get
>> nil.
>> So you get a non-nil for all \n-terminated lines.
>> and a nil for the rest, even if it contains some characters.
>
>
> That's not what I am seeing on Lua 5.3.4 (macOS). If there's anything after
> the last \n it gets returned as a separate line.
>
> Emacs by default does not append a \n at the end of the file, unless you
> explicitly add it, so files not ending in \n are easy to create.

file:lines() and file:read"l" are supposed to do the right thing on all
systems of your text file is in that system's format.

A Windows text file read on Linux usually has \r at the end which
is not removed by those two routines.

Reply | Threaded
Open this post in threaded view
|

Re: Reading from an empty file

Scott Morgan
On 09/06/2017 06:33 AM, Dirk Laurie wrote:
> A Windows text file read on Linux usually has \r at the end which
> is not removed by those two routines.

A Windows (DOS) format text file uses '\r\n' instead of plain '\n' for
line breaks. An empty text file is still empty (0 bytes) on Windows, and
a single line (no break) does not have any '\r' char appended.

Scott