로우 레벨 I/O 함수를 사용하여 텍스트 데이터 파일 가져오기
개요
로우 레벨 파일 I/O 함수를 사용하면 파일에서 데이터를 읽어오거나 파일에 데이터를 쓸 때 최대한 제어할 수 있습니다. 그러나 이런 함수를 사용할 때는 사용이 쉬운 하이 레벨 함수(예: importdata
)에 비해 파일에 더 자세한 정보를 지정해야 합니다. 텍스트 파일을 읽어오는 데 사용할 수 있는 하이 레벨 함수에 대한 자세한 내용은 텍스트 파일 가져오기 항목을 참조하십시오.
하이 레벨 함수가 데이터를 가져올 수 없는 경우 다음 중 하나를 사용하십시오.
fscanf
- 텍스트 편집기에서 볼 수 있는 파일(텍스트 파일이나 ASCII 파일)에서 형식 지정된 데이터를 읽어옵니다. 자세한 내용은 형식 지정된 패턴의 데이터 읽어오기 항목을 참조하십시오.fgetl
과fgets
- 파일의 라인을 한 번에 하나씩 읽어옵니다. 여기서 각각의 라인은 새 줄(Newline) 문자로 구분됩니다. 자세한 내용은 라인 단위로 데이터 읽어오기 항목을 참조하십시오.fread
- 바이트 또는 비트 수준에서 데이터 스트림을 읽어옵니다. 자세한 내용은 로우 레벨 I/O를 사용하여 이진 데이터 가져오기 항목을 참조하십시오.
추가적인 정보는 다음 항목을 참조하십시오.
참고
로우 레벨 파일 I/O 함수는 ANSI® 표준 C 라이브러리의 함수를 기반으로 합니다. 그러나 MATLAB®에서 사용하는 함수는 벡터화된 버전이며, 배열에서 데이터를 읽어오고 쓸 때 최소한의 제어 루프를 사용합니다.
형식 지정된 패턴의 데이터 읽어오기
importdata
와 textscan
이 읽어올 수 없는 텍스트 파일을 가져오려면 fscanf
를 사용해 보십시오. fscanf
함수를 사용하려면 파일의 형식을 설명해야 하는데, 이 함수에는 이러한 형식의 설명을 위한 여러 옵션이 포함되어 있습니다.
예를 들어, 아래와 같이 텍스트 파일 mymeas.dat
를 만듭니다. mymeas.dat
의 데이터에는 한 세트의 시간, 날짜, 측정값이 반복적으로 포함됩니다. 헤더 텍스트에는 측정값 세트의 개수 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
파일 열기
어느 로우 레벨 I/O 함수에서든 파일을 읽어오려면 먼저 fopen
을 사용하여 파일을 열고 파일 ID를 부여받아야 합니다. 기본적으로, fopen
은 'r'
의 권한을 가지고 읽기 목적으로 파일을 엽니다.
파일에 대한 작업을 마치면 fclose
(
를 사용하여 파일을 닫습니다.fid
)
데이터 설명(기술)하기
텍스트의 경우 '%s'
, 정수의 경우 '%d'
, 부동소수점 숫자의 경우 '%f'
등의 형식 지정자로 파일의 데이터를 설명합니다. 전체 지정자 목록을 보려면 fscanf
함수 도움말 페이지를 참조하십시오.
파일에서 리터럴 문자를 건너뛰려면 형식 설명에 이 리터럴 문자를 포함시키십시오. 데이터 필드를 건너뛰려면 지정자에 별표('*'
)를 사용하십시오.
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 ...
헤더를 읽고 N
에 대한 단일 값을 반환하는 방법은 다음과 같습니다.
N = fscanf(fid, '%*s %*s\nN=%d\n\n', 1);
읽어올 값의 개수 지정하기
기본적으로, fscanf
는 사용자의 형식 설명을 데이터에 일치시킬 수 없거나 파일 끝에 도달할 때까지 형식 설명을 다시 적용합니다.
선택적으로, fscanf
가 전체 파일 읽기를 시도하지 않도록 읽어올 값의 개수를 지정할 수 있습니다. 예를 들어, mymeas.dat
에 포함된 측정값 세트의 행과 열을 고정된 수로 지정합니다.
measrows = 4; meascols = 4; meas = fscanf(fid, '%f', [measrows, meascols])';
작업 공간에 변수 만들기
MATLAB 작업 공간에 mymeas.dat
를 저장하는 방법은 여러 가지가 있습니다. 여기에서는 값을 구조체로 읽어옵니다. 구조체의 각 요소에는 mtime
, mdate
, meas
의 세 개 필드가 있습니다.
참고
fscanf
는 배열을 열 순서대로 숫자형 값으로 채웁니다. 출력 배열이 파일의 숫자형 데이터의 방향과 일치하도록 하려면 배열을 전치하십시오.
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);
라인 단위로 데이터 읽어오기
MATLAB은 파일에서 라인을 읽어와 문자형 벡터로 저장하는 두 개의 함수, fgetl
및 fgets
를 제공합니다. fgets
함수는 라인을 새 줄(Newline) 문자와 함께 출력값에 복사하지만, fgetl
함수는 그렇지 않습니다.
다음 예제에서는 fgetl
을 사용하여 전체 파일을 한 번에 한 라인씩 읽어옵니다. litcount
함수는 지정된 문자 시퀀스(literal
)가 각 라인에 나타나는지 확인합니다. 이 함수는 주어진 문자 시퀀스가 발견된 모든 라인에 대해 그 앞에 리터럴이 나타난 횟수를 출력합니다.
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);
다음과 같이 badpoem
이라는 입력 데이터 파일을 만듭니다.
Oranges and lemons, Pineapples and tea. Orangutans and monkeys, Dragonflys or fleas.
이 파일에 'an'
이 나타나는 횟수를 확인하려면 다음과 같이 litcount
를 호출하십시오.
litcount('badpoem','an')
반환되는 결과는 다음과 같습니다.
2: Oranges and lemons, 1: Pineapples and tea. 3: Orangutans and monkeys, ans = 6
파일의 끝(EOF) 테스트하기
한 번에 데이터의 일부만 읽어오는 경우 feof
를 사용하여 파일 끝에 도달했는지 확인할 수 있습니다. feof
는 파일 포인터가 파일 끝에 도달하면 값 1
을 반환합니다. 그렇지 않으면, 0
을 반환합니다.
참고
빈 파일을 열면 파일 위치 표시자가 파일 끝으로 이동하지 않습니다. 읽기 작업을 하거나 fseek
및 frewind
함수를 사용하면 파일 위치 표시자의 위치가 바뀔 수 있습니다.
feof를 사용하여 EOF 테스트하기
textscan
, fscanf
, fread
중 하나를 사용하여 한 번에 데이터의 여러 부분을 읽는 경우, feof
를 사용하여 파일의 끝에 도달했는지 확인할 수 있습니다.
예를 들어, 가상의 파일 mymeas.dat
가 측정값 세트 개수에 대한 정보 없이 다음과 같은 형태를 취한다고 가정해 보겠습니다. mtime
, mdate
, 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
파일을 읽는 방법은 다음과 같습니다.
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);
fgetl 및 fgets를 사용하여 EOF 테스트하기
제어 루프에 fgetl
또는 fgets
를 사용하는 경우, feof
가 항상 파일 끝을 테스트하는 최선의 방법은 아닙니다. 대안으로서, fgetl
또는 fgets
가 반환하는 값이 문자형 벡터인지 확인하는 방법을 고려해 보겠습니다.
예를 들어, 라인 단위로 데이터 읽어오기에서 설명된 함수 litcount
는 다음과 같은 while
루프와 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
이 접근 방식은 다음과 같은 두 가지 이유로 ~feof(fid)
를 테스트하는 것보다 더 강력합니다.
fgetl
또는fgets
는 데이터를 찾으면 문자형 벡터를 반환합니다. 그렇지 않으면, 숫자(-1
)를 반환합니다.각각의 읽기 작업 후,
fgetl
과fgets
는 파일의 바로 다음에 오는 문자에 파일 끝(EOF) 마커가 있는지 확인합니다. 따라서, 어떤 경우에는 값-1
을 반환하기 전에 파일 끝 마커를 설정하기도 합니다. 예를 들어, 다음과 같이 세 라인으로 구성된 텍스트 파일이 있다고 가정하겠습니다. 처음 두 개 라인은 각각 새 줄(Newline) 문자로 끝나고, 세 번째 라인에는 파일 끝(EOF) 마커만 있습니다.123 456
fgetl
을 3회 순차적으로 호출하면 다음과 같은 결과가 생성됩니다.t1 = fgetl(fid); % t1 = '123', feof(fid) = false t2 = fgetl(fid); % t2 = '456', feof(fid) = true t3 = fgetl(fid); % t3 = -1, feof(fid) = true
이 동작은 관련 C 언어 함수에 대한 ANSI 사양을 준수하지 않습니다.
다양한 문자 인코딩으로 파일 열기
인코딩 체계는 일본어나 유럽어의 자모와 같은 특정 자모에 필요한 문자를 지원합니다. 일반 인코딩 체계에는 US-ASCII 또는 UTF-8이 포함됩니다.
읽기를 위해 파일을 열 때 인코딩 체계를 지정하지 않으면 fopen
은 자동 문자 집합 감지를 사용하여 인코딩을 확인합니다. 쓰기를 위해 파일을 열 때 인코딩 체계를 지정하지 않으면 fopen
은 데이터 손실이나 손상 없이 모든 플랫폼과 로캘 간 상호 운용성을 제공하기 위해 기본적으로 UTF-8을 사용하도록 설정됩니다.
디폴트 값을 확인하려면 파일을 열고 다음 구문을 사용하여 fopen
을 다시 호출하십시오.
[filename, permission, machineformat, encoding] = fopen(fid);
파일을 열 때 인코딩 체계를 지정하면 fscanf
, fprintf
, fgetl
, fgets
, fread
, fwrite
와 같은 함수는 해당 체계를 적용합니다.
지원되는 인코딩 체계의 전체 목록과 인코딩을 지정하기 위한 구문은 fopen
함수 도움말 페이지를 참조하십시오.