Amiga C Tutorial

a) File Input and Output

Amiga DOS library includes some simple file i/o functions to open, read,write and close files. The following functions are commonly used:

BPTR Open( CONST_STRPTR name, LONG accessMode ); /* Open a file for read or write */
LONG Close( BPTR file ); /* Close a file */
LONG Read( BPTR file, APTR buffer, LONG length ); /* Read n bytes into a buffer (unbuffered) */
LONG Write( BPTR file, CONST APTR buffer, LONG length ); /* Write n bytes into a buffer (unbuffered) */
LONG Seek( BPTR file, LONG position, LONG offset ); /* Seek to a n bytes from current, beginning or end of file */
LONG FGetC( BPTR fh ); /* Get a character from file */
LONG FPutC( BPTR fh, LONG ch ); /* Write a character to file */
LONG UnGetC( BPTR fh, LONG character ); /* Return a character to buffer */
LONG FRead( BPTR fh, APTR block, ULONG blocklen, ULONG number ); /* Read a number of blocks from file (buffered) */
LONG FWrite( BPTR fh, CONST APTR block, ULONG blocklen, ULONG number ); /* Write a number of blocks to a file (buffered) */
STRPTR FGets( BPTR fh, STRPTR buf, ULONG buflen ); /* Gets a string from a file */
LONG FPuts( BPTR fh, CONST_STRPTR str ); /* Writes a string to a file */
VOID VFWritef( BPTR fh, CONST_STRPTR format, CONST LONG *argarray ); /* Write a BCPL formatted string to a file */
LONG VFPrintf( BPTR fh, CONST_STRPTR format, CONST APTR argarray ); /* Format and print a string to a file */
LONG Flush( BPTR fh ); /* Flush buffers to file */
LONG SetVBuf( BPTR fh, STRPTR buff, LONG type, LONG size ); /*Set buffering modes and size */

Amiga DOS supports buffered and unbuffered file I/O. Buffered file I/O is more efficient than unbuffered i/o for small files. FPuts and FGets would be ideal for getting lines of text from a text file with line feed or null terminated strings. FGetC and FPutC would be ideal for reading binary files. To detect End of File, most functions will return -1 (EOF), 0 or NULL values depending on the return value of the function, there is no EOF type function as in ANSI C. When opening a file, you need to specify the accessMode which can be MODE_OLDFILE (read an existing file), MODE_NEWFILE (create a new file for writing) or MODE_READWRITE (for read/writing to an existing file), the Open command returns a file handle of BPTR type which is used in most I/O functions.

The following example, will write out 20 numbers to a file, and read them back in and print them to the console.

/* File Example
   using DOS.library
   by PHutchison
   */
#include <proto/dos.h>
#include <stdio.h>
#include <stdlib.h>
/* Write some numbers to a file */
   void WriteNumbers(void) {
     BPTR fh;
     int n;
     UBYTE numstr[5];
   
     printf("Writing numbers to numbers.dat\n\n");
     /* Open file for writing */
     fh = Open("numbers.dat", MODE_NEWFILE);
     if (fh) {
       for (n=1; n<=20; n++) {
         /* Convert number to a string with new line
             & write string to file */
         sprintf(numstr, "%d\n", n);
         FPuts(fh, numstr);
        }
        Close(fh);
     } 
   }
/* Read numbers from a file */
void ReadNumbers(void) {
     BPTR fh;
     int i;
     UBYTE numstr[5];
     UBYTE *buffer;
   
     printf("Reading file numbers.dat.\n");
     /* Open existing file for reading */
     fh = Open("numbers.dat", MODE_OLDFILE);
     if (fh) {
        /* Read a string and check for End of File */
        while (buffer = FGets(fh, numstr, 5L)) {
            /* Convert string to number and print it */
            i = atoi(numstr);
            printf("Number %d\n", i);
        }
        Close(fh);
     }
     printf("EOF found\n");
}
int main(void)
   {
     WriteNumbers();
   
     ReadNumbers();
   
     return 0;
   }
 

For AmigaOS 4, prefix Open, FPuts, FGets, and Close with 'IDOS->'.
Compile using the command 'gcc -o fileexample fileexample.c -lauto'.

b) Reading files and directories in the file system.

To read files in AmigaOS is to examine the filesystem directory so you can see what files and directories or in a folder for instance. For example you want to read in a list of files and display the files in a list in your application interface.
There are a number of useful functions to help you with this:

AmigaOS 3.x or 4.x

BPTR lock = CreateDir( CONST_STRPTR name); /* Create a directory or folder */
int32 success = Delete (CONST_STRPTR name);
/* Delete a file, directory or symbolic link */
LONG Examine( BPTR lock, struct FileInfoBlock *fileInfoBlock ); /* Examine a directory, which is locked first */
LONG ExNext( BPTR lock, struct FileInfoBlock *fileInfoBlock );
/* Examine next file in a directory */
int32 success = Format(CONST_STRPTR filesystem, CONST_STRPTR volume, uint32 dostype);
int32 success = GetDiskFileSystemData(CONST_STRPTR name);
int32 success = GetDiskInfo(const struct TagItem *tags);
int64 filesize = GetFileSize(BPTR filehandle);
BPTR lock = GetProgramDir(VOID);
int32 success = Info(BPTR lock, struct InfoData *paramBlock);
BPTR lock = Lock( CONST_STRPTR name, int32 mode);
int32 error = MatchFirst( CONST_STRPTR str, struct AnchorPath *anchor);
int32 error = MatchNext( struct AnchorPath *anchor);
BPTR newlock = ParentDir(BPTR lock);
int32 success = Rename(
CONST_STRPTR oldname, CONST_STRPTR newname);
int32 rc = RunCommand(BPTR seglist, uint32 stacksize, CONST_STRPTR argptr, uint32 arglen);
int32 success = Comment(
CONST_STRPTR name, CONST_STRPTR comment);

AmigaOS 4.x(only):

BPTR lock = CreateDirTree( CONST_STRPTR name); /* Create a directory tree e.g. \Dir1\Dir2\Dir3 */
struct ExamineData *data = ExamineDir(APTR context); /* Examine a directory, a file at a time */
struct ExamineData *data = ExamineObject(struct TagList *tags); /* Examine a single file or directory */
APTR context = ObtainDirContext(const struct TagItem *tags);
ReleaseDirContext(APTR context);

Here is a routine to display a list of files within a directory.

int main(void)
{
char currdir[255] = "Work:";
char filename[255];
APTR context;
BPTR lock;
struct ExamineData *data;

if (!(lock = IDOS->Lock(currdir, ACCESS_READ))) {
   IDOS->PutStr("Failed to lock currect dir!\n");
   exit (5);
}
context = IDOS->ObtainDirContextTags(EX_LockInput, lock, TAG_END);

while ( data = IDOS->ExamineDir(context))
{
   if (! strstr(data->Name, ".info")) {
       strcpy (filename, data->Name);
       IDOS->PutStr(filename);
       IDOS->PutStr("\n");
   }
}

if (lock) IDOS->Unlock (lock);
IDOS->ReleaseDirContext(context);
return(0);
}

 


Next Page