Using Low-Level File I/O Functions

Overview

The MATLAB® product includes a set of low-level file I/O functions that are based on the I/O functions of the American National Standards Institute's ANSI® Standard C Library. If you know C, you are probably familiar with these routines.

To read or write data, perform these steps:

  1. Open the file, using fopen. fopen returns a file identifier that you use with all the other low-level file I/O routines.

  2. Operate on the file.

    1. Read binary data, using fread.

    2. Write binary data, using fwrite.

    3. Read text strings from a file line-by-line, using fgets or fgetl.

    4. Read formatted ASCII data, using fscanf.

    5. Write formatted ASCII data, using fprintf.

  3. Close the file, using fclose.

This section also describes how these functions affect the current position in the file where read or write operations happen and how you can change the position in the file.

Opening Files

Before reading or writing a text or binary file, you must open it with the fopen command.

fid = fopen('filename','permission')

Specifying the Permission String

The permission string specifies the kind of access to the file you require. Possible permission strings include:

Using the Returned File Identifier (fid)

If successful, fopen returns a nonnegative integer, called a file identifier (fid). You pass this value as an argument to the other I/O functions to access the open file. For example, this fopen statement opens the data file named penny.dat for reading:

fid = fopen('penny.dat','r')

If fopen fails, for example if you try to open a file that does not exist, fopen does the following:

Test the file identifier each time you open a file in your code. For example, this code loops until a readable filename is entered:

fid=0;
while fid < 1 
   filename=input('Open file: ', 's');
   [fid,message] = fopen(filename, 'r');
   if fid == -1
     disp(message)
   end
end

When you run this code, if you specify a file that doesn't exist, such as nofile.mat, at the Open file: prompt, the results are as follows:

Open file: nofile.mat
Sorry. No help in figuring out the problem . . .

If you specify a file that does exist, such as goodfile.mat, the code example returns the file identifier, fid, and exits the loop:

Open file: goodfile.mat

Opening Temporary Files and Directories

The tempdir and tempname functions assist in locating temporary data on your system.

Function

Purpose

tempdir

Get temporary directory name.

tempname

Get temporary filename.

Use these functions to create temporary files. Some systems delete temporary files every time you reboot the system. On other systems, designating a file as temporary can mean only that the file is not backed up.

The tempdir function returns the name of the directory or folder that has been designated to hold temporary files on your system. For example, issuing tempdir on The Open Group UNIX® systems returns the /tmp directory.

MATLAB also provides a tempname function that returns a filename in the temporary directory. The returned filename is a suitable destination for temporary data. For example, if you need to store some data in a temporary file, then you might issue the following command first:

fid = fopen(tempname, 'w');

Reading Binary Data

The fread function reads all or part of a binary file (as specified by a file identifier) and stores it in a matrix. In its simplest form, it reads an entire file and interprets each byte of input as the next element of the matrix. For example, the following code reads the data from a file named nickel.dat into matrix A:

fid = fopen('nickel.dat','r');
A = fread(fid);

To echo the data to the screen after reading it, use char to display the contents of A as characters, transposing the data so it is displayed horizontally:

disp(char(A'))

The char function causes MATLAB to interpret the contents of A as characters instead of as numbers. Transposing A displays it in its more natural horizontal format.

Controlling the Number of Values Read

fread accepts an optional second argument that controls the number of values read (if unspecified, the default is the entire file). For example, this statement reads the first 100 data values of the file specified by fid into the column vector A.

A = fread(fid,100);

Replacing the number 100 with the matrix dimensions [10 10] reads the same 100 elements into a 10-by-10 array.

Controlling the Data Type of Each Value

An optional third argument to fread controls the class of the input. The class argument controls both the number of bits read for each value and the interpretation of those bits as character, integer, or floating-point values. MATLAB supports a wide range of precisions, which you can specify with MATLAB specific strings or their C or Fortran equivalents.

Some common precisions include:

For example, if fid refers to an open file containing single-precision floating-point values, then the following command reads the next 10 floating-point values into a column vector A:

A = fread(fid,10,'float');

Writing Binary Data

The fwrite function writes the elements of a matrix to a file in a specified numeric precision, returning the number of values written. For instance, these lines create a 100-byte binary file containing the 25 elements of the 5-by-5 magic square, each stored as 4-byte integers:

fwriteid = fopen('magic5.bin','w');
count = fwrite(fwriteid,magic(5),'int32');
status = fclose(fwriteid);

In this case, fwrite sets the count variable to 25 unless an error occurs, in which case the value is less.

Controlling Position in a File

When you open a file with fopen, MATLAB maintains a file position indicator that specifies a particular location within a file. MATLAB uses the file position indicator to determine where in the file the next read or write operation will begin. The following sections describe how to:

Setting and Querying the File Position

The fseek and ftell functions enable you to set and query the position in the file at which the next input or output operation takes place:

The syntax for fseek is

status = fseek(fid,offset,origin)

fid is the file identifier for the file. offset is a positive or negative offset value, specified in bytes. origin is one of the following strings that specify the location in the file from which to calculate the position.

'bof'

Beginning of file

'cof'

Current position in file

'eof'

End of file

Example of Using fseek And ftell

To see how fseek and ftell work, consider this short M-file:

A = 1:5;
fid = fopen('five.bin','w');
fwrite(fid, A,'short');
status = fclose(fid);

This code writes out the numbers 1 through 5 to a binary file named five.bin. The call to fwrite specifies that each numerical element be stored as a short. Consequently, each number uses 2 storage bytes.

Now reopen five.bin for reading:

fid = fopen('five.bin','r');

This call to fseek moves the file position indicator forward 6 bytes from the beginning of the file:

status = fseek(fid,6,'bof');

This call to fread reads whatever is at file positions 7 and 8 and stores it in variable four:

four = fread(fid,1,'short');

The act of reading advances the file position indicator. To determine the current file position indicator, call ftell:

position = ftell(fid)

position = 

     8 

This call to fseek moves the file position indicator back 4 bytes:

status = fseek(fid,-4,'cof');

Calling fread again reads in the next value (3):

three = fread(fid,1,'short');

Reading Strings Line by Line from Text Files

MATLAB provides two functions, fgetl and fgets, that read lines from formatted text files and store them in string vectors. The two functions are almost identical; the only difference is that fgets copies the newline character to the string vector, but fgetl does not.

The following M-file function demonstrates a possible use of fgetl. This function uses fgetl to read an entire file one line at a time. For each line, the function determines whether an input literal string (literal) appears in the line.

If it does, the function prints the entire line preceded by the number of times the literal string appears on the line.

function y = litcount(filename, literal)
% Search for number of string matches per line.  

fid = fopen(filename, 'rt');
y = 0;
while feof(fid) == 0
   tline = fgetl(fid);
   matches = findstr(tline, literal);
   num = length(matches);
   if num > 0
      y = y + num;
      fprintf(1,'%d:%s\n',num,tline);
   end
end
fclose(fid);

For example, consider the following input data file called badpoem:

Oranges and lemons,
Pineapples and tea.
Orangutans and monkeys,
Dragonflys or fleas.

To find out how many times the string 'an' appears in this file, use litcount:

litcount('badpoem','an')
2: Oranges and lemons,
1: Pineapples and tea.
3: Orangutans and monkeys,

Reading Formatted ASCII Data

The MATLAB fscanf function is like the fscanf function in standard C. Both functions operate in a similar manner, reading data from a file and assigning it to one or more variables. Both functions use the same set of conversion specifiers to control the interpretation of the input data.

The conversion specifiers for fscanf begin with a % character; common conversion specifiers include the following.

Conversion Specifier

Description

%s

Match a string.

%d

Match an integer in base 10 format.

%g

Match a double-precision floating-point value.

You also can specify that fscanf skip a value by specifying an asterisk in a conversion specifier. For example, %*f means skip the floating-point value in the input data; %*d means skip the integer value in the input data.

Differences Between the MATLAB® fscanf and the C fscanf

Despite all the similarities between the MATLAB and C versions of fscanf, there are some significant differences. For example, consider a file named moon.dat for which the contents are as follows:

3.654234533
2.71343142314
5.34134135678

The following code reads all three elements of this file into a matrix named MyData:

fid = fopen('moon.dat','r');
MyData = fscanf(fid,'%g');
status = fclose(fid);

Notice that this code does not use any loops. Instead, the fscanf function continues to read in text as long as the input format is compatible with the format specifier.

An optional size argument controls the number of matrix elements read. For example, if fid refers to an open file containing strings of integers, then this line reads 100 integer values into the column vector A:

A = fscanf(fid,'%5d',100);

This line reads 100 integer values into the 10-by-10 matrix A:

A = fscanf(fid,'%5d',[10 10]);

A related function, sscanf, takes its input from a string instead of a file. For example, this line returns a column vector containing 2 and its square root:

root2 = num2str([2, sqrt(2)]);
rootvalues = sscanf(root2,'%f');

Writing Formatted Text Files

The fprintf function converts data to character strings and outputs them to the screen or a file. A format control string containing conversion specifiers and any optional text specify the output format. The conversion specifiers control the output of array elements; fprintf copies text directly.

Common conversion specifiers include

Conversion Specifier

Description

%e

Exponential notation

%f

Fixed-point notation

%g

Automatically select the shorter of %e and %f

Optional fields in the format specifier control the minimum field width and precision. For example, this code creates a text file containing a short table of the exponential function:

x = 0:0.1:1;
y = [x; exp(x)];

The code below writes x and y into a newly created file named exptable.txt:

fid = fopen('exptable.txt','w');
fprintf(fid,'Exponential Function\n\n');
fprintf(fid,'%6.2f  %12.8f\n',y);
status = fclose(fid);

The first call to fprintf outputs a title, followed by two carriage returns. The second call to fprintf outputs the table of numbers. The format control string specifies the format for each line of the table:

fprintf converts the elements of array y in column order. The function uses the format string repeatedly until it converts all the array elements.

Now use fscanf to read the exponential data file:

fid = fopen('exptable.txt','r');
title = fgetl(fid);
[table,count] = fscanf(fid,'%f %f',[2 11]);
table = table';
status = fclose(fid);

The second line reads the file title. The third line reads the table of values, two floating-point values on each line, until it reaches end of file. count returns the number of values matched.

A function related to fprintf, sprintf, outputs its results to a string instead of a file or the screen. For example:

root2 = sprintf('The square root of %f is %10.8e.\n',2,sqrt(2));

Closing a File

When you finish reading or writing, use fclose to close the file. For example, this line closes the file associated with file identifier fid:

status = fclose(fid);

This line closes all open files:

status = fclose('all');

Both forms return 0 if the file or files were successfully closed or -1 if the attempt was unsuccessful.

MATLAB automatically closes all open files when you exit from MATLAB. It is still good practice, however, to close a file explicitly with fclose when you are finished using it. Not doing so can unnecessarily drain system resources.

  


 © 1984-2008- The MathWorks, Inc.    -   Site Help   -   Patents   -   Trademarks   -   Privacy Policy   -   Preventing Piracy   -   RSS