Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

(R)Blockread/write problem

1 view
Skip to first unread message

Karl Brendel

unread,
Aug 29, 1990, 12:49:50 PM8/29/90
to

In article <900829075...@VIM.BRL.MIL>, Edwin Groothuis
<S89405079%HSEPM1.HSE.NL> writes

> assign(fil1,'FILE.1');reset(fil1); {Sourcefile}
> assign(fil2,'TEMP');rewrite(fil2); {Targetfile}
> repeat
> blockread(fil1,buffer,bufsize,recsread);
> blockwrite(fil2,buffer,recsread);
> writeln(recsread:5,' blocks written.');
> until recsread=0;

>1. When I run this program, I don't get the whole file copied (I miss
> several bytes).
>
> FILE.1 TEMP missing bytes:
> 7056 7040 16

Carefully read the procedure BlockRead documentation in the RefGuide.
The "result" variable (your recsread) returns the number of _complete_
"records" written. Since you opened the file with the default record
size of 128 bytes, the final bytes (filesize mod 128) are not being
written. "...a possible last partial record is not included in result."

As suggested by others, open the file with a record size of 1. Your file
I/O speed will not be affected.

>2. When I reset a read-only file, why does TurboPascal then say that it
> is impossible to open the file<>

Refer to the FileMode variable documentation in the RefGuide. Altho
sometimes a nuisance, this behavior is not a bug, is well-documented,
and is easily dealt with.

+-------------------------------------------------------------------------+
| Karl Brendel Centers for Disease Control |
| phone 404/639-2709 Epidemiology Program Office |
| fts 236-2709 Atlanta, GA |
| |
| Home of Epi Info 5.0 |
+-------------------------------------------------------------------------+

Karl Brendel

unread,
Aug 31, 1990, 8:56:55 AM8/31/90
to

In <26DE0F0...@ics.uci.edu> Alastair Milne <mi...@ics.uci.edu>
writes:

>In <1990Aug29.1...@ux1.cso.uiuc.edu> dslg...@uxa.cso.uiuc.edu (Daniel


> S. Lewart) writes:
>
>>>1. When I run this program, I don't get the whole file copied (I miss severa

>>> bytes).
>>> FILE.1 TEMP missing bytes:
>>> 7056 7040 16

>>> 6899 6784 115
>>> 6296 6272 24
>>> 3040 2944 96
>
>>Notice that all the TEMP sizes are multiples of 128, the default record size.
>>Try reset(fil1,1) instead.
>
> Doing an entire BlockRead for a single byte seems a waste of the routine,
> and probably invites a lot of overhead. If you want to do single-characte
> I/O, skip BlockIO altogether and just use FILE OF BYTE, with plain READs.
> May even be faster than BlockIO.

The suggestion is not to BlockRead one byte at a time, but to use a
record size of one byte. The BlockRead can still access as many bytes as
in the original. I suspect that all typed file I/O becomes equivalent to
BlockI/O in the end, so I doubt that Read(some file of byte) can be any
faster than BlockRead.

> I suspect you are not getting the whole file copied because BlockRead's
> last call causes a non-zero IOResult because of not being able to read a
> full 128-byte block. This would keep BlockWrite from doing any further

Because the original code provided a variable for the optional "result"
parameter, BlockRead would not cause an I/O error (or a non-zero
IOResult) when reading the last partial block. It _would_, indeed, read
that partial block into the buffer. Unfortunately, there would be no
explicit indication that a partial block had been read.

Alastair Milne

unread,
Sep 3, 1990, 3:09:44 AM9/3/90
to

>Because the original code provided a variable for the optional "result"
>parameter, BlockRead would not cause an I/O error (or a non-zero
>IOResult) when reading the last partial block. It _would_, indeed, read
>that partial block into the buffer. Unfortunately, there would be no
>explicit indication that a partial block had been read.

I'll double-check the documentation, but I don't believe that the
result parameter and IOResult are mutually exclusive. If your read
request wants more than is left in the file, you will still get
a non-0 IOResult, whatever the NumberRead parameter reports.

I agree that it would read the partial block (I also think the whole block
should be zeroed first so that the unread part does not remain garbage)
but that would set the IOResult so what *would* get suppressed is the
following BlockWrite.

This is from memory as I'm not where I can check this just now,
but I believe I have it correct.


Alastair Milne

Karl Brendel

unread,
Sep 4, 1990, 1:09:09 PM9/4/90
to

In <26E201...@ics.uci.edu>, Alastair Milne <mi...@ics.uci.edu>
writes

>In <24...@adm.BRL.MIL> CDCKAB%EMUVM1...@cunyvm.cuny.edu ( Karl Brendel)
> writes:
>
>>Because the original code provided a variable for the optional "result"
>>parameter, BlockRead would not cause an I/O error (or a non-zero
>>IOResult) when reading the last partial block. It _would_, indeed, read
>>that partial block into the buffer. Unfortunately, there would be no
>>explicit indication that a partial block had been read.
>
> I'll double-check the documentation, but I don't believe that the
> result parameter and IOResult are mutually exclusive. If your read
> request wants more than is left in the file, you will still get
> a non-0 IOResult, whatever the NumberRead parameter reports.
>
> I agree that it would read the partial block (I also think the whole block
> should be zeroed first so that the unread part does not remain garbage)
> but that would set the IOResult so what *would* get suppressed is the
> following BlockWrite.

I've followed this up here just for the sake of others, in case your
double-checking doesn't result in a message to the list.

The 5.X Ref Guide documentation on BlockRead says:

BlockRead(var f: file; var buf; count: word [; var result: word])
...
BlockRead reads count or less records from the file f into memory,
starting at the first byte occupied by buf. The actual number of
complete records read (less than or equal to count) is returned in the
optional parameter result. If result is not specified, an I/O error
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
will occur if the number read is not equal to count.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
result is an optional parameter. Here is how it works: If the entire
block was transferred, result will be equal to count on return.
Otherwise, if result is less than count, the end of the file was
reached before the transfer was completed. In that case, if the file's
^^^^^^^^^^^^^
record size is greater than one, result returns the number of complete
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
records read; that is, a possible last partial record is not included
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
in result.
^^^^^^^^^^
[end of quotation] (All ^^^^^^^ emphasis added during typing. :))

If what I've said previously still doesn't ring true, I'll be glad to
email you directly. It would be better for you to experiment with it a
little, though.

FWIW, while 0ing buffers can often be helpful, in this case even those
0s are probably garbage if you haven't tracked where the final read
ends. In any case where a final read can produce a valid partial
record, I know of no general way to avoid garbage other than to do your
own tracking of the end of the file. The best approach is probably to
declare a "recsize" of 1, and to read blocks of convenient, larger sizes
(multiples of your true record length, if there is one). Then "result"
always tells you how many bytes you got from the read, and anything
beyond that number is garbage.

0 new messages