From EDM2
Jump to: navigation, search

Reads the specified number of bytes from a file, pipe, or device to a buffer location.


DosRead (hFile, pBuffer, cbRead, pcbActual)


hFile (HFILE) - input 
File handle obtained from DosOpen.
pBuffer (PVOID) - output 
Address of the buffer to receive the bytes read.
cbRead (ULONG) - input 
The length, in bytes, of pBuffer.
This is the number of bytes to be read.
pcbActual (PULONG) - output 
Address of the variable to receive the number of bytes actually read.

Return Code

ulrc (APIRET) - returns

DosRead returns one of the following values:

  • 0 NO_ERROR


Note: When writing message pipes the application is limited to 64K messages. As well, these messages cannot span 64k boundaries due to the current design of the thunk layer in read or write routines. If the message is not written in an aligned manner, the subsequent read will not be able to handle the messages properly. If a 64k or less message is written to a pipe from an aligned buffer, the read will handle this properly.

The requested number of bytes might not be read. If the value returned in pcbActual is zero, the process tried to read from the end of the file.

A value of zero for cbRead is not considered an error. In such a case, the system treats the request as a null operation.

The file pointer is moved to the desired position by reading data, writing data, or issuing DosSetFilePtr.

If you issue DosOpen with the Direct Open flag set to 1 in the fsOpenFlags parameter, you have direct access to an entire disk or diskette volume, independent of the file system. You must lock the logical volume before accessing it, and you must unlock the logical volume when you are finished accessing it. Issue DosDevIOCtl for Category 8, DSK_LOCKDRIVE to lock the logical volume, and for Category 8, DSK_UNLOCKDRIVE to unlock the logical volume. While the logical volume is locked, no other process can access it.

Named Pipe Considerations

A named pipe is read as one of the following:

  • A byte pipe in byte-read mode
  • A message pipe in message-read mode
  • A message pipe in byte-read mode.

A byte pipe must be in byte-read mode to be read; an error is returned if it is in message-read mode. All currently available data, up to the size requested, is returned.

A message pipe can be read in either message-read mode or byte-read mode. When the message pipe is in message-read mode, a read operation that is larger than the next available message returns only that message. pcbActual is set to indicate the size of the message returned.

A read operation that is smaller than the next available message returns with the number of bytes requested and an ERROR_MORE_DATA return code. When the reading of a message is resumed after ERROR_MORE_DATA is returned, a read operation always blocks until the next piece (or the rest) of the message can be transferred. DosPeekNPipe can be issued to determine how many bytes are left in the message.

A message pipe in byte-read mode is read as if it were a byte stream, and DosRead skips over message headers. This is like reading a byte pipe in byte-read mode.

When blocking mode is set for a named pipe, a read operation blocks until data is available. In this case, the read operation never returns with pcbActual equal to zero, except when the pipe is closed. When the mode is set to message-read, messages are always read in their entirety, except when the message is bigger than the size of the read operation.

pcbActual can equal zero in nonblocking mode, but only when no data is available at the time of the read operation.

If you attempt a read of a named pipe when the other end of the pipe is closed while the read is pending, DosRead returns:

  • pcbActual equal to 0
  • ulrc equal to either 0 or ERROR_NO_DATA

Unnamed Pipe Considerations

Threads writing to and reading from the same unnamed pipe are not synchronized. It is possible for the pipe reader to obtain partial contents of a write request if the pipe becomes full during the write request.

Example Code

This example opens or creates and opens a file named "DOSTEST.DAT", writes to it, reads from it, and finally closes the file.

#define INCL_DOSFILEMGR          /* File Manager values */
#define INCL_DOSERRORS           /* DOS Error values    */
#include <os2.h>
#include <stdio.h>
#include <string.h>

int main(void) {
   HFILE  hfFileHandle   = 0L;     /* Handle for file being manipulated */
   ULONG  ulAction       = 0;      /* Action taken by DosOpen */
   ULONG  ulBytesRead    = 0;      /* Number of bytes read by DosRead */
   ULONG  ulWrote        = 0;      /* Number of bytes written by DosWrite */
   ULONG  ulLocal        = 0;      /* File pointer position after DosSetFilePtr */
   UCHAR  uchFileName[20]  = "dostest.dat",     /* Name of file */
          uchFileData[100] = " ";               /* Data to write to file */
   APIRET rc             = NO_ERROR;            /* Return code */

   /* Open the file dostest.dat. Use an existing file or create a new */
   /* one if it doesn't exist.                                      */
   rc = DosOpen(uchFileName,                    /* File path name */
                &hfFileHandle,                  /* File handle */
                &ulAction,                      /* Action taken */
                100L,                           /* File primary allocation */
                FILE_ARCHIVED | FILE_NORMAL,    /* File attribute */
                OPEN_ACTION_CREATE_IF_NEW |
                OPEN_ACTION_OPEN_IF_EXISTS,     /* Open function type */
                OPEN_FLAGS_NOINHERIT |
                OPEN_SHARE_DENYNONE  |
                OPEN_ACCESS_READWRITE,          /* Open mode of the file */
                0L);                            /* No extended attribute */

   if (rc != NO_ERROR) {
      printf("DosOpen error: return code = %u\n", rc);
      return 1;
   } else {
     printf ("DosOpen: Action taken = %ld\n", ulAction);
   } /* endif */

   /* Write a string to the file */
   strcpy (uchFileData, "testing...\n1...\n2...\n3\n");

   rc = DosWrite (hfFileHandle,                /* File handle */
                  (PVOID) uchFileData,         /* String to be written */
                  sizeof (uchFileData),        /* Size of string to be written */
                  &ulWrote);                   /* Bytes actually written */
   if (rc != NO_ERROR) {
      printf("DosWrite error: return code = %u\n", rc);
      return 1;
   } else {
      printf ("DosWrite: Bytes written = %u\n", ulWrote);
   } /* endif */

   /* Move the file pointer back to the beginning of the file */
   rc = DosSetFilePtr (hfFileHandle,           /* File Handle */
                       0L,                     /* Offset */
                       FILE_BEGIN,             /* Move from BOF */
                       &ulLocal);              /* New location address */
   if (rc != NO_ERROR) {
      printf("DosSetFilePtr error: return code = %u\n", rc);
      return 1;

   /* Read the first 100 bytes of the file */
   rc = DosRead (hfFileHandle,                /* File Handle */
                 uchFileData,                 /* String to be read */
                 100L,                        /* Length of string to be read */
                 &ulBytesRead);               /* Bytes actually read */

   if (rc != NO_ERROR) {
      printf("DosRead error: return code = %u\n", rc);
      return 1;
   } else {
      printf ("DosRead: Bytes read = %u\n%s\n", ulBytesRead, uchFileData);
   } /* endif */

   rc = DosClose(hfFileHandle);                /* Close the file */

   if (rc != NO_ERROR) {
      printf("DosClose error: return code = %u\n", rc);
      return 1;
   return NO_ERROR;

Related Functions