MenuIcon

Owl-Networks Archive

LoginIcon

Perl : 파일을 읽기/쓰기 모드로 열고 읽고 쓰고 닫기

| 분류: Perl | 최초 작성: 2008-05-08 04:55:17 |

그리 흔한 경우는 아닙니다만, 하나의 파일 핸들을 통해 데이터를 읽고 쓰기를 함께 해야 할 필요성이 있는 경우가 있습니다. 이 경우, +< 모드를 주어 파일을 열 수 있습니다.

#!/usr/bin/perl
use strict;
use warnings;

umask(000);

## 파일 열기: +< 는 파일이 존재하여야 한다. 파일이 없다면 실패한다.

open my $fHandle, "+<", "./data.txt" or die "Failed.\n";

## 읽기

my @TempArray = <$fHandle>;

## 화면으로 출력하기

foreach ( @TempArray ) {
    print "$_";
}

## 현재 열린 파일핸들의 포인터는 파일의 제일 끝에 있다.
## 이 상태에서 기록을 시작한다면 파일의 제일 끝에 추가되는 형태로 기록된다.
## 파일의 처음부터 덮어씌워 기록하기 위해 포인터를 파일의 제일 앞으로 옮긴다.

seek($fHandle,0,0);

## 파일에 데이터 기록하기

shift @TempArray;   # 파일의 제일 첫 줄 삭제

foreach ( @TempArray ) {
    print $fHandle "$_";
}

## 파일에 한 줄을 추가 기록

print $fHandle "8th Line Added.\n";

## 파일 닫기

close $fHandle;
exit;

참고로, 최초의 data.txt 파일의 내용은 다음과 같았습니다. (마지막 7th Line 뒤에도 개행 문자가 있습니다.)

1st Line
2nd Line
3rd Line
4th Line
5th Line
6th Line
7th Line
 

위 코드를 1회 실행한 결과, 화면상에는 다음과 같이 출력됩니다.

>perl test.pl
1st Line
2nd Line
3rd Line
4th Line
5th Line
6th Line
7th Line

>

또한, 실행 후의 data.txt 는 다음과 같이 변경되었습니다. (첫 줄에 있었던 1st Line 이 사라졌습니다)

2nd Line
3rd Line
4th Line
5th Line
6th Line
7th Line
8th Line Added.
 

만약, 파일을 다 읽은 후 포인터를 처음으로 옮기지 않는다면, 즉 위 코드 25번째 라인의 seek($fHandle,0,0); 을 주석처리한다면 화면상 출력 결과는 동일하나 실행 결과 data.txt 는 다음과 같이 수정될 것입니다.

1st Line
2nd Line
3rd Line
4th Line
5th Line
6th Line
7th Line
2nd Line
3rd Line
4th Line
5th Line
6th Line
7th Line
8th Line Added.
 

이 코드는 포인터를 파일의 가장 앞으로 돌려 새로운 내용을 기록하기 때문에, 기존의 내용이 덮어씌워지게 됩니다. 이 경우, 만약 새로 기록하는 내용이 원래의 내용보다 길다면 상관이 없으나, 새로 기록하는 내용이 원래 내용보다 짧다면 필요없는 값이 파일에 그대로 남아 있게 됩니다. 예를 들면, a 가 70개 기록된 파일에 이 방식을 사용하여 포인터를 처음으로 돌린 후 b 를 60개 기록한 경우, b가 60개 기록된 후 나머지 a 문자 10개는 지워지지 않고 그대로 남아있게 되죠.

작업 전: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

작업 후: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaa

만약 뒷부분의 a 10개가 필요 없는 데이터라면, 이 부분을 잘라낼 필요가 있습니다. 이 때는 truncate 함수와 tell 함수를 사용하면 되며, 모든 기록을 마친 후 파일을 닫기 전에 다음과 같은 코드를 삽입하면 됩니다.

truncate($fHandle,tell($fHandle));

위 방식을 윈도우 환경에서 사용할 때에는 한 가지 주의해야 할 점이 있습니다. 읽기/쓰기 모드를 넘나들 때에는 반드시 현재의 포인터를 명시적으로 리셋해 주지 않으면 코드가 의도와 다르게 동작할 수 있습니다. 다음 게시물을 아울러 참고하십시오.

☞ 태그:

☞ 트랙백 접수 모듈이 설치되지 않았습니다.

☞ 덧글이 없고, 트랙백이 없습니다.

덧글을 남기시려면 여기를 클릭하십시오.
[483] < [299] [298] [295] [294] [270] ... [265] ... [261] [260] [254] [249] [247] > [19]

(C) 2000-2018, Owl-Networks. Powered by Perl. 이 페이지는 HTML 5 표준에 따라 작성되었습니다.