Problem with seeking in existing files

I’m trying to write a program that will be writing
data to an existing file, that will not necessarily be
done in the physical file order. I used mode ‘ab+’ to
open the file, as only the ‘a’ modes allow writing
without changing the existing file. I am using sysread
and syswrite to work with the file.

The problem is that seek doesn’t seem to work. At
first I thought it might be regarding the end of the
original file as the 0 point, but some more testing
showed that even with an empty file, seek was not
changing the position of the file pointer.

I did some tests in IRB with a file opened with the
same mode, and seek seemed properly in it. Changing
the mode in the program to ‘ab’ did not work. (And I’m
eventually going to need read-write capability
anyway…)

Anyone know what could be causing this problem?

-Morgan.

···

Do you Yahoo!?
Exclusive Video Premiere - Britney Spears
http://launch.yahoo.com/promos/britneyspears/

Hi,

···

In message “Problem with seeking in existing files.” on 03/10/30, agemoagemo@yahoo.com agemoagemo@yahoo.com writes:

I’m trying to write a program that will be writing
data to an existing file, that will not necessarily be
done in the physical file order. I used mode ‘ab+’ to
open the file, as only the ‘a’ modes allow writing
without changing the existing file. I am using sysread
and syswrite to work with the file.

I don’t know what platform you are working on. But in general, stdio
does not work well with “a” (append) mode and seeking. It’s stdio
restriction.

						matz.

Win32.

What IO commands should be used with append mode?

-Morgan.

···

— Yukihiro Matsumoto matz@ruby-lang.org wrote:

Hi,

In message “Problem with seeking in existing files.” > on 03/10/30, agemoagemo@yahoo.com > agemoagemo@yahoo.com writes:

I’m trying to write a program that will be writing
data to an existing file, that will not necessarily
be
done in the physical file order. I used mode ‘ab+’
to
open the file, as only the ‘a’ modes allow writing
without changing the existing file. I am using
sysread
and syswrite to work with the file.

I don’t know what platform you are working on. But
in general, stdio
does not work well with “a” (append) mode and
seeking. It’s stdio
restriction.


Do you Yahoo!?
Exclusive Video Premiere - Britney Spears
http://launch.yahoo.com/promos/britneyspears/

Morgan,

I’m trying to write a program that will be writing
data to an existing file, that will not necessarily
be done in the physical file order. I used mode
‘ab+’ to open the file, as only the ‘a’ modes allow
writing without changing the existing file.

It sounds like what you really want is to open the file with a mode

of ‘r+b’. This allows reading and writing of the file without
truncating the file (like ‘w+b’). As you mentioned, a mode of ‘ab’
opens the file for writing only (at end of file). To open for reading
and writing (at end of file) you would need a mode of ‘a+b’. I believe
a mode of ‘ab+’ is technically incorrect on most platforms, although it
may work on some.

I hope this helps!

- Warren Brown

Dunno about win32 in general, but why not simply use File.open/new ?

f = File.new(“ayaken”, File::CREAT|File::RDWR, 0644)
f.puts(“banzai!”);
f.close
f = File.new(“ayaken”, File::RDWR)
f.seek(8);
f.puts(“ayaken!”);

=> ayaken now contains (at least on Unix)
banzai!\n
ayaken!\n

(on windows probably have to seek one further for the \r)

-Martin

···

On Fri, Oct 31, 2003 at 12:46:20AM +0900, agemoagemo@yahoo.com wrote:

Win32.

What IO commands should be used with append mode?

Well, I don’t know about technical incorrectness, but
mode ‘a+b’ is identified as an illegal access mode,
wheras ‘ab+’ will execute.

Using mode ‘rb+’ seems to produce the behavior I
need… when the file exists. When it doesn’t,
however, it produces:

in `initialize’: No such file or directory - “new.zip”
(Errno::ENOENT)

Given the alternative, I’d be quite happy to work
around it by testing for the presence of a file, and
creating a new one if it doesn’t exist… but I
haven’t yet found a simple way to test for this.

-Morgan.

···

— Warren Brown wkb@airmail.net wrote:

Morgan,

I’m trying to write a program that will be writing
data to an existing file, that will not
necessarily
be done in the physical file order. I used mode
‘ab+’ to open the file, as only the ‘a’ modes
allow
writing without changing the existing file.

It sounds like what you really want is to open

the file with a mode
of ‘r+b’. This allows reading and writing of the
file without
truncating the file (like ‘w+b’). As you mentioned,
a mode of ‘ab’
opens the file for writing only (at end of file).
To open for reading
and writing (at end of file) you would need a mode
of ‘a+b’. I believe
a mode of ‘ab+’ is technically incorrect on most
platforms, although it
may work on some.


Do you Yahoo!?
Exclusive Video Premiere - Britney Spears
http://launch.yahoo.com/promos/britneyspears/

File.new/open(filename, File::CREAT|File::RDWR) …

File::CREAT means, create the file if it doesn’t exist.

“a” is equivalent to File::CREAT|File::WRONLY +
seek(0, IO::SEEK_END)

w is File::CREAT|File::WRONLY|File::TRUNC

r is File::RDONLY

r+ is File::RDWR

See, File::CREAT is lacking here. With it there would be
no error.

w+ is File::TRUNC|File::CREAT|File::RDWR

b means binary on windows, but on unix that’s a noop, as
there is no artificial distinction between file types. Content
is what counts, so I can’t tell you what’s the File:: equivalent
to it. Just don’t use the strings, use the File:: constants.

-Martin

···

On Fri, Oct 31, 2003 at 02:57:13AM +0900, agemoagemo@yahoo.com wrote:

— Warren Brown wkb@airmail.net wrote:

Morgan,

I’m trying to write a program that will be writing
data to an existing file, that will not
necessarily
be done in the physical file order. I used mode
‘ab+’ to open the file, as only the ‘a’ modes
allow
writing without changing the existing file.

It sounds like what you really want is to open

the file with a mode
of ‘r+b’. This allows reading and writing of the
file without
truncating the file (like ‘w+b’). As you mentioned,
a mode of ‘ab’
opens the file for writing only (at end of file).
To open for reading
and writing (at end of file) you would need a mode
of ‘a+b’. I believe
a mode of ‘ab+’ is technically incorrect on most
platforms, although it
may work on some.

Well, I don’t know about technical incorrectness, but
mode ‘a+b’ is identified as an illegal access mode,
wheras ‘ab+’ will execute.

Using mode ‘rb+’ seems to produce the behavior I
need… when the file exists. When it doesn’t,
however, it produces:

Do:

begin
File.open(filename, “rb+”) { |f| … }
rescue Errno::ENOENT
File.open(filename, “wb”).close
retry
end

-austin

···

On Fri, 31 Oct 2003 02:57:13 +0900, agemoagemo@yahoo.com wrote:

Using mode ‘rb+’ seems to produce the behavior I need… when the file
exists. When it doesn’t, however, it produces:

in `initialize’: No such file or directory - “new.zip” (Errno::ENOENT)

Given the alternative, I’d be quite happy to work around it by testing
for the presence of a file, and creating a new one if it doesn’t exist…
but I haven’t yet found a simple way to test for this.


austin ziegler * austin@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.10.30
* 13.34.38