# How to determine EOF with sysread?

**URL:** <https://rubytalk.org/t/how-to-determine-eof-with-sysread/554>\
**Category:** ruby-talk\
**Created:** [8 July 2002 03:58 UTC](https://rubytalk.org/t/how-to-determine-eof-with-sysread/554 "2002-07-08T03:58:13Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jim\_Freeze2](https://avatars.discourse-cdn.com/v4/letter/j/e480ec/32.png) [@Jim\_Freeze2](https://rubytalk.org/u/Jim_Freeze2)\
**Post date:** [8 July 2002 03:58 UTC](https://rubytalk.org/t/how-to-determine-eof-with-sysread/554/1 "2002-07-08T03:58:13Z")

</div>

Hi:

How does one determine the eof when using  
sysread. The example below seems to indicate  
that using #eof? corrupts the file pointer.

buff\_size = File.stat(ARGV[0]).blksize  
File.open(ARGV[0]) { |f|

# until f.eof? ## this statement corrupts f

```
buff = f.sysread(buff_size)
print buff

```

# end

}

Thanks

> **···**
>
> –  
> Jim Freeze  
> If only I had something clever to say for my comment…  
> ~

---

<div class="post-metadata">

**Author:** ![Sean\_Chittenden2](https://avatars.discourse-cdn.com/v4/letter/s/94ad74/32.png) [@Sean\_Chittenden2](https://rubytalk.org/u/Sean_Chittenden2)\
**Post date:** [8 July 2002 04:31 UTC](https://rubytalk.org/t/how-to-determine-eof-with-sysread/554/2 "2002-07-08T04:31:26Z")

</div>

> How does one determine the eof when using sysread. The example below  
> seems to indicate that using #eof? corrupts the file pointer.
> 
> buff\_size = File.stat(ARGV[0]).blksize  
> File.open(ARGV[0]) { |f|  
> # until f.eof? ## this statement corrupts f  
> &nbsp;&nbsp;&nbsp;&nbsp;buff = f.sysread(buff\_size)  
> &nbsp;&nbsp;&nbsp;&nbsp;print buff  
> # end  
> }

file = '/etc/passwd'  
File.open(file) do |f|  
&nbsp;&nbsp;begin  
&nbsp;&nbsp;&nbsp;&nbsp;buff\_size = f.stat.blksize  
&nbsp;&nbsp;&nbsp;&nbsp;while buff = f.sysread(buff\_size)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print buff  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;rescue EOFError  
&nbsp;&nbsp;&nbsp;&nbsp;# done reading  
&nbsp;&nbsp;end  
end

-sc

> **···**
>
> --  
> Sean Chittenden

---

<div class="post-metadata">

**Author:** ![Ned\_Konz](https://avatars.discourse-cdn.com/v4/letter/n/ad7895/32.png) [@Ned\_Konz](https://rubytalk.org/u/Ned_Konz)\
**Post date:** [8 July 2002 04:35 UTC](https://rubytalk.org/t/how-to-determine-eof-with-sysread/554/3 "2002-07-08T04:35:46Z")

</div>

So don’t use eof?. Use the EOFError that sysread raises  
at the end of file:

buff\_size = File.stat(ARGV[0]).blksize  
File.open(ARGV[0]) { |f|  
begin  
loop { buff = f.sysread(buff\_size); print buff }  
rescue EOFError  
print “\nDone.\n”  
end  
}

> **···**
>
> On Sunday 07 July 2002 08:58 pm, Jim Freeze wrote:
> 
> > Hi:
> > 
> > How does one determine the eof when using  
> > sysread. The example below seems to indicate  
> > that using #eof? corrupts the file pointer.
> 
> –  
> Ned Konz  
> [http://bike-nomad.com](http://bike-nomad.com)  
> GPG key ID: BEEA7EFE

---

<div class="post-metadata">

**Author:** ![Park\_Heesob5](https://avatars.discourse-cdn.com/v4/letter/p/77aa72/32.png) [@Park\_Heesob5](https://rubytalk.org/u/Park_Heesob5)\
**Post date:** [8 July 2002 04:41 UTC](https://rubytalk.org/t/how-to-determine-eof-with-sysread/554/4 "2002-07-08T04:41:37Z")

</div>

Hi,

“Jim Freeze” [jim@freeze.org](mailto:jim@freeze.org) wrote in message  
[news:20020707235655.A1477@freeze.org](mailto:news:20020707235655.A1477@freeze.org)…

> Hi:
> 
> How does one determine the eof when using  
> sysread. The example below seems to indicate  
> that using #eof? corrupts the file pointer.
> 
> buff\_size = File.stat(ARGV[0]).blksize  
> File.open(ARGV[0]) { |f|
> 
> # until f.eof? ## this statement corrupts f
> 
> ```
> buff = f.sysread(buff_size)
> print buff
> 
> ```
> 
> # end
> 
> }

How about?

File.open(ARGV[0]) { |f|  
while true  
begin  
buff = f.sysread(buff\_size)  
print buff  
rescue EOFError  
break  
end  
end  
}

Or

File.open(ARGV[0]) { |f|  
begin  
while buff = f.sysread(buff\_size)  
print buff  
end  
rescue EOFError  
end  
}

> Thanks
> 
> –  
> Jim Freeze  
> If only I had something clever to say for my comment…  
> ~

Park Heesob

---

<div class="post-metadata">

**Author:** ![Jim\_Freeze2](https://avatars.discourse-cdn.com/v4/letter/j/e480ec/32.png) [@Jim\_Freeze2](https://rubytalk.org/u/Jim_Freeze2)\
**Post date:** [8 July 2002 04:41 UTC](https://rubytalk.org/t/how-to-determine-eof-with-sysread/554/5 "2002-07-08T04:41:36Z")

</div>

> > Hi:
> > 
> > How does one determine the eof when using  
> > sysread. The example below seems to indicate  
> > that using #eof? corrupts the file pointer.
> 
> So don’t use eof?. Use the EOFError that sysread raises  
> at the end of file:

Thanks all for the answers.  
Does it strike anyone as bad practice  
to use a rescue for control flow?  
I thought a more explicit test method would  
have been provided.

Jim

> **···**
>
> On Mon, Jul 08, 2002 at 01:35:46PM +0900, Ned Konz wrote:
> 
> > On Sunday 07 July 2002 08:58 pm, Jim Freeze wrote:
> 
> > buff\_size = File.stat(ARGV[0]).blksize  
> > File.open(ARGV[0]) { |f|  
> > begin  
> > loop { buff = f.sysread(buff\_size); print buff }  
> > rescue EOFError  
> > print “\nDone.\n”  
> > end  
> > }
> > 
> > –  
> > Ned Konz  
> > [http://bike-nomad.com](http://bike-nomad.com)  
> > GPG key ID: BEEA7EFE
> 
> –  
> Jim Freeze  
> If only I had something clever to say for my comment…  
> ~

---

<div class="post-metadata">

**Author:** ![Sean\_Chittenden2](https://avatars.discourse-cdn.com/v4/letter/s/94ad74/32.png) [@Sean\_Chittenden2](https://rubytalk.org/u/Sean_Chittenden2)\
**Post date:** [8 July 2002 05:47 UTC](https://rubytalk.org/t/how-to-determine-eof-with-sysread/554/6 "2002-07-08T05:47:25Z")

</div>

> Thanks all for the answers. Does it strike anyone as bad practice  
> to use a rescue for control flow? I thought a more explicit test  
> method would have been provided.

My C roots tell me, yes, but my Ruby roots tell me no. Having an  
exception thrown/caught is okay practice in Ruby. -sc

> **···**
>
> --  
> Sean Chittenden

---

<div class="post-metadata">

**Author:** ![David\_Alan\_Black1](https://avatars.discourse-cdn.com/v4/letter/d/278dde/32.png) [@David\_Alan\_Black1](https://rubytalk.org/u/David_Alan_Black1)\
**Post date:** [8 July 2002 10:52 UTC](https://rubytalk.org/t/how-to-determine-eof-with-sysread/554/7 "2002-07-08T10:52:43Z")

</div>

Hi –

> Does it strike anyone as bad practice  
> to use a rescue for control flow?

Except for speed considerations, I personally prefer this:

begin  
object.meth  
rescue NoMethodError  
# …  
end

to this:

if object.respond\_to?(meth) then object.meth end

but that’s partly because I really dislike the latter idiom and try to  
get around it whenever possible.

David

> **···**
>
> On Mon, 8 Jul 2002, Jim Freeze wrote:
> 
> –  
> David Alan Black  
> home: [dblack@candle.superlink.net](mailto:dblack@candle.superlink.net)  
> work: blackdav@shu.edu  
> Web: [http://pirate.shu.edu/~blackdav](http://pirate.shu.edu/~blackdav)

---

<div class="post-metadata">

**Author:** ![Austin\_Ziegler2](https://avatars.discourse-cdn.com/v4/letter/a/ad7895/32.png) [@Austin\_Ziegler2](https://rubytalk.org/u/Austin_Ziegler2)\
**Post date:** [8 July 2002 12:40 UTC](https://rubytalk.org/t/how-to-determine-eof-with-sysread/554/8 "2002-07-08T12:40:52Z")

</div>

It still seems wrong to me, since an end of file condition is an  
expected situation, not an exceptional situation.

_shrug_

-austin  
– Austin Ziegler, austin@halostatue.ca on 2002.07.08 at 08.39.15

> **···**
>
> On Mon, 8 Jul 2002 14:47:25 +0900, Sean Chittenden wrote:
> 
> > > Thanks all for the answers. Does it strike anyone as bad practice  
> > > to use a rescue for control flow? I thought a more explicit test  
> > > method would have been provided.
> > 
> > My C roots tell me, yes, but my Ruby roots tell me no. Having an  
> > exception thrown/caught is okay practice in Ruby.

---

<div class="post-metadata">

**Author:** ![Peter\_Hickman](https://avatars.discourse-cdn.com/v4/letter/p/ecd19e/32.png) [@Peter\_Hickman](https://rubytalk.org/u/Peter_Hickman)\
**Post date:** [8 July 2002 13:05 UTC](https://rubytalk.org/t/how-to-determine-eof-with-sysread/554/9 "2002-07-08T13:05:34Z")

</div>

Austin Ziegler wrote:

> > > Thanks all for the answers. Does it strike anyone as bad practice  
> > > to use a rescue for control flow? I thought a more explicit test  
> > > method would have been provided.
> > 
> > My C roots tell me, yes, but my Ruby roots tell me no. Having an  
> > exception thrown/caught is okay practice in Ruby.
> 
> It still seems wrong to me, since an end of file condition is an  
> expected situation, not an exceptional situation.
> 
> _shrug_
> 
> -austin  
> – Austin Ziegler, austin@halostatue.ca on 2002.07.08 at 08.39.15

But eof is the exception when reading a file, because a read will  
usually succeed.  
This sort of thing is used a lot on VAXes (if they still exist) and  
early mini / mainframe designs.

I expect programs to have bugs, but I can’t predict what and where or I  
would have written the program differently. Therefore they are  
exceptions even though they are expected.

> **···**
>
> > On Mon, 8 Jul 2002 14:47:25 +0900, Sean Chittenden wrote:

---

<div class="post-metadata">

**Author:** ![Ned\_Konz](https://avatars.discourse-cdn.com/v4/letter/n/ad7895/32.png) [@Ned\_Konz](https://rubytalk.org/u/Ned_Konz)\
**Post date:** [8 July 2002 14:53 UTC](https://rubytalk.org/t/how-to-determine-eof-with-sysread/554/10 "2002-07-08T14:53:26Z")

</div>

I look at exceptions as communicating “out of band” information. In  
the case of sysread(), the “in band” information is the data you’re  
reading. Everything else (EOF, failures, etc.) is out of band.

If you don’t use an exception you have to test all over the place.  
This can also require status codes to be passed up several levels.

The main impetus behind using exceptions is this:

- we can detect exceptional conditions easiest at the lowest levels  
(in this case, inside sysread).
- but the callers of these low-level routines generally don’t know  
what the policy for dealing with the exceptional conditions is
- so we want some caller, possibly quite a bit up the caller chain, to  
be notified
- but this would require passing status all the way back up, or  
(worse) testing status at higher levels

So it’s no accident that Ruby, Smalltalk, C++, and Java (I don’t know  
about the specifics of exception handling in CLU, Ada, or PL/I) ended  
up with essentially the same exception model (except, of course, that  
most Smalltalks allow resumption as well as termination).

Another point is that code using exceptions is generally smaller and  
faster than code using status code propagation.

> **···**
>
> On Monday 08 July 2002 05:40 am, Austin Ziegler wrote:
> 
> > On Mon, 8 Jul 2002 14:47:25 +0900, Sean Chittenden wrote:
> > 
> > > > Thanks all for the answers. Does it strike anyone as bad  
> > > > practice to use a rescue for control flow? I thought a more  
> > > > explicit test method would have been provided.
> > > 
> > > My C roots tell me, yes, but my Ruby roots tell me no. Having an  
> > > exception thrown/caught is okay practice in Ruby.
> > 
> > It still seems wrong to me, since an end of file condition is an  
> > expected situation, not an exceptional situation.
> 
> –  
> Ned Konz  
> [http://bike-nomad.com](http://bike-nomad.com)  
> GPG key ID: BEEA7EFE

---

<div class="post-metadata">

**Author:** ![Tim\_Hunter3](https://avatars.discourse-cdn.com/v4/letter/t/4491bb/32.png) [@Tim\_Hunter3](https://rubytalk.org/u/Tim_Hunter3)\
**Post date:** [8 July 2002 19:04 UTC](https://rubytalk.org/t/how-to-determine-eof-with-sysread/554/11 "2002-07-08T19:04:37Z")

</div>

(snip)

> So it’s no accident that Ruby, Smalltalk, C++, and Java (I don’t know  
> about the specifics of exception handling in CLU, Ada, or PL/I) ended  
> up with essentially the same exception model (except, of course, that  
> most Smalltalks allow resumption as well as termination).  
> (snip)

I haven’t messed with PL/I in over 18 years, but my memory is that EOF  
is handled by an “on unit,” a special statement label that is branched  
to when certain conditions occur. The syntax is something like:

ON EOF MYFILE DO;  
/\* whatever \*/  
END;

Looks like an exception to me.

> **···**
>
> On Mon, 08 Jul 2002 14:58:13 GMT, Ned Konz [ned@bike-nomad.com](mailto:ned@bike-nomad.com) wrote:

---

<div class="post-metadata">

**Author:** ![Jim\_Freeze2](https://avatars.discourse-cdn.com/v4/letter/j/e480ec/32.png) [@Jim\_Freeze2](https://rubytalk.org/u/Jim_Freeze2)\
**Post date:** [8 July 2002 20:34 UTC](https://rubytalk.org/t/how-to-determine-eof-with-sysread/554/12 "2002-07-08T20:34:12Z")

</div>

You have a point, but everyone that provided code to answer my question  
assumed there was no errors in reading. In other words, if we use  
the exception to catch an EOF, we have to be able to distinquish it  
from a ‘real’ error. So, if the file is 100 bytes, and it only reads  
fifty, I would like to know about it.

Seems I would have to add some code to sum the bytes read and re-throw  
if the exception is caught before the end of the file is reached.

> **···**
>
> On Mon, Jul 08, 2002 at 10:05:34PM +0900, Peter Hickman wrote:
> 
> > Austin Ziegler wrote:
> > 
> > > On Mon, 8 Jul 2002 14:47:25 +0900, Sean Chittenden wrote:
> > > 
> > > > > Thanks all for the answers. Does it strike anyone as bad practice  
> > > > > to use a rescue for control flow? I thought a more explicit test  
> > > > > method would have been provided.
> > > > 
> > > > My C roots tell me, yes, but my Ruby roots tell me no. Having an  
> > > > exception thrown/caught is okay practice in Ruby.
> > > 
> > > It still seems wrong to me, since an end of file condition is an  
> > > expected situation, not an exceptional situation.
> > > 
> > > – Austin Ziegler, austin@halostatue.ca on 2002.07.08 at 08.39.15
> > 
> > But eof is the exception when reading a file, because a read will  
> > usually succeed.  
> > This sort of thing is used a lot on VAXes (if they still exist) and  
> > early mini / mainframe designs.
> > 
> > I expect programs to have bugs, but I can’t predict what and where or I  
> > would have written the program differently. Therefore they are  
> > exceptions even though they are expected.
> 
> –  
> Jim Freeze  
> If only I had something clever to say for my comment…  
> ~

---

<div class="post-metadata">

**Author:** ![Ned\_Konz](https://avatars.discourse-cdn.com/v4/letter/n/ad7895/32.png) [@Ned\_Konz](https://rubytalk.org/u/Ned_Konz)\
**Post date:** [8 July 2002 22:42 UTC](https://rubytalk.org/t/how-to-determine-eof-with-sysread/554/13 "2002-07-08T22:42:22Z")

</div>

Depends on whether you know how big it needs to be.  
But if you just want to catch read errors, just catch SystemError  
somewhere (possibly higher). No need to re-throw at this level.

> **···**
>
> On Monday 08 July 2002 01:34 pm, Jim Freeze wrote:
> 
> > You have a point, but everyone that provided code to answer my  
> > question assumed there was no errors in reading. In other words, if  
> > we use the exception to catch an EOF, we have to be able to  
> > distinquish it from a ‘real’ error. So, if the file is 100 bytes,  
> > and it only reads fifty, I would like to know about it.
> > 
> > Seems I would have to add some code to sum the bytes read and  
> > re-throw if the exception is caught before the end of the file is  
> > reached.
> 
> –  
> Ned Konz  
> [http://bike-nomad.com](http://bike-nomad.com)  
> GPG key ID: BEEA7EFE
