처음부터 차근차근

파일 접근과 해제, 읽기, 쓰기, 접근 위치 이동, 생성, 삭제 본문

Linux & Unix

파일 접근과 해제, 읽기, 쓰기, 접근 위치 이동, 생성, 삭제

_soyoung 2022. 4. 7. 11:47
반응형

파일 접근과 해제

#include <sys/types.h> // 파일 작업할 때 필요한 헤더
#include <sys/stat.h> // 파일 작업할 때 필요한 헤더
#include <fcntl.h> // 파일 작업할 때 필요한 헤더
#include <stdio.h> // c 언어 파일 작성할 때 필요한 헤더
#include <unistd.h> // unix 계열 헤더

// argc : 명령 파라미터의 개수(자기 자신까지 1개로 침)
// argv[] : 각각의 아규멘트의 값들(argv[0]는 자기자신)
int main(int argc, char* argv[]){ 
	// 파일 기술자
	int nFd = -1; 

	// 받은 값이 두 개(자기 자신 + 매개변수 1개)가 아니면
	if (argc != 2) { 
		// perror : 표준 에러
		perror("we need an argument.\n");

		// 프로그램 종료
		return -1;
	}
	// 파일 접근
	// argv[1] : 매개변수로 넣은 값
	// O_RDWR | O_CREAT : 읽기/쓰기 모드로 접근하는데 파일이 없으면 새로 생성한다.
	// 0644 : 파일을 생성할 때 이 permission으로 함. 소유자 : 읽기/쓰기(6), 나머지 : 읽기(4)
	nFd = open(argv[1], O_RDWR | O_CREAT, 0644); 

	//출력
	// 파일 기술자 0, 1, 2는 이미 할당 되어있기 때문에 그거 제외한 뒤에 아무 숫자 나옴. 그래서 3으로 나옴
	printf("FD is %d\n", nFd);

	//파일 접근 해제
	close(nFd);

	// 프로그램 종료
	return 0;
}

 

실행결과

파일 기술자 0, 1, 2는 이미 할당 되어있기 때문에 0, 1, 2를 제외한 3이 출력됐다.

 

 

 

파일 읽기

#include <sys/types.h> // 파일 작업할 때 필요한 헤더
#include <sys/stat.h> // 파일 작업할 때 필요한 헤더
#include <fcntl.h> // 파일 작업할 때 필요한 헤더
#include <stdio.h> // c 언어 파일 작성할 때 필요한 헤더
#include <unistd.h> // unix 계열 헤더

// argc : 명령 파라미터의 개수(자기 자신까지 1개로 침)
// argv[] : 각각의 아규멘트의 값들(argv[0]는 자기자신)
int main(int argc, char* argv[]) {
	// 파일 기술자
	int nFd = -1;

	// 버퍼 생성
	char pBuf[BUFSIZ] = { 0, };

	// 성공적으로 읽어들인 값의 크기 ex) 1byte읽으면 1로 나옴
	int nLen = 0;

	// 받은 값이 두 개(자기 자신 + 매개변수 1개)가 아니면
	if (argc != 2) {
		// perror : 표준 에러
		perror("we need an argument.\n");

		// 프로그램 종료
		return -1;
	}

	// 파일 접근
	// argv[1] : 매개변수로 넣은 값
	// O_RDONLY : 읽기 전용 모드
	nFd = open(argv[1], O_RDONLY);

	// 파일 읽기
	// nFd : 파일 기술자
	// pBuf : 읽어들인 파일의 내용을 이 버퍼에다 넣음
	// BUFSIZ : 읽을 최대 길이. 최대 8192 만큼 읽어들여라
	while ((nLen = read(nFd, pBuf, BUFSIZ)) > 0)
	{
		// 파일 내용을 읽어가지고 출력
		printf("%s", pBuf);
	}

	//파일 접근 해제
	close(nFd);

	// 프로그램 종료
	return 0;
}

 

실행결과

hi 파일의 내용인 hi hi hi가 출력됐다.

 

 

 

파일쓰기

#include <sys/types.h> // 파일 작업할 때 필요한 헤더
#include <sys/stat.h> // 파일 작업할 때 필요한 헤더
#include <fcntl.h> // 파일 작업할 때 필요한 헤더
#include <stdio.h> // c 언어 파일 작성할 때 필요한 헤더
#include <unistd.h> // unix 계열 헤더

// argc : 명령 파라미터의 개수(자기 자신까지 1개로 침)
// argv[] : 각각의 아규멘트의 값들(argv[0]는 자기자신)
int main(int argc, char* argv[]) {
	// 파일 기술자
	int nFd1 = -1;
	int nFd2 = -1;

	// 버퍼 생성
	char pBuf[BUFSIZ] = { 0, };

	// 성공적으로 읽어들인 값의 크기 ex) 1byte읽으면 1로 나옴
	int nLen = 0;

	// 받은 값이 3 개가 아니면(자기 자신 + 매개변수 2개)
	if (argc != 3) {
		// perror : 표준 에러
		perror("we need an argument.\n");

		// 프로그램 종료
		return -1;
	}

	// 파일 접근
	// argv[1] : 매개변수로 넣은 값
	// O_RDONLY : 읽기 전용 모드
	// O_WRONLY | O_CREAT : 쓰기전용 모드로 접근하는데 파일이 없으면 새로 생성한다.
	// 0644 : 파일을 새로 생성할 때 permission (소유자 - 읽기/쓰기(6), 나머지 - 읽기(4))
	nFd1 = open(argv[1], O_RDONLY);
	nFd2 = open(argv[2], O_WRONLY | O_CREAT, 0644);

	// 파일 읽기
	// nFd1 : 파일 기술자
	// pBuf : 읽어들인 파일의 내용을 이 버퍼에다 넣음
	// BUFSIZ : 읽을 최대 길이. 최대 8192 만큼 읽어들여라
	while ((nLen = read(nFd1, pBuf, BUFSIZ)) > 0)
	{
		// 파일 쓰기
		// nFd2 : 파일 기술자
		// pBuf : 기록할 내용(아까 읽어들인 파일 내용)
		// nLen : 기록할 내용의 길이
		// nFd1의 내용을 nFd2에다 복사한다.
		if (write(nFd2, pBuf, nLen) < 0) {
			// 파일 쓰기 실패 시 아래 내용 출력하고 while문 탈출
			perror("Writting Failed.\n");
			break;
		}
	}

	//파일 접근 해제
	close(nFd2);
	close(nFd1);

	// 프로그램 종료
	return 0;
}

 

실행결과

Hi 파일 안에 있는 내용이 복사되어 hello 파일 안에 입력되었다.

 

 

 

접근 위치 이동

#include <sys/types.h> // 파일 작업할 때 필요한 헤더
#include <sys/stat.h> // 파일 작업할 때 필요한 헤더
#include <fcntl.h> // 파일 작업할 때 필요한 헤더
#include <stdlib.h> // atoi() 있는 헤더
#include <stdio.h> // c 언어 파일 작성할 때 필요한 헤더
#include <unistd.h> // unix 계열 헤더

// argc : 명령 파라미터의 개수(자기 자신까지 1개로 침)
// argv[] : 각각의 아규멘트의 값들(argv[0]는 자기자신)
int main(int argc, char* argv[]) {
	// 파일 기술자
	int nFd = -1;

	// 버퍼 생성
	char pBuf[BUFSIZ] = { 0, };

	// 성공적으로 읽어들인 값의 크기 ex) 1byte읽으면 1로 나옴
	int nLen = 0;
	
	// 받은 값이 4개가 아니면(자기자신 + 매개변수 3개)
	if (argc != 4) {
		printf("Usage : cmd [filename] [Whence] [Offset]\n");
		printf("\t-Whence : SEEK_SET(0), SEEK_CUR(1), SEEK_END(2)\n");

		// 프로그램 종료
		return -1;
	}

	// 파일 접근
	// argv[1] : 첫 번째 매개변수. filename을 뜻함
	// O_RDONLY : 읽기전용 모드로 접근
	nFd = open(argv[1], O_RDONLY);
	
	// atoi() : 문자열을 정수로 반환하는 함수
	// argv[2] : 두 번째 매개변수. Whence를 뜻함
	switch(atoi(argv[2]))
	{
		case 0:
			// lseek() : 파일의 접근 위치를 주어진 값으로 이동하게 하는 함수
			// nFd : 파일 기술자
			// atoi(argv[3]) : 이동할 위치
			// SEEK_SET : 파일의 처음을 기준으로 offset 계산
			lseek(nFd, atoi(argv[3]), SEEK_SET);
			break;
		case 1:
			// SEEK_CUR : 파일의 현재 위치를 기준으로 offset을 계산
			lseek(nFd, atoi(argv[3]), SEEK_CUR);
			break;
		default:
			// SEEK_END : 파일의 마지막을 기준으로 offset을 계산
			lseek(nFd, atoi(argv[3]), SEEK_END);
			break;
	}

	// 파일 읽기
	// nFd : 파일 기술자
	// pBuf : 읽어들인 파일의 내용을 이 버퍼에다 넣는다
	// 20 : 읽을 최대 길이
	nLen = read(nFd, pBuf, 20);

	// 읽어들인 파일 내용을 출력한다.
	printf("Data : %s\n", pBuf);

	//파일 접근 해제
	close(nFd);

	// 프로그램 종료
	return 0;
}

 

실행결과

hi 파일 내용 : hi hi hi
파일의 처음을 기준으로 offset을 계산하여 3개의 문자(‘hi ‘)를 건너 뛴 ‘hi hi’가 결과값으로 출력됐다.

 

 

 

파일의 생성과 삭제

#include <sys/types.h> // 파일 작업할 때 필요한 헤더
#include <sys/stat.h> // 파일 작업할 때 필요한 헤더
#include <fcntl.h> // 파일 작업할 때 필요한 헤더
#include <stdio.h> // c 언어 파일 작성할 때 필요한 헤더
#include <unistd.h> // unix 계열 헤더

// argc : 명령 파라미터의 개수(자기 자신까지 1개로 침)
// argv[] : 각각의 아규멘트의 값들(argv[0]는 자기자신)
int main(int argc, char* argv[]) {
	// 파일 기술자
	int nFd = -1;

	// 받은 값이 2개가 아니면(자기자신 + 매개변수 1개)
	if (argc != 2) {
		// perror : 표준 에러
		perror("we need an argument.\n");

		// 프로그램 종료
		return -1;
	}

	// 파일 생성
	// argv[1] : 첫 번째 매개변수
	// 0644 : 파일 생성할 때 permission
	// --> 소유자 : 읽기/쓰기(6), 나머지 : 읽기(4)
	nFd = creat(argv[1], 0644);

	// 파일 쓰기
	// nFd에다 Hello라고 쓴다
	write(nFd, "Hello", 5);

	//파일 접근 해제
	close(nFd);

	printf("Press Enter Key to continue.\n");

	// 문자받는 함수
	getchar();

	printf("Deleting %s\n", argv[1]);

	// 매개변수로 받는 파일을 삭제한다.
	unlink(argv[1]);

	printf("Done.\n");

	// 프로그램 종료
	return 0;
}

 

실행 결과

hello 파일을 삭제했다.

 

실제로 확인해보면

                               

hello 파일이 삭제된 것을 볼 수 있다.

 

 

 

 

출처 : 네트워크개론(22-1학기)김병국교수 강의 내용 변형 및 요약

반응형
Comments