Sign in to follow this  
bpoint

ReadFileEx woes

Recommended Posts

Hello, I would have searched before asking this question, but the search appears to be offline -- and Google hasn't been of much help. Here's my situation. I'm using (successfully) ReadFileEx to read a file's contents in the background while doing other processing. It works great -- I get the right data and my callback routine is called when I enter SleepEx() after my work is done. The only problem I have is there apparently is no way to determine the number of bytes that have been transferred at a given point in time. I have tried using GetOverlappedResult (with bWait set to FALSE), but it always returns TRUE, indicating the transfer has completed (?) with nBytesRead set to zero. If the transfer has actually completed, then nBytesRead is set to the size I requested when I called ReadFileEx. Basically, it's zero or the size I requested (even if this size is 32Mb) -- nothing inbetween. Is there any other function that could provide me with the amount of data that has been transferred? I've tried looking at the OVERLAPPED structure members directly (InternalHigh is supposed to be the size transferred, according to ReadFile), but there's nothing of interest. I have a feeling I'm going to have to use ReadFile and poll the completion status manually so I can fake a callback into application code... *sigh* Any help/thoughts would be appreciated.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Use a smaller buffer and do several calls to ReadFileEx. For each call you could update a progress indicator.

Share this post


Link to post
Share on other sites
Sounds like a decent way to work around it. Thanks for the tip.

Edit: After thinking about it for a little bit, I realize that this method won't work very well. In order for my callback function to be called, I'd have to enter an alertable state (via SleepEx or similar method) in order to queue up another read operation. My code which does processing in the foreground is CPU intensive, and I can't really guarantee SleepEx() would be called very often (maybe once every 15ms, at best). So if I used a buffer size of 64Kb to read 16Mb, it would take 256 callbacks -- resulting in at least 3.8sec required to read the file. It certainly wouldn't take 3.8sec to read 16Mb directly... :/

Any other ideas? :)


[Edited by - bpoint on July 10, 2005 5:28:33 AM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Basically you have 2 threads as I understand. the "Read-thread" and the "UI-thread", right? You don't need to let the Read-thred wait for the UI-thread for each read.

For instance you could let the UI-thread do a PostMessage with the progress. The UI-thread will then update the UI with the new progress as soon as possible, but the Read-thread could still go on reading more data.

I know too little about your application to give more details, but this should hopefully give you some ideas.

Share this post


Link to post
Share on other sites
Quote:
Original post by bpoint
Any other ideas? :)


Since ReadFileEx does not use the hEvent field of the OVERLAPPED structure, you can stuff whatever control data you need for your I/O into it; e.g., you can put a pointer to a structure that contains the current offset and total size you want to read and just issue another ReadFileEx call.

MSN

Share this post


Link to post
Share on other sites
Thanks for the ideas. However, this is only a single-threaded application. My main concern was I wouldn't be able to call SleepEx() often enough to allow my callback to be called which would allow me to queue another ReadFileEx.

After reading through the MSDN documentation again, it appears there is no method to obtain the status of a currently in-progress overlapped transfer. I was under the impression that was what GetOverlappedResult did, but with correct operation using ReadFile (not Ex). I now know that is not the case.

I've just went with the callback method to queue up another request. I calculate a variable block size based on the size of the read request itself, so that it can run properly in the background, but not too small of a block size that the transfers would finish before the next SleepEx() call would be called.

Anyway, thanks for the help! It would have been nice if Microsoft had some kind of status checking function, however... *grumbles*

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this