압축

tar 압축

  tar -cvf [파일명.tar] [폴더|파일명]

  # a 라는 폴더를 a.tar로 압축
  tar -cvf a.tar a

tar 압축 해제

  tar -xvf [파일명.tar]

  # a.tar라는 tar 파일 압축해제 예시
  tar -xvf a.tar
option desc
-c compress 압축
-x extract 해제, 추출
-z gzip으로 작업
-v 작업 과정의 파일들 command line에 출력
-f 파일 이름 지정
-p 파일 권한 저장
-C 대상 경로 지정

tar.gz 압축

  tar -zcvf [파일명.tar.gz] [폴더|파일명]

  # a라는 폴더를 a.tar.gz으로 압축
  tar -zcvf a.tar.gz a

tar.gz 압축 해제

  tar -zxvf [파일명.tar.gz]

  # a.tar.gz라는 tar.gz 파일 압축 해제
  tar -zxvf a.tar.gz

zip 압축

  zip [파일명.zip] [폴더|파일명]

  # 현재폴더 전체를 a.zip으로 압축
  zip a.zip ./*

  # a.zip으로 압축하고 현재 폴더의 모든 것과 현재 폴더의 **하위 폴더들**도 모두 압축
  zip a.zip -r ./*

zip 압축 해제

  unzip [파일명.zip]

  # a.zip 압축 해제
  unzip a.zip

  # 특정 폴더에 압축 해제
  unzip a.zip -d ./경로

728x90
반응형

리눅스나 MacOS 는 tail 함수가 내장 되어 있기 때문에 서버의 로그를 실시간으로 보는 법은 간단하다.

Window의 경우는 cmd 상에서 명령어가 있긴 하지만, 버젼에 따라 없거나, 옵션 값도 달라지고 cli의 ux가 좋지 않기 때문에 차라리 써드파티 어플리케이션을 사용하는 게 낫다.

mtail 이라는 프로그램인데, 설치는 필요 없고, 아래 링크에서 다운로드 후 압축을 풀고 실행, 대상 파일을 불러와 주기만 하면 된다.

 

프로그램 다운로드 -> http://ophilipp.free.fr/op_tail.htm

728x90
반응형

linux에서 log 통계 내는 명령어

Linux 서버에서 서버를 운영하다 보면, 시간대별 유입 건수, 특정 ip의 접속 건수, http 에러가 몇 건인지 파악하기 위해 access 로그를 이용하여 접속 통계가 필요한 경우가 있다.

 

ip별 접속 건수 확인

cat 파일_이름 | awk '{print $1}' | sort | uniq -c | sort -n

awk '{print $1}'은 각 라인에서 첫번째 값(IP)을 의미 한다.
uniq -c는 해당 라인이 몇번 나오는지를 카운트 한다.

만약 line 수가 많아 일정 횟수 이상만 확인하고 싶다면, `| awk '$1 >= 500' 조건을 추가해 준다.

 

시간대별 접속 건수 확인

cat 파일_이름 | awk '{print $4}' | awk -F ":" '{print $2}' | uniq -c

awk '{print $4}'는 각 라인의 4번째 필드인 시간을 추출한 뒤,
추출한 필드를 다시 ":"를 구분자로 2번째 필드(시간)을 추출하여 그 카운트를 센다.

 

HTTP 결과 코드별 접속 건수 구하기

cat 파일_이름 | awk '{print $9}' | sort | uniq -c

awk '{print $9}' 9번째 필드인 http 결과 코드를 추출하여 정렬 후, 그 카운트를 센다.

 

완성 예제 스크립트 파일

  _date=`date "+%Y-%m-%d"`
  tgt=localhost_access_log.$_date.txt

  echo -e "\nTARGET FILE : $tgt\n"

  echo -e ":: COUNT OF ACCESS IP ::"
  cat $tgt | awk '{print $1}' | sort | uniq -c | sort -n | awk '$1 >= 500'

  echo -e "\n:: COUNT OF ACCESSER BY HOUR ::"
  cat $tgt | awk '{print $4}' | awk -F ":" '{print $2}' | uniq -c

  echo -e "\n:: COUNT OF HTTP STATUS CODE ::"
  cat $tgt | awk '{print $9}' | sort | uniq -c

  echo -e "\n\n"

 

이를 3일치를 뽑으면 다음과 같다.

  SET=$(seq 0 3)

  function dateLogPrinter() {
    local _date=$1

    echo -e "\n----- DATE : $_date -----"

    echo -e ":: COUNT OF ACCESS IP ::"
    cat localhost_access_log.$_date.txt | awk '{print $1}' | sort | uniq -c | sort -n | awk '$1 >= 500'

    echo -e "\n:: COUNT OF ACCESSER BY HOUR ::"
    cat localhost_access_log.$_date.txt | awk '{print $4}' | awk -F ":" '{print $2}' | uniq -c

    echo -e "\n:: COUNT OF HTTP STATUS CODE ::"
    cat localhost_access_log.$_date.txt | awk '{print $9}' | sort | uniq -c

    echo -e "\n\n"

  }


  for i in $SET
  do
    dateLogPrinter `date -d "-$i days" "+%Y-%m-%d"`
  done

기타

특정 기간 지난 로그 파일 찾아 지우기.

find -name '*.out' -mtime +200 | xargs rm
out으로 끝나는 파일중 200일이 지난 파일을 찾아 지운다.

  

압축된 로그파일 출력하기

catzcat 으로 바꿔서 위와 같은 명령을 수행하면 됨.

 


참고

728x90
반응형

조달청/나라장터 iframe 링크 생성

공공 SI를 진행하다 보면 조달청/나라장터 데이터를 iframe으로 넣어 달라는 요구 사항이 있다.
처음에는 어떻게 하는지 몰라서 한참 삽질 했는데,
나중에 알고보니 iframe용 url 생성하는 서비스가 따로 있었다.
그건 여기

728x90
반응형

인덱스 리빌드

DB의 쿼리 수행 속도 저하의 문제 중 하나는 쿼리 튜닝이 문제일 수도 있지만, 인덱스의 밸런스가 깨졌을 경우의 가능성도 있다.
인덱스 밸런스가 깨졌다는게 무슨 의미냐 하면,
DB는 ArrayList와 트리를 합쳐 놓은 구조와 비슷한 B+트리 구조인데, 트리 아래의 데이터들이 무작위로 수정되거나 삭제 되었을 경우 트리 구조가 불균형을 이루게 된다.

이런 경우 인덱스를 재구성 해주면 쿼리 수행 속도를 향상 시킬 수 있다.
(물론 튜닝이 잘 된 쿼리를 짜는게 중요하다.)

오라클의 인덱스 재설정 쿼리는 ALTER INDEX 인덱스명 REBUILD;이고,
인덱스 명을 조회하는 쿼리는 SELECT INDEX_NAME FROM USER_INDEXED;이다.
그리고 인덱스의 데이터 타입이 LOB이라면 인덱스 리빌드는 불가능 하다.

따라서 이 두 쿼리를 조합하고, 조건을 추가하면 리빌드 하는 쿼리는 다음과 같다.

SELECT 'ALTER INDEX ' || INDEX_NAME || ' REBUILD ;'
FROM USER_INDEXES
WHERE INDEX_TYPE != 'LOB'
;

경험상 CUBRID나 TIBERO 도 동일했던 것 같다.

참고 : https://docs.oracle.com/database/121/SPATL/alter-index-rebuild.htm#SPATL1017

 
 
728x90
반응형

url을 a 태그로 변환하기

딱히 좋은 방법은 아닌거 같긴 한데 급할때는 최선인듯 하다.

    function parseUrl(orgnTxt) {
      var rplcdTxt, rplcdPttrn1, rplcdPttrn2, rplcdPttrn3;

      //  http://, https://로 url이 시작한다면.
      rplcdPttrn1 = /(\b(https?):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
      rplcdTxt = orgnTxt.replace(rplcdPttrn1, '<a href="$1" target="_blank">$1</a>');
      console.info('rplcdTxt : ', rplcdTxt);

      //  http?없이 www로 시작한다면.
      rplcdPttrn2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
      rplcdTxt = rplcdTxt.replace(rplcdPttrn2, '$1<a href="http://$2" target="_blank">$2</a>');
      console.info('rplcdTxt : ', rplcdTxt);

      //  메일 주소일 경우
      rplcdPttrn3 = /(([a-zA-Z0-9\-\_\.])+@[a-zA-Z\_]+?(\.[a-zA-Z]{2,6})+)/gim;
      rplcdTxt = rplcdTxt.replace(rplcdPttrn3, '<a href="mailto:$1">$1</a>');
      console.info('rplcdTxt : ', rplcdTxt);

      return rplcdTxt;
    }
728x90
반응형

'Language > JavaScript' 카테고리의 다른 글

[javascript] HTML form to JSON object  (0) 2022.08.08
[JS] 페이지 리로드  (0) 2021.06.07
windows 10 NVM 과 nodejs 설치하기  (0) 2020.12.09
[JS] 날짜 비교  (0) 2020.11.11
[Modern JS] 동기 처리를 위한 Async Await  (0) 2020.06.14

대상 서버의 포트가 열려있는지 확인하는 방법

부제 ) telnet 없이 포트 오픈 확인하는 방법

대부분의 서버는 보안 문제로 ssh나 http, telnet 을 사용할 수 없는 경우가 있다.

이런 경우에 대상 버의 포트가 열려 있는지 확인 하는 방법에 대해서 삽질하다, 잊으면 안될것 같아서 남겨본다.

Linux의 경우이다.

echo > /dev/tcp/IP/PORT

bash의 내장 기능으로 자세한 내용은 여기 에서 확인 할 수 있다.
포트가 열린 경우라면, 아무 메세지가 나오지 않는다. echo $? 해보면 정상적인 프로세스의 종료를 의미하는 0이 나온다.
포트가 닫힌 경우라면, 에러메세지가 나오고 echo $?의 결과가 1이 나온다.

포트가 열린 경우

    $ echo > /dev/tcp/127.0.0.1/22
    $ echo $?
    0

포트가 닫힌 경우

    $ echo > /dev/tcp/127.0.0.1/10002
    bash: connect: 연결이 거부됨
    bash: /dev/tcp/127.0.0.1/10002: 연결이 거부됨
    $ echo $?
    1

curl -v telnet://IP:PORT

curl의 파라미터중 url에 telnet 스키마가 허용된다.

포트가 열린 경우

    $ curl -v telnet://IP:PORT
    * About to connect() to IP port PORT (#0)
    *   Trying IP... connected
    * Connected to IP (IP) port PORT (#0)

포트가 닫힌 경우

    $ curl -f telnet://IP:PORT
    curl: (7) couldn't connect to host
728x90
반응형

'OS > Linux' 카테고리의 다른 글

[Linux] 파일 압축 및 해제  (0) 2021.03.20
[Linux etc tip] 접속 로그 분석 하기  (0) 2021.02.15
[Linux] 웹 서버  (0) 2020.12.13
[Linux] 원격 관리  (0) 2020.12.13
[Linnux] 네트워크 설정 및 점검  (0) 2020.12.05

메모리 동적 할당

메모리 정/동적 할당의 개념과 동적할당함수의 기능과 사용법, 메모리 관리 함수.

  • 학습 목표
    1. 메모리 정적할당과 동적할당의 이해.
    2. 메모리 동적할당함수를 이용하여 프로그램 작성.
    3. 메모리 관리함수의 기능 이해.

주요 용어

  • 데이터 영역 : 전역변수와 static 변수가 저장되는 기억공간 영역.
  • 힙(heap) 영역 : 프로그래머의 필요에 의해 할당과 소멸이 이루어지는 기억공간 영역.
  • 스택(stack) 영역 : 지역변수와 매개변수가 저장되는 기억공간 영역.
  • 메모리 정적할당 : 프로그램이 작성되는 단계에서 기억공간의 크기가 결정되는 기억공간 확보방법.
  • 메모리 동적할당 : 프로그램이 실행되는 중에 입력되는 자료에 따라 기억공간의 크기를 결정할 수 있는 기억공간 확보방법.

메모리 동적할당의 개념

C 언어에서의 기억공간?

  • 프로그램의 실행을 위해 기억공간 필요.
  • 기억공간은 운영체제에서 할당.
  • 할당되는 기억공간의 영역.
    • 데이터 영역.
      • 전역변수와 static 변수가 저장되는 영역.
      • 프로그램이 시작하면서 할당되고, 종료하면 소멸하게 됨.
    • 힙 영역
      • 개발자의 필요에 의해 할당/소멸이 이루어지는 영역.
      • 프로그램이 실행되는 중에 크기가 변함.
      • 메모리 동적 할당에 사용되는 영역.
    • 스택 영역
      • 지역변수와 매개변수가 저장되는 영역.
      • 함수 호출이 완료되면 사라짐.

기억공간의 확보

메모리 정적 할당(Static Allocation)

  • 기억공간의 데이터 영역스택 영역 이용.
  • 프로그램을 작성하는 단계에서 필요한 기억공간의 크기를 결정.

메모리 동적 할장(Dynamic Allocation)

  • 기억공간의 힙 영역 이용.
  • 프로그램 실행 중에 입력되는 자료에 맞게끔 기억공간의 크기를 결정.

메모리 정적할당

  • 변수 선언이나 배열 선언과 같이 프로그램을 작성하는 단계에서 필요한 기억 공간의 크기를 결정.
    • 변수 선언과 같이 할당 시켜줘야 할 기억공간의 한계 크기를 명확히 알고 있을 경우 사용.
    • 메모리 정적 할당은 프로그램이 시작될 때 미리 기억공간의 크기를 고정하여 할당.

메모리 정적할당의 예

  #include <stdio.h>

  void test1(int);
  void test2(int);

  //  전역변수로 선언되어 데이터 영역에 할당.
  //  프로그램 종료될 때까지 존재.
  int a = 100;

  void main()
  {
    //  지역변수로 스택 영역에 할당.
    //  main()가 종료될 때까지 존재.
    int b = a;

    test1(b);
    test2(b);
  }

  //  test1이 호출되면,
  //  매개변수 c와 지역변수 d는 스택영역에 할당.
  //  test1이 종료되면 c, d는 지워짐.
  void test1(int c)
  {
    int d;
    d = c + 10;
    printf("%d\n", d);
  }

  //  test2가 호출되면,
  //  매개변수 e와 지역변수 f는 스택영역에 할당.
  //  종료되면 d, f는 지워짐.
  void test2(int e)
  {
    int f;
    f = e + 20;
    printf("%d\n", f);
  }

  //  main()가 종료되면 스택영역에 할당된 b도 제거.
  //  프로그램이 끝아면 a도 제거.

메모리 정적할당의 장/단점

  • 장점
    • 프로그램에서 사용하게 될 변수의 기억 공간의 크기를 명확히 알고 있다면,
      메모리 정정할당은 쉽게 기억 공간을 사용할 수 있고, 에러의 발생 확률을 줄일 수 있음.
  • 단점
    • 사용하게 될 기억 공간의 크기를 정확히 알지 못하거나, 사용되는 자료의 크기가 각각 차이가 심하다면,
      기억공간의 낭비를 가져오게 됨.

메모리 정적할당의 문제점

  #include <stdio.h>

  void main()
  {
    int size;
    //  배열의 크기를 변수로 선언하면 에러 발생?
    char a[size];

    printf("입력할 문자열의 크기? : ");
    scanf("%d", &size);

    printf("주소 : ");
    scanf("%s", a);

    printf("입력된 주소 %s\n", a);
  }
  #include <stdio.h>
  #include <stdlib.h>

  void main()
  {
    int size;
    char *a;

    printf("입력할 문자열의 크기? : ");
    scanf("%d", &size);

    //  메모리 동적할당.
    a = (char *)malloc(sizeof(char) * size);
    printf("주소 : ");
    scanf("%s", a);

    printf("입력된 주소 %s\n", a);
    free(a);
  }

메모리 동적할당 함수

malloc(), calloc(), realloc(), free() 등

메모리 동적할당의 장/단점

  • 힙 영역을 이용하여 프로그램 실행 중에 입력되는 자료의 크기에 맞게 기억 공간 확보.
  • 많은 자료를 처리하는 배열의 크기를 실행 시간에 정의해야 하는 경우에 유용.
  • 프로그램 실행 시 기억 공간의 크기를 지정/재조정 가능.
  • 시간이 지체되는 단점.

메모리 동적할당 순서

  • 기억공간을 동적으로 할당 받을 변수를 포인터를 이용하여 선언.
  • malloc() 등을 이용하여 기억공간을 동적으로 할당 가능.
  • 기억공간의 사용이 끝나면 free()를 이용하여 기억공간 해제.

malloc()

  • 인자로 할당 받고자 하는 기억 공간의 크기를 byte 단위로 전달.
  • 힙 영역에 그 크기만큼 기억 공간을 할당, 할당한 기억공간의 첫 번째 주소 반환.
  • void*로 명시하여 어떤 형이든 형 변환 가능.
  • 초기화 안됨(기억공간의 초기화를 위해서는 memset() 사용).
  • 형식 : void * malloc(size_t, number_of_bytes);
  • 기능 : number_of_bytes에서 주어지는 크기만큼 기억 공간을 동적으로 할당.
  • 예 : void * malloc(sizeof(int));

free()

  • 메모리 해제 함수.
    • 힙 영역에 할당된 공간은 프로그램이 종료될 때까지 유지됨.
    • 할당된 기억 공간을 해제하지 않으면, 공간 부족 현상 발생.
    • 명시적인 반남.
  • 형식 : void free(void *p);
  • 기능 : 동적으로 할당된 기억 공간을 해제할 때 사용.

메모리 동적할당 예 - 1

  #include <stdio.h>
  #include <stdlib.h>

  void main()
  {
    //  1) 동적할당을 위한 포인터변수 선언.
    int *a;
    //  2) 기억공간 할당,
    //    - (int *)는 왼쪽의 포인터변수 a와 자료형을 일치시키기 위한
    //      강제 형변환.
    a = (int *)malloc(sizeof(int));

    if (a == NULL)
    {
      puts("FAILLURE OF ALLOCATION!");
      exit(1);
    }

    *a = 20;
    printf("VARIABLE a : %d\n", *a);
    //  3) 할당받은 기억공간 해제.
    free(a);
  }

메모리 동적할당 예 - 2

  #include <stdio.h>
  #include <stdlib.h>
  #pragma warning(disable : 4996)

  void main()
  {
    //  입력받을 문자 수 저장 변수 선언.
    int size;
    // 1) 동적 할당된 기억공간을 연결할 포인터.
    char *str;

    printf("INSERT SIZE OF STRING : ");
    scanf("%d", &size);

    // 2) 입력 받을 문자 수(size + 1)에 맞게 동적 할당.
    str = (char *)malloc(size + 1);

    if (str == NULL)
    {
      puts("FAILLURE OF ALLOCATION!");
      exit(1);
    }

    printf("INSERT STRING : ");
    // 동적으로 할당된 기억공간에 문자열 저장.
    scanf("%s", str);

    printf("STRING THAT SAVED AT DYNAMIC MEMORY : \n%s\n", str);

    // 3) 할당받은 기억공간 해제.
    free(str);
  }

calloc()

  • malloc()와 동일하게 힙 영역에 기억공간 할당.
  • 사용하는 형태와 할당된 기억 공간을 0으로 초기화.
  • 형식 : void * calloc( int n, int size );
  • 기능 : 주어진 size의 크기를 갖는 기억 공간 n개를 할당.
  • 예 : void * calloc( n, sizeof(int));
  #include <stdio.h>
  #include <stdlib.h>

  void main()
  {
    int i;
    int *a;

    // int형 크기의 기억공간 5개 할당.
    a = (int *)calloc(5, sizeof(int));

    for (i = 0; i < 5; i++)
    {
      //  0으로 초기화 되어 있음.
      printf("%d\n", a[i]);
    }

    free(a);
  }

realloc()

  • 이미 할당 받은 기억 공간의 크기를 변경해야 할 필요가 있을 때 사용.
  • 형식 : void * realloc( void *p, int size);
  • 기능 : 포인터 p가 가리키고 있는 기억공간의 크기를 지정된 size의 크기로 변경.
  int *a;
  //  int형 크기의 5개 기억공간 할당.
  a = (int *)calloc(5, sizefo(int));
  ...
  //  int형 크기의 10개 기억공간 재할당.
  a = (int *) realloc(a, 10 * sizeof(int));

기억공간 관리함수

memcmp(), memcpy(), memset()

memcmp()

  • 기억 공간에 들어 있는 자료를 주어지는 크기만큼 비교하여, 같은지 여부를 알 수 있게 해주는 함수.
  • 형식 : int memcmp( void *s1, void *s2, size_t n);
  • 기능 : s1, s2가 가리키고 있는 기억 공간의 내용을 n byte 만큼 비교.
    • n바이트만큼 비교하여 s1 > s2 면 양수, s1 < s2 면 음수, s1 == s2 면 0 반환.
  #include <stdio.h>
  //  기억공간 관리함수를 위한 헤더파일.
  // #include <mem.h>
  #include <memory.h>

  void main() {
    char *s1 = "aaa";
    char *s2 = "bbb";

    int stat;

    stat = memcmp(s1, s2, 3);

    printf("%d\n", stat);
  }

memcpy()

  • 기억 공간의 자료를 다른 기억 공간 영역으로 복사하기 위한 함수.
  • 형식 : void * memcpy( void *dest, const void * src, size_t n);
  • 기능 : src에서 n byte만큼 dest에 복사.
  #include <stdio.h>
  #include <memory.h>
  #include <string.h>

  void main()
  {
    char src[] = "1234567890";
    char dest[] = "abcdefghijklmnopqrstuvwxyz";
    char *stat;

    printf("BEFORE MEMCPY() DEST : %s\n", dest);

    //  src의 첫 부분에서부터 문자열의 길이(strlen())만큼의 자료를 dest에 복사.
    stat = (char *)memcpy(dest, src, strlen(src));

    if (stat)
      printf("AFTER MEMCPY() DEST : %s\n", dest);
    else
      printf("FAILURE ON MEMCPY()!");
  }
  //  BEFORE MEMCPY() DEST : abcdefghijklmnopqrstuvwxyz
  //  AFTER MEMCPY() DEST : 1234567890klmnopqrstuvwxyz

memset()

  • 기억 공간의 자료를 지정한 문자로 채우는 함수.
  • 할당된 기억 공간의 초기화나 내용 삭제를 위해 주로 사용.
  • 형식 : void * memset( void *s, int c, size_t n );
  • 기능 : 포인터 s가 가리키는 곳을 c 값으로 n byte 만큼 채운다.
  #include <stdio.h>
  #include <memory.h>
  #include <string.h>

  void main()
  {
    char s[] = "1234567890";

    printf("BEFORE MEMSET() : %s\n", s);

    //  배열 s의 데이커를 *로 길이 만큼 채움.
    memset(s, '*', strlen(s));

    printf("AFTER MEMSET() : %s\n", s);
  }

728x90
반응형

'Language > C' 카테고리의 다른 글

[C] 파일 처리 함수 - 2  (0) 2021.01.02
[C] 파일 처리 함수 - 1  (0) 2021.01.01
[C] 구조체와 공용체 - 2  (0) 2021.01.01
[C] 구조체와 공용체 -1  (0) 2020.12.27
[C] 배열과 포인터 - 3  (0) 2020.12.27

파일 처리 함수 - 2

순차파일 입출력함수와 랜덤파일 입출력함수, 랜덤파일의 위치제어.

  • 학습 목표
    1. 순차파일을 만들고 읽기.
    2. 랜덤파일 만들고 읽기.
    3. 랜덤파일의 위치 제어.

주요 용어

  • 레코드(record) : 파일을 구성하는 논리적인 기본 단위.
  • 텍스트 모드(textmode) : \n과 CR/LF 사이의 변환과정을 거치는 파일 모드.
  • 2진 모드(binary mode) : \n과 CR/LF 사이의 변환과정 없는 파일 모드.
  • 랜덤파일의 위치제어 : fseek()를 사용하여 랜덤파일의 특정부분을 입출력하는 것..

순차파일 입출력 함수

순차파일 출력함수

만들어진 파일에 자료를 기록하는 함수.

  • putc(), fputc(), fputs(), fprintf()

putc()

  • 문자 단위의 파일 출력함수.
  • fputc()와 유사.
  • 형식 : putc(문자변수, 파일포인터변수);
  • 사용 예 : putc(c, fp);
  • 기능 : fp가 가리키는 파일에 변수 c에 있는 문자 출력.
  #include <stdio.h>
  #include <stdlib.h>

  void main()
  {
    //  파일 포인터 선언
    FILE *fp;
    char c;

    // 파일 생성이므로 텍스트 쓰기모드로 오픈.
    fp = fopen("putc.tt.txt", "w");

    //  파일 개방 여부 체크. -> 에러메세지와 프로그램 종료.
    if (fp == NULL)
    {
      printf("FAIL TO OPEN FILE");
      exit(1);
    }

    //  문자 출력의 끝 확인.
    while ((c = getchar()) != EOF)
    {
      // 문자를 파일로 출력.
      putc(c, fp);
    }

    printf("END OF WHILE!");
    fclose(fp);
  }

fputs()

  • 문자열을 파일로 출력.
  • 형식 : fputs(문자열변수, 파일포인터변수);
  • 사용 예 : fputs(s, fp);
  • 기능 : 지정된 파일에 문자열(하나의 레코드) 출력.
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>

  void main() {
    char name[64];
    FILE *fp;
    //  텍스트 쓰기모드 개방하고, 에러시 프로그램 종료.
    if ((fp = fopen("02_fputs.tt.txt", "w")) == NULL) {
      puts("CAN NOT OPEN FILE");
      exit(1);
    }

    gets(name);
    while (strcmp(name, "end")) {
      // 하나의 문자열에 개행문자 추가.
      strcat(name, "\n");
      // 문자열을 fp가 가르키는 파일에 수록.
      fputs(name, fp);
      gets(name);
    }

    printf("BYE!\n");
    // 파일 닫기.
    fclose(fp);
  }

fprintf()

  • 지정된 형식을 가지로 파일에 자료를 출력.
  • 여러 항목의 복합적인 자료로 구성된 레코드를 저장할 때 유용.
  • 형식 : fprintf(파일포인터변수, "출력형식", 변수);
  • 사용 예 : fprintf(fp, "%s %d\n", a, b);
  • 기능 : 지정된 형식대로 자료를 파일포인터 변수가 가리키는 곳에 출력.
  #include <stdio.h>
  #include <stdlib.h>

  void main()
  {
    FILE *fp;
    char no[10], name[10];
    int mid, term, rep, att, i;

    if ((fp = fopen("03_fprintf.tt.txt", "w")) == NULL)
    {
      puts("CAN NOT OPEN FILE");
      exit(1);
    }

    //  stdout : 모니터를 가리키는 특수한 파일포인터.
    fprintf(stdout, "insert no name mid term rep att.");

    for (i = 0; i < 5; ++i)
    {
      scanf("%s %s %d %d %d %d", no, name, &mid, &term, &rep, &att);
      // 지정된 형식으로 자료를 파일에 출력.
      fprintf(fp, "%10s %8s %3d %3d %3d %3d\n", no, name, mid, term, rep, att);
    }

    printf("BYE!\n");
    // 파일 닫기.
    fclose(fp);
  }

C 언어에서 입출력 장치를 파일 개념으로 처리

  • 자동적으로 3개의 표준 파일에 대한 포인터를 생성함.
  • 이러한 표준 파일에 대해서는 다로 파일포인터를 선언할 필요가 없음.
표준파일 파일 포인터 대응 장치
입력 stdin 키보드
출력 stdout 모니터
에러 stderr 모니터

순차파일 입력함수

파일 출력함수에 의해 만들어진 순차파일의 저장된 자료를 읽어내는 함수.
자료를 읽을 때는 파일의 끝에 있는 EOF 신호를 만날 때까지 읽을 수 있는 프로그램 작성.

  • getc(), fgetc(), fgets(), fscanf()

getc()

  • 문자 단위의 파일 입력함수.
  • fgetc() 함수와 유사.
  • 형식 : getc(파일포인터변수);
  • 사용예 : c = getc(fp);
  • 기능 : 지정된 파일로부터 한 문자를 읽어온다.
  #include <stdio.h>
  #include <stdlib.h>

  void main() {
    FILE *fp;
    char c;

    if ((fp = fopen("01_putc.tt.txt", "r")) == NULL) {
      puts("\n\nCAN NOT OPEN FILE");
      exit(1);
    }

    while ((c = getc(fp)) != EOF) {
      putchar(c);
    }

    printf("\n\nBYE!\n");
    // 파일 닫기.
    fclose(fp);
  }

fgets()

  • 파일에 저장된 문자열 자료를 읽을 때 사용.
  • 읽어 낼 문자열의 길이를 반드시 명시.
  • 형식 : fget(문자열변수, 문자열 길이 + 1, 파일포인터 편수);
  • 사용 예 : fget(s, 40, fp);
  • 기능 : 지정된 파일로부터 해당 문자열 길이 만큼의 문자를 읽어 문자열 변수에 저장한다.
  #include <stdio.h>
  #include <stdlib.h>

  void main() {
    char name[20];
    FILE *fp;

    if ((fp = fopen("02_fputs.tt.txt", "r")) == NULL) {
      puts("\n\nCAN NOT OPEN FILE");
      exit(1);
    }

    //  파일의 끝에 도달할 때까지 읽기.
    while (fgets(name, 20, fp) != NULL) {
      printf("%s", name);
    }

    printf("\n\nBYE!\n");
    // 파일 닫기.
    fclose(fp);
  }

scanf()

  • 숫자, 문자 등 복합적인 자료로 구성된 레코드를 읽을 때 사용.
  • 일반적으로 파일의 끝을 판별하는 feof()와 같이 사용.
  • 형식 : fscanf(파일포인터변수, "입력형식", 변수);
  • 사용 예 : fscanf(sp, "%s %d", &a, &b);
  • 기능 : 파일 포인터가 가리키는 곳으로부터 지정된 형식대로 자료를 읽어온다.
  #include <stdio.h>
  #include <stdlib.h>

  void main() {
    FILE *fp;
    char no[10], name[10];
    int mid, term, rep, att;

    if ((fp = fopen("03_fprintf.tt.txt", "r")) == NULL) {
      puts("\n\nCAN NOT OPEN FILE");
      exit(1);
    }

    printf("no name mid, term, rep, att\n");

    //  파일의 끝인지 확인하는 feof()
    while (!feof(fp)) {
      //  파일에 저장된 자료의 형식에 맞게 입력형식을 지정해야 함.
      fscanf(fp, "%10s %8s %3d %3d %3d %3d\n", no, name, &mid, &term, &rep, &att);
      printf("%-10s %-8s %4d %4d %4d %4d\n", no, name, mid, term, rep, att);
    }

    printf("\n\nBYE!\n");
    // 파일 닫기.
    fclose(fp);
  }

레코드 추가를 위한 사용 모드

a a+ ab ab+

  • 형식 : fp = fopen("파일명", "a");
  • 사용 예 : fp = fopen("파일명", "a");
  • 기능 : 이미 만들어진 순차파일의 끝에 새로운 레코드 추가(append).
  #include <stdio.h>

  void main() {
    FILE *fp;
    //  레코드 추가 모드로 파일 개방.
    fp = fopen("04_tt.dat", "a");
    //  파일이 없으르모 새 파일 생성 후 새 내용 기록.
    fputs("asdf \n", fp);
    fputs("qwer \n", fp);
    fputs("zxcv \n", fp);
    fputs("qaz \n", fp);
    fputs("wsx \n", fp);

    fclose(fp);
  }

랜덤파일 처리 (random file)

  • 파일의 임의의 위치에서 자료를 읽거나 쓸 수 있음.

  • 레코드의 길이가 일정함.

  • 순차파일에 비해

    • 장점 : 레코드 탐색이 빠르고 효과적.
    • 단점 : 기억공간 낭비.

랜덤파일 열기

일반적으로 랜덤파일을 입출력할 때는 2진 모드로 파일을 개방.

  • 2진 모드의 특징
    • 텍스트 파일보다 적은 기억공간.
    • 레코드의 길이를 개발자가 결정.
    • 파일 포인터의 위치 변경 가능.

랜덤파일 입출력 함수

fwrite()

  • 레코드의 길이를 지정.
  • 자료저장 변수는 포인터 형.
  • 형식 : fwirte(저장자료변수, 레코드길이, 레코드개수, 파일포인터);
  • 사용 예 : fwrite(name, 10, 1, fp);
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>

  void main()
  {
    FILE *fp;
    char name[10];

    //  2진 파일 쓰기 모드 개방.
    if ((fp = fopen("08_fwrite.dat", "wb")) == NULL)
    {
      puts("\n\nCAN NOT OPEN FILE");
      exit(1);
    }

    gets(name);

    while (strcmp(name, "END"))
    {
      //  2진 파일 쓰기.
      fwrite(name, 10, 1, fp);
      gets(name);
    }

    fclose(fp);
  }

fread()

  • 읽기에 성공하면 읽은 레코드 수를 리턴.
  • 형식 : fread(읽을자료변수, 레코드길이, 레코드개수, 파일포인터);
  • ex : fread(name, 10, 2, fp);
  #include <stdio.h>
  #include <stdlib.h>

  void main() {
    FILE *fp;
    char name[10];

    //  2진 파일 읽기 모드 개방.
    if ((fp = fopen("08_fwrite.dat", "rb")) == NULL) {
      puts("\n\nCAN NOT OPEN FILE");
      exit(1);
    }

    while (1) {
      //  레코드의 개수가 1이 아닌 값이 리턴되면 파일은 끝난다.
      if (fread(name, 10, 1, fp) != 1)
        break;

      puts(name);
    }

    fclose(fp);
  }

랜덤파일 위치 제어

레코드의 길이가 일정하기 때문에, 자료의 위치를 제어할 수 있음.

fseek()

  • 파일 포인터를 임의의 위치로 이동시키는 함수.
  • 랜덤파일의 특정부분을 입출력 할 수 있음.
  • 형식 : fseek(파일포인터_변수, 이동할_상대위치, 기준위치를_지정하는*모드);
  • ex : fseek( fp, 2 * REC_size, SEEK_SET );

기준위치 지정모드

stdio.h에 정의됨

기준위치모드 동일기호 설명
0 SEEK_SET 파일의 시작위치
1 SEEK_CUR 현재 파일포인터의 위치
2 SEEK_END 파일의 끝 위치

 

  #include <stdio.h>
  #include <string.h>

  void main()
  {
    char str[10];
    FILE *fp = fopen("sample6.txt", "wt");

    fputs("1234567890", fp);
    fclose(fp);

    fp = fopen("sample6.txt", "rt");
    fseek(fp, 7, SEEK_SET);
    fgets(str, 4, fp);
    printf("print 3 str from 7 : %s\n", str);
    // 890

    fseek(fp, -2, SEEK_CUR);
    fgets(str, 3, fp);
    printf("print 2 char before 2 char cur loc : %s\n", str);
    // 90

    fseek(fp, -9, SEEK_END);
    fgets(str, 6, fp);
    printf("print 5 str from 9 char before last : %s\n", str);
    // 23456

    fclose(fp);
  }

728x90
반응형

'Language > C' 카테고리의 다른 글

[C] 메모리 동적 할당  (0) 2021.01.03
[C] 파일 처리 함수 - 1  (0) 2021.01.01
[C] 구조체와 공용체 - 2  (0) 2021.01.01
[C] 구조체와 공용체 -1  (0) 2020.12.27
[C] 배열과 포인터 - 3  (0) 2020.12.27

파일 처리 함수 - 1

자료의 입출력 개념과 파일 입출력의 개념. 파일 포인터와 순차파일.

  • 학습 목표
    1. 파일을 이용한 자료의 입출력 이해.
    2. 파일 입출력의 수행과정 이해.
    3. 파일 포인터를 이용한 자료의 입출력 수행.
    4. 순차파일의 개념 이해.

주요 용어

  • 스트림(stream) : 자료의 입출력을 위한 논리적인 통로.
  • 파일 포인터 : 파일이 어디 있는지를 가리키는 포인터.
  • 순차파일 : 파일의 처음에서부터 자료를 차례로 읽고, 기록하는 파일.
  • 랜덤파일 : 파일의 임의의 위치에서 자료를 읽고, 기록하는 파일.

파일 입출력의 개념

  • 보조기억장치의 파일을 이용한 자료의 입출력.
    • 파일 처리함수를 이용.
    • 표준입출력 -> 키보드나 모니터를 통한 입출력.
  • 파일 처리 함수.
    • 보조기억장치에 들어있는 정보들의 모임을 파일이라 하고, 이러한 파일을 제어하는 함수.

파일

  • 보조기억장치에 저장된 데이터들의 모임.
  • 일련의 byte들로 구성.
  • C 프로그램은 운영체제를 통해서 파일을 읽거나 씀.
  • C 언어에서는 컴퓨터와 연결된 장치들 까지도 모두 파일의 범주에 넣어 처리.

파일 구분

  • 텍스트 파일(text file)
    • 화면에 출력되는 문자들로 구성된 파일.
  • 2진 파일(binary file)
    • 텍스트 파일을 포함한 모든 종류의 자료를 다루는 파일.
    • 컴파일 되어 있어 기계어에 가까우므로 내용을 이해하거나 인쇄 불가능.

파일에 대한 자료의 입출력

  • 파일 입력
    • 디스크 상의 특정 위치(파일)에 수록되어 있는 자료를 읽어들여 기억공간에 수록하는 절차.
  • 파일 출력
    • 기억공간에 있는 자료를 디스크상의 특정위치(파일)에 수록하는 절차.
  • 파일포인터를 사용하여 파일 입출력 수행.

파일처리를 위해서는 파일포인터를 사용

  • 파일포인터
    • 파일이 어디에 있는지를 가리키는 포인터.
    • 모든 파일 입출력 함수는 파일 포인터를 사용

파일을 입출력 할 때 버퍼(buffer) 사용

  • 기억공간과 디스크 사이에 존재하는 임시 기억 공간.
  • 사용
    • 파일 입출력 시 디스크에 저장된 자료를 기억공간으로 읽어 들일 때.
    • 기억 공간에서 처리된 자료를 디스크에 저장할 때.

파일포인터를 이용한 파일 입출력

자료의 입출력 개념

  • 프로그램과 입출력 장치(콘솔, 파일, 소켓등)와의 사잉에 이루어 지는 자료의 입력과 출력.
  • 자료의 입출력을 위한 논리넉인 통로 : 스트림

스트림 (stream)

stream

  • 표준 입출력장치를 이용한 자료 입출력.
    • 표준 입출력장치와의 스트림은 프로그램 실행/종료 시
      자동으로 생성/소멸 됨.
  • 파일 입출력을 위한 스트림은 프로그램을 통해 생성/소멸 시켜주어야 함.

파일 입출력의 수행 과정

  • 과정

    1. 파일을 연다.
      • 파일과 자료를 주고 받을 수 있는 스트림을 생성(fopen() 사용).
    2. 입출력을 수행한다.
    3. 파일을 닫는다.
  • 생성된 스트림을 소멸시키기 위한 과정(fclose() 사용).

스트림(stream)의 생성

  • 파일과 프로그램과의 통로(논리적인 접속)를 구성.
  • 통로 역할을 파일포인터가 수행.

파일입출력 프로그램 구조

  // 파일을 가리키는 파일포인터 선언.
  FILE *fp;

  //  파일 열기 : 지정한 모드로 열고, fp로 하여금 파일을 가리키게 함.
  fp = fopen("파일명", "모드");

  //  입출력 수행 : 파일처리함수와 fp를 이용하여 입출력 수행.
  ...

  //  파일 닫기 : 버퍼를 비우고 fp가 가리키는 파일을 닫음.
  fclose(fp);
  #include <stdio.h>

  void main() {
    char ch;
    FILE *fp;
    fp = fopen("file_IO_test.txt", "W");
    for (ch = 'A'; ch <= 'Z'; ch++)
      fputc(ch, fp);

    fclose(fp);
  }

파일처리 함수와 기능

function desc
fopen("filename", "mode") 파일을 지정된 모드로 열기
fclose() 파일 닫기
fget(), getc() 파일로부터 한 문자 읽기
fputc(), putc() 파일에 한 문자 쓰기
fgets() 파일로부터 문자열 읽기
fputs() 파일에 문자열 쓰기
fscanf() 파일로 부터 정해진 형식에 따라 읽기
fprintf() 파일에 정해진 형식에 따라 쓰기
fread() 파일로부터 정해진 크기의 자료를 정해진 개수만큼 읽기
fwrite() 파일에 정해진 크기의 자료를 정해진 개수만큼 쓰기
fseek() 파일에서 입출력 위치 이동
feof() 파일의 끝인가를 판별
ferror() 파일의 입출력 시 에러 발생 유무 조사

파일포인터 선언과 파일 열기

파일포인터 선언

  • 파일 입출력을 위해 파일포인터 선언.
  • 실제 파일과 프로그램을 연결해주는 통로가 됨.
  • 형식 : FILE *변수명;
  • 사용 예 : FILE *fp;
  • 기능 : 파일형 포인터변수를 선언.

파일포인터 변수와 버퍼의 관계

  • FILE형 : 구조체형.
  • FILE형 포인터 변수 : 파일에 대한 여러가지 정보를 가진 변수.

file 형 포인터 변수

 

파일 열기 : fopen()

프로그램과 디스크 상의 파일 사이에 데이터가 입출력할 수 있도록 통로를 만들어 주는 것.

  • 형식 : fopen("파일명", "사용모드");
  • 사용 예 : fp = fopen("test.dat", "r");
  • 기능 : 파일을 열어 사용할 수 있게 함.
  • 입출력이 정상이면 지정된 파일의 파일포인터에 시작주소 값을 리턴.
  • 파일이 개방되지 않을 때는 에러 값(NULL값) 리턴.
  • 파일 명
    • 경로를 포함 할수도 안 할 수도 있다?
  • 사용 모드
    • 개방한 파일의 용도를 결정.
    • 자료의 입출력 방식을 의미
    • 사용(개방)모드 = 파일 접근 모드 + 데이터 입출력 모드.
      • r, r+ : 읽기
      • w, w+ : 쓰기
      • a, a+ : 추가
      • t : 텍스트 모드(text mode)
        • 기본 값.
        • 프로그램에서 파일로 자료를 입출력할 때 변환이 일어나는 입출력 모드.
        • 문자 변환이 필요(\n -> CR/LF).
      • b : 2진 모드(bianry mode)
        • 변환이 일어나지 않는 입출력 모드.
        • 문자 변환 불필요.
사용 모드 의미 파일이 있을 경우 파일이 없을 경우
r, rb 읽기 정상처리 NULL
r+, rb+ 읽기/쓰기 정상처리 NULL
w, wb 쓰기 이전 내용 삭제 새 파일 생성
w+, wb+ 읽기/쓰기 이전 내용 삭제 새 파일 생성
a, ab 추가 이전 내용 뒤에 추가 새 파일 생성
a+, ab+ 읽기/추가 이전 내용 뒤에 추가 새 파일 생성
  fopen("filename", "w") //  텍스트 출력 모드
  fopen("filename", "rt") //  텍스트 입력 모드
  fopen("filename", "wb") //  2진 출력 모드
  fopen("filename", "rb+") //  2인 입력 모드

파일 닫기 fclose()

  • 형식 : fclose(파일포인터 변수);
  • 사용 예 : fclose(fp);
  • 기능 : 열었던 파일을 닫고, fp 해제.
  • 개방된 통로와 버퍼를 원 상태로 환원.
  • 쓰기의 경우 파일 끝에 EOF(End Of File) 신호 부가(완전한 파일로 완성됨).

파일 열기와 닫기 사용 예

  FILE *fp1, fp2;
  //  a파일을 쓰기용으로 열어 그 시작주소를 파일포인터 fp1에게 부여.
  fp1 = fopen("a", "w");
  fp2 = fopen("b", "r");

  //  파일 open이 안된 경우 종료 해야 함.
  if( (fp = fopen("filename", "r") ) == NULL ) {
    exit(1);  //  프로그램 종료
  }

  //  열었던 파일을 닫고 파일포인터 해제.
  fclose(fp1);
  fclose(fp2);

순차파일처리

정보의 집합 => 파일 => 레코드 단위 구성

  • 레코드
    • 파일 입출력 처리에 사용되는 논리적인 기본 단위.
    • 각 레코드들은 필드(field)들로 구성.

파일 처리 함수를 이용하여 파일을 편성하는 방법에 따라 순차파일, 랜덤파일로 구분.

파일의 종류

순차 파일 (sequential file)

  • 파일의 처음부터 자료를 차례로 읽고, 기록하는 파일.
  • 레코드의 길이가 일정하지 않은 파일.

랜덤 파일 (random file)

  • 파일의 임의의 위치에서 자료를 읽고, 기록하는 파일.
  • 레코드의 길이가 일정한 파일.

순차파일에서 레코드 구성

순차파일은 레코드의 길이가 일정하지 않기 때문에 레코드들의 구분이 필요 : CR/LF를 사용하여 구뷴

 

순차파일 출력함수

만들어진 파일에 자료를 기록하는 함수.

  • putc(), fputc(), fputs(), fprintf()
  • 순차파일 출력함수
    • getc(), fgetc(), fgets(), fscanf()

728x90
반응형

'Language > C' 카테고리의 다른 글

[C] 메모리 동적 할당  (0) 2021.01.03
[C] 파일 처리 함수 - 2  (0) 2021.01.02
[C] 구조체와 공용체 - 2  (0) 2021.01.01
[C] 구조체와 공용체 -1  (0) 2020.12.27
[C] 배열과 포인터 - 3  (0) 2020.12.27

+ Recent posts