13.1: Introduction
- Page ID
- 35864
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)
( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\id}{\mathrm{id}}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\kernel}{\mathrm{null}\,}\)
\( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\)
\( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\)
\( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)
\( \newcommand{\vectorA}[1]{\vec{#1}} % arrow\)
\( \newcommand{\vectorAt}[1]{\vec{\text{#1}}} % arrow\)
\( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vectorC}[1]{\textbf{#1}} \)
\( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)
\( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)
\( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)High level fileio in C uses functions such as fopen()
, fclose()
, fread()
, fwrite
, fprintf()
, fgetc()
, and so on. These utilize a variable of type FILE
to access disk files. They allow you to read and write data from/to files on disk in a manner very similar to sending data to the computer screen via printf()
or retrieving data from the keyboard via scanf()
.
Closer to home, we have low level fileio. These use a file descriptor, which is basically just an integer. High level functions actually call the low level functions anyway. There are five things you need to do with files. First, you open them to obtain access to an existing file or to create a new one. Next, you read or write data from/to the file. You may also need to move around in a file, perhaps to reread data or to skip over data. Finally, when you are finished using the file, you must close it. To open a file use:
fh = open( name, mode );
where
char *name: /* disk name of file */ int fh: /* file descriptor */ int mode; /* a define */
fh
is the file descriptor that is needed for subsequent read/write calls. It will be >= O
if all is OK, -1
on error.
Example modes:
O_RDONLY |
read only |
O_WRONLY |
write only |
O_CREAT |
create if not exists |
To read/write data, use:
count = read( fh, buffer, len ); count = write( fh, buffer, len );
fh
is the file descriptor returned from open()
, buffer
is the address of where to find/place data (i.e., the thing you’re copying to disk or making a copy of from disk), len
is the number of bytes to read/write, count
is the actual number of bytes read/written.
A common construct is:
if( (count = read( fh, buf, len )) != len ) { //...there was an error, process it... }
You can also skip around in a file:
apos = lseek( fh, rpos, mode );
where
long apos |
absolute position ( |
long rpos |
relative position |
mode |
|
Note that your present position is = lseek( fh, O, 1 );
When you are done with the file, you must close it:
error = close( fh );
error
is O
if all went OK, -1
otherwise.
C allows you to have multiple files open simultaneously for reading and writing. You will need one file descriptor for each file open at the same time (they can be reused later, if desired).
Below is a program that can be used to investigate the contents of almost any kind of file. It uses a variety of techniques that we have examined through the course. Some lines have wrapped.
/* headdump.c This program spits out the first 128 bytes of a file in hex, decimal, and string form (non printable chars are printed out as periods). */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #define CHUNKSIZE 128 unsigned char buf[CHUNKSIZE]; char *szerrmsgs[] = { "No errors on %s\n", "USAGE: %s <filename>\n", "Could not open %s\n", "Seek error on %s\n", "Position error on %s\n", "Rewind error on %s\n", "Read error on %s\n" }; void my_exit( FILE *fp, int err, char *pc ) { if( fp ) fclose( fp ); if( err ) printf( szerrmsgs[err], pc ); /* don't bother if all OK */ exit( err ); } void main( int argc, char *argv[] ) { int size, c=0, x; FILE *fp=0; if( (argc < 2) || ( !strcmp(argv[1], "?") ) ) my_exit( fp, 1, argv[0] ); if( fp = fopen( argv[1], "r" ) ) { /* Find out how big the file is. If it's < CHUNKSIZE then read in what's available */ if( -1 != fseek( fp, 0, 2 ) ) /* seek to end */ { if( -1 != (size = ftell( fp )) ) { if( size > CHUNKSIZE ) size = CHUNKSIZE; if( -1 != fseek( fp, 0, 0 ) ) /* seek to start */ { if( fread( buf, 1, size, fp ) == (unsigned int)size ) { /* print this out as 8 chars by 16 (or so) lines, first hex, then decimal, then string */ while( c < size ) { /* print out line as hex */ printf("%3d: %02x%02x %02x%02x %02x%02x %02x%02x ", c,buf[c],buf[c+1],buf[c+2],buf[c+3],buf[c+4],buf[c+5],buf[c+6],buf[c+7] ); /* print out line as decimal */ printf(" %03d%03d %03d%03d %03d%03d %03d%03d ", buf[c],buf[c+1],buf[c+2],buf[c+3],buf[c+4],buf[c+5],buf[c+6],buf[c+7] ); /* print out line as string. check the chars and if not printable, replace with periods */ for( x=0; x<8; x++ ) { if( !isprint( buf[c+x] ) ) buf[c+x] = '.'; } printf(" %c%c%c%c%c%c%c%c\n",buf[c],buf[c+1],buf[c+2], buf[c+3],buf[c+4],buf[c+5],buf[c+6], buf[c+7] ); c+=8; } } else my_exit( fp, 6, argv[0] ); } else my_exit( fp, 5, argv[0] ); } else my_exit( fp, 4, argv[0] ); } else my_exit( fp, 3, argv[0] ); } else my_exit( fp, 2, argv[1] ); my_exit( fp, 0, argv[1] ); }