Re: WriteFile()
- From: "Alexander Grigoriev" <alegr@xxxxxxxxxxxxx>
- Date: Mon, 11 Apr 2005 09:19:17 -0700
BTW, whether the I/O is synchronous or asynchronous doesn't change anything.
We only consider the Ifinal /O completion result, not intermediate
ERROR_IO_PENDING condition. The final result obeys the same rules for both
synch/asynch cases.
With a direct-access storage device file, one can expect that WriteFile
either writes everything, or doesn't write at all and returns an error. But
if your program may perform I/O on a generic file handle, you need to be
aware of incomplete writes.
There is still possibility for DASD file I/O to write less than requested.
WriteFile first atomically extends the file, then writes data. If during the
write, another program shrinks the file back, I would speculate that
WriteFile may write incomplete buffer. It requires more experiments.
"Hector Santos" <nospamhere@xxxxxxxxxxxxxx> wrote in message
news:%23%23EB2BoPFHA.204@xxxxxxxxxxxxxxxxxxxxxxx
> "Chris Burnette" <burnette@xxxxxxxxxxxxxxxxxx> wrote in message
>
>> ...
>
>> I didn't have anything to do with the design and implementation of
>> WriteFile... I'm only writing based on my experience, so take my advice
> for
>> what it's worth. One basic tenet of programming is to check return
> values.
>> These return values are in there for a reason, and they should be checked
>> accordingly. Making assumptions about what the expected behavior is when
>> that behavior is not clearly spelled out in the documentation isn't a
>> good
>> idea.
>
> Chris,
>
> I'm glad you not designing my products <g> MSDN serves as a reference.
> It
> does not replace the 28+ years of a rich software engineering background
> especially in the Telecommunications market (note that is before Windows!)
>
> I think you have some misunderstanding on decades old fundamental FILE
> I/O
> and communications principles and I think you might have read the docs
> incorrectly on this. The ReadFile() analogy was poor and finally, if these
> unexpected possibilities did exist, then thouands of applications based on
> standard RTL streaming and low-level file handling functions would
> fundamentally break down. They are inherently synchronous and their
> implementation is based on fundamental blocking I/O operations.
>
> For a non-timeout prepared sync device, whether its read or write, the
> request is BLOCKED until the I/O is completed. For a READ, there is only
> one condition for a partial read - not enough bytes available (EOF). This
> is not the same thing as Writing where writing X is based on having the
> EXPECTED space available to write.
>
> Again, when a timeout concept is NOT part of the design, a BLOCK call can
> only behave one way - BLOCKED until it completes the request. This is the
> essense of asynchronous vs sychronous I/O operations. There is no bending
> of the rules. Its one way only. Anything else that happens is a FLAW or
> and
> ERROR.
>
> Therefore, when there is NO timeout conditions, a blocking WriteFile()
> call
> only return with 1 of 2 possible design expectations:
>
> - TRUE with request == written
> - FALSE with and extended error code set.
>
> If a TIMEOUT does occur here with a TRUE result and no error, then we have
> a
> DESIGN FLAW in the sub-system. That function should NEVER return until it
> finishes or an error occurs.
>
>
> --
> Hector Santos, Santronics Software, Inc.
> http://www.santronics.com
>
>
>
>
>
>
> "Chris Burnette" <burnette@xxxxxxxxxxxxxxxxxx> wrote in message
> news:uD6BCqkPFHA.2468@xxxxxxxxxxxxxxxxxxxxxxx
>> I think one of the problems that I see is that there isn't enough
>> documentation on the expected behavior of Read/WriteFile. There is no
>> mention of what success really means under various conditions. It's up to
> us
>> to try to figure it out. And then there's always unexpected behaviors due
> to
>> hardware malfunctions, etc. Part of this is probably because
> Read/WriteFile
>> can be used in so many different ways, fron files, serial ports, pipes,
> etc.
>> Heck, the documentation doesn't even mention the various errors that
>> GetLastError can return. Try looking in the documentation for WriteFile
>> to
>> see what the return value for GetLastError is when a disk is full. Not
> even
>> mentioned.
>>
>> But, let's apply your argument to ReadFile. Let's assume we're using
>> ReadFile to read a series of bytes synchronously. According to your
>> argument, if ReadFile cannot read the requested number of bytes, it
>> should
>> fail. However, this isn't the case. The documentation for ReadFile states
>> that when you read to the end of a file, it's normal for ReadFile to
> return
>> success with *lpNumRead < nNumToRead. When the end of file is read,
>> *lpNumRead = 0 and ReadFile returns TRUE.
>>
>> Here's code taken from MSDN's documentation of ReadFile that demonstrates
>> how to test for end of file condition:
>> // Attempt a synchronous read operation.
>> bResult = ReadFile(hFile, &inBuffer, nBytesToRead, &nBytesRead, NULL) ;
>> // Check for end of file.
>> if (bResult && nBytesRead == 0 )
>> {
>> // we're at the end of the file
>> } So, ReadFile doesn't apply the logic of stating that it's a failure
>> condition when *lpNumRead < nNumToRead in sync situations. It also uses
> the
>> same timeout methodology that WriteFile exhibits when using serial port
> IO.
>>
>> The point I was trying to make is that it's probably not a good idea to
>> assume that *lpNumWritten == nNumToWrite when WriteFile returns TRUE in
> sync
>> mode (which was the original question). The fact that the documentation
>> states that this assumption is false to begin with only reinforces my
>> argument. Should it be the other way around? A good argument could be
>> made
>> for that, I agree. But nowhere in the documentation does it state this
>> (in
>> fact, it states that WriteFile can return TRUE when *lpNumWritten <
>> nNumToWrite under certain circumstances).
>>
>> I didn't have anything to do with the design and implementation of
>> WriteFile... I'm only writing based on my experience, so take my advice
> for
>> what it's worth. One basic tenet of programming is to check return
> values.
>> These return values are in there for a reason, and they should be checked
>> accordingly. Making assumptions about what the expected behavior is when
>> that behavior is not clearly spelled out in the documentation isn't a
>> good
>> idea.
>>
>> Chris Burnette
>> EOIR Technologies
>>
>>
>> "Hector Santos" <nospamhere@xxxxxxxxxxxxxx> wrote in message
>> news:%23R7RzcaPFHA.1172@xxxxxxxxxxxxxxxxxxxxxxx
>> >
>> > "Chris Burnette" <burnette@xxxxxxxxxxxxxxxxxx> wrote in message
>> > news:##RKupYPFHA.204@xxxxxxxxxxxxxxxxxxxxxxx
>> >
>> >> Typically, I've found that WriteFile will report that it's written the
>> > same
>> >> number of bytes that you've told it to write. I would think that an
>> >> application should not necessarily assume that this is the case; these
>> >> return values are in there for a reason.
>> >
>> > Chris, I respectfully disagree.
>> >
>> > This is not a fuzzy situation. There is no unknown carbon intelligence
>> > making decisions for us here. It is black and white. There is no gray
>> > area.
>> >
>> > If the design calls for a sync behavior with no regards to timeouts,
> then
>> > your must design the code based on expected behaviors. A sync call to
>> > WriteFile() must return the write amount equal to the request amount.
>> > Otherwise there is an error condition.
>> >
>> > If you can't "trust" the result, then there MUST be a reason for the
> lack
>> > of
>> > trust. You can't program this stuff blindly... but then again, thats
>> > probably why bugs exist :-)
>> >
>> > Here is another way to look at this:
>> >
>> > If you design your I/O with async in mind, then you using IO PENDING
> logic
>> > to properly synchronize it.
>> >
>> > If you design your I/O with sync, if what you say is true, then YOU
>> > have
>> > no
>> > choice but to have every WriteFile() call in your code changed to use
> loop
>> > concept watching for no error partial writes.
>> >
>> > Unless you specially expect this type of behavior (using serial write
>> > timesout for example), then that is completely redundant.
>> >
>> > I'm not saying that isn't ok (every sync writefile replaced with a
> wrapper
>> > that watches for generic timeout partial writes), but you might as
>> > well
>> > use
>> > a ASYNC I/O communications design.
>> >
>> > But if I have an sync WriteFile() with no timeout parameters set for
>> > the
>> > device (if possible), then I expect a block call and a 100% complete
>> > write.
>> >
>> > --
>> > Hector Santos, Santronics Software, Inc.
>> > http://www.santronics.com
>> >
>> >
>> >
>> >
>>
>>
>
.
- Follow-Ups:
- Re: WriteFile()
- From: Hector Santos
- Re: WriteFile()
- References:
- WriteFile()
- From: Frank A. Uepping
- Re: WriteFile()
- From: Hector Santos
- Re: WriteFile()
- From: Gary Chanson
- Re: WriteFile()
- From: Chris Burnette
- Re: WriteFile()
- From: Hector Santos
- Re: WriteFile()
- From: Chris Burnette
- Re: WriteFile()
- From: Hector Santos
- WriteFile()
- Prev by Date: RE: QueryPerformanceCounter on HT plus Enhanced SpeedSteep
- Next by Date: Re: WriteFile()
- Previous by thread: Re: WriteFile()
- Next by thread: Re: WriteFile()
- Index(es):
Relevant Pages
|
Loading