Main Content

이 번역 페이지는 최신 내용을 담고 있지 않습니다. 최신 내용을 영문으로 보려면 여기를 클릭하십시오.

로우 레벨 I/O 함수를 사용하여 텍스트 데이터 파일 가져오기

개요

로우 레벨 파일 I/O 함수를 사용하면 파일에서 데이터를 읽어오거나 파일에 데이터를 쓸 때 최대한 제어할 수 있습니다. 그러나 이런 함수를 사용할 때는 사용이 쉬운 하이 레벨 함수(예: importdata)에 비해 파일에 더 자세한 정보를 지정해야 합니다. 텍스트 파일을 읽어오는 데 사용할 수 있는 하이 레벨 함수에 대한 자세한 내용은 텍스트 파일 가져오기 항목을 참조하십시오.

하이 레벨 함수가 데이터를 가져올 수 없는 경우 다음 중 하나를 사용하십시오.

추가적인 정보는 다음 항목을 참조하십시오.

참고

로우 레벨 파일 I/O 함수는 ANSI® 표준 C 라이브러리의 함수를 기반으로 합니다. 그러나 MATLAB®에서 사용하는 함수는 벡터화된 버전이며, 배열에서 데이터를 읽어오고 쓸 때 최소한의 제어 루프를 사용합니다.

형식 지정된 패턴의 데이터 읽어오기

importdatatextscan이 읽어올 수 없는 텍스트 파일을 가져오려면 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은 파일에서 라인을 읽어와 문자형 벡터로 저장하는 두 개의 함수, fgetlfgets를 제공합니다. 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을 반환합니다.

참고

빈 파일을 열면 파일 위치 표시자가 파일 끝으로 이동하지 않습니다. 읽기 작업을 하거나 fseekfrewind 함수를 사용하면 파일 위치 표시자의 위치가 바뀔 수 있습니다.

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)를 반환합니다.

  • 각각의 읽기 작업 후, fgetlfgets는 파일의 바로 다음에 오는 문자에 파일 끝(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 함수 도움말 페이지를 참조하십시오.