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
yfgets
, 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
ofgets
encuentran datos, devuelven un vector de caracteres. Si no, devuelven un número (-1
).Después de cada operación de lectura,
fgetl
yfgets
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
.