Main Content

La traducción de esta página aún no se ha actualizado a la versión más reciente. Haga clic aquí para ver la última versión en inglés.

Importar archivos de datos de texto con E/S de bajo nivel

Visión general

Las funciones de E/S de archivos de bajo nivel permiten el máximo control sobre la lectura o escritura de datos en un archivo. Sin embargo, estas funciones requieren que especifique información más detallada sobre el archivo que las funciones de alto nivel, más fáciles de usar, como importdata. Para obtener más información sobre las funciones de alto nivel que leen archivos de texto, consulte Importar archivos de texto.

Si las funciones de alto nivel no pueden importar los datos, utilice una de las siguientes opciones:

  • fscanf, que lee datos con formato de un archivo de texto o ASCII; es decir, un archivo que puede ver en un editor de texto. Para obtener más información, consulte Leer datos en un patrón con formato.

  • fgetl y fgets, que leen una línea de un archivo a la vez, donde un carácter de nueva línea separa cada línea. Para obtener más información, consulte Leer datos línea a línea.

  • fread, que lee un flujo de datos a nivel de byte o bit. Para obtener más información, consulte Import Binary Data with Low-Level I/O.

Para obtener más información, consulte:

Nota

Las funciones de E/S de archivos de bajo nivel se basan en funciones de la biblioteca de C estándar de ANSI®. Sin embargo, MATLAB® incluye versiones vectorizadas de las funciones, para leer y escribir datos en un arreglo con un mínimo de bucles de control.

Leer datos en un patrón con formato

Para importar archivos de texto que importdata y textscan no pueden leer, considere usar fscanf. La función fscanf requiere que describa el formato del archivo, pero incluye muchas opciones para la descripción de este formato.

Por ejemplo, cree un archivo de texto mymeas.dat como se muestra. Los datos de mymeas.dat incluyen conjuntos repetidos de horas, fechas y medidas. El texto del encabezado incluye el número de conjuntos de medidas, N:

Measurement Data
N=3

12:00:00
01-Jan-1977
4.21  6.55  6.78  6.55
9.15  0.35  7.57  NaN
7.92  8.49  7.43  7.06
9.59  9.33  3.92  0.31
09:10:02
23-Aug-1990
2.76  6.94  4.38  1.86
0.46  3.17  NaN   4.89
0.97  9.50  7.65  4.45
8.23  0.34  7.95  6.46
15:03:40
15-Apr-2003
7.09  6.55  9.59  7.51
7.54  1.62  3.40  2.55
NaN   1.19  5.85  5.05
6.79  4.98  2.23  6.99

Abrir el archivo

Al igual que con cualquiera de las funciones de E/S de bajo nivel, antes de leer, abra el archivo con fopen y obtenga un identificador de archivo. De forma predeterminada, fopen abre los archivos con acceso de lectura, con permiso de 'r'.

Cuando acabe de procesar el archivo, ciérrelo con fclose(fid).

Describir los datos

Describa los datos del archivo con especificadores de formato, como '%s' para texto, '%d' para un número entero o '%f' para un número de punto flotante. (Para obtener una lista completa de los especificadores, consulte la página de referencia de fscanf).

Para omitir caracteres literales en el archivo, inclúyalos en la descripción del formato. Para omitir un campo de datos, use un asterisco ('*') en el especificador.

Por ejemplo, considere las líneas de encabezado de mymeas.dat:

Measurement Data   % skip the first 2 words, go to next line:  %*s %*s\n
N=3                % ignore 'N=', read integer:  N=%d\n
                   % go to next line:  \n
12:00:00
01-Jan-1977
4.21  6.55  6.78  6.55
...

Para leer los encabezados y devolver el valor único para N:

N = fscanf(fid, '%*s %*s\nN=%d\n\n', 1);

Especificar el número de valores para leer

De forma predeterminada, fscanf vuelve a aplicar la descripción del formato hasta que no pueda hacer coincidir la descripción con los datos o hasta que llegue al final del archivo.

De forma opcional, especifique el número de valores para leer, para que fscanf no intente leer el archivo completo. Por ejemplo, en mymeas.dat, cada conjunto de medidas incluye un número fijo de filas y columnas:

measrows = 4;
meascols = 4;
meas  = fscanf(fid, '%f', [measrows, meascols])';

Crear variables en el espacio de trabajo

Hay varias formas de almacenar mymeas.dat en el espacio de trabajo de MATLAB. En este caso, lea los valores en una estructura. Cada elemento de la estructura tiene tres campos: mtime, mdate y meas.

Nota

fscanf llena arreglos con valores numéricos en el orden de la columna. Para hacer que el arreglo de salida coincida con la orientación de los datos numéricos de un archivo, transponga el arreglo.

filename = 'mymeas.dat';
measrows = 4;
meascols = 4;

% open the file
fid = fopen(filename);

% read the file headers, find N (one value)
N = fscanf(fid, '%*s %*s\nN=%d\n\n', 1);

% read each set of measurements
for n = 1:N
    mystruct(n).mtime = fscanf(fid, '%s', 1);
    mystruct(n).mdate = fscanf(fid, '%s', 1);

    % fscanf fills the array in column order,
    % so transpose the results
    mystruct(n).meas  = ...
      fscanf(fid, '%f', [measrows, meascols])';
end

% close the file
fclose(fid);

Leer datos línea a línea

MATLAB proporciona dos funciones que leen líneas de archivos y las almacenan como vectores de caracteres: fgetl y fgets. La función fgets copia la línea junto con el carácter de nueva línea en la salida, pero fgetl no.

El siguiente ejemplo usa fgetl para leer un archivo completo línea a línea. La función litcount determina si una determinada secuencia de caracteres (literal) aparece en cada línea. Si lo hace, la función imprime la línea completa precedida por el número de veces que aparece el literal en la línea.

function y = litcount(filename, literal)
% Count the number of times a given literal appears in each line.

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

Cree un archivo de datos de entrada llamado badpoem:

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

Para ver cuántas veces 'an' aparece en este archivo, llame a litcount:

litcount('badpoem','an')

Esto devuelve:

2: Oranges and lemons,
1: Pineapples and tea.
3: Orangutans and monkeys,
ans =
     6

Comprobar el final del archivo (EOF)

Al leer una parte de los datos en un momento dado, puede usar feof para comprobar si ha llegado al final del archivo. feof devuelve un valor de 1 cuando el puntero de archivo se encuentra al final del archivo. Si no, devuelve 0.

Nota

Abrir un archivo vacío no mueve el indicador de posición del archivo al final del mismo. Las operaciones de lectura y las funciones fseek y frewind mueven el indicador de posición del archivo.

Comprobar el EOF con feof

Cuando use textscan, fscanf o fread para leer partes de datos cada vez, use feof para comprobar si ha llegado al final del archivo.

Por ejemplo, suponga que el archivo hipotético mymeas.dat tiene el siguiente formato, sin información sobre el número de conjuntos de medidas. Lea los datos en una estructura con campos para mtime, mdate y meas:

12:00:00
01-Jan-1977
4.21  6.55  6.78  6.55
9.15  0.35  7.57  NaN
7.92  8.49  7.43  7.06
9.59  9.33  3.92  0.31
09:10:02
23-Aug-1990
2.76  6.94  4.38  1.86
0.46  3.17  NaN   4.89
0.97  9.50  7.65  4.45
8.23  0.34  7.95  6.46

Para leer el archivo:

filename = 'mymeas.dat';
measrows = 4;
meascols = 4;

% open the file
fid = fopen(filename);

% make sure the file is not empty
finfo = dir(filename);
fsize = finfo.bytes;

if fsize > 0 

    % read the file
    block = 1;
    while ~feof(fid)
        mystruct(block).mtime = fscanf(fid, '%s', 1);
        mystruct(block).mdate = fscanf(fid, '%s', 1);

        % fscanf fills the array in column order,
        % so transpose the results
        mystruct(block).meas  = ...
          fscanf(fid, '%f', [measrows, meascols])';

        block = block + 1;
    end

end

% close the file
fclose(fid);

Comprobar el EOF con fgetl y fgets

Si usa fgetl o fgets en un bucle de control, feof no siempre es la mejor manera de comprobar el final del archivo. Como alternativa, considere verificar si el valor que fgetl o fgets devuelven es un vector de caracteres.

Por ejemplo, la función litcount descrita en Leer datos línea a línea incluye el siguiente bucle while y las llamadas a fgetl:

y = 0;
tline = fgetl(fid);
while ischar(tline)
   matches = strfind(tline, literal);
   num = length(matches);
   if num > 0
      y = y + num;
      fprintf(1,'%d:%s\n',num,tline);
   end
   tline = fgetl(fid);
end

Este enfoque es más robusto que comprobar ~feof(fid) por dos razones:

  • Si fgetl o fgets encuentran datos, devuelven un vector de caracteres. Si no, devuelven un número (-1).

  • Después de cada operación de lectura, fgetl y fgets comprueban si el siguiente carácter del archivo es un marcador de fin de archivo. Por lo tanto, estas funciones a veces establecen el indicador de fin de archivo antes de devolver un valor de -1. Por ejemplo, considere el siguiente archivo de texto de tres líneas. Cada una de las dos primeras líneas termina con un carácter de nueva línea y la tercera línea contiene solo el marcador de fin de archivo:

    123
    456
    

    Tres llamadas seguidas a fgetl ofrecen los siguientes resultados:

    t1 = fgetl(fid);    % t1 = '123', feof(fid) = false
    t2 = fgetl(fid);    % t2 = '456', feof(fid) = true
    t3 = fgetl(fid);    % t3 = -1,    feof(fid) = true
    

    Este comportamiento no se ajusta a las especificaciones ANSI para las funciones de lenguaje C relacionadas.

Abrir archivos con cifrados de caracteres diferentes

Los esquemas de cifrado admiten los caracteres necesarios para alfabetos concretos, como los de las lenguas europeas o el japonés. Los esquemas de cifrado más frecuentes son US-ASCII o UTF-8.

Si no especifica un esquema de cifrado al abrir un archivo para lectura, fopen utiliza la detección automática del conjunto de caracteres para determinar la codificación. Si no especifica un esquema de cifrado al abrir un archivo para escritura, fopen utiliza de forma predeterminada UTF-8 para permitir la interoperabilidad entre todas las plataformas y configuraciones locales sin pérdida de datos ni daños.

Para determinar el valor predeterminado, abra un archivo y llame a fopen de nuevo con la sintaxis:

[filename, permission, machineformat, encoding] = fopen(fid);

Si especifica un esquema de cifrado al abrir un archivo, las siguientes funciones aplican dicho esquema: fscanf, fprintf, fgetl, fgets, fread y fwrite.

Para obtener una lista completa de los esquemas de cifrado admitidos y la sintaxis para especificar el cifrado, consulte la página de referencia de fopen.