질문의 역사:
Perl은 원래 텍스트 스트림을 효율적으로 처리하기 위한 수단으로 개발되었기에, 입력/출력(I/O) 메커니즘은 언어의 핵심에서 가장 정교하게 다듬어졌습니다. 유니코드의 발전과 다양한 입력/출력 레이어의 등장으로 올바른 인코딩 선택 및 스트림 관리는 데이터 손실이나 손상을 피하기 위한 중요한 과제가 되었습니다.
문제:
파일을 읽거나 쓸 때 잘못된 인코딩을 선택하면 데이터 왜곡이 발생합니다(특히 국가 기호와 관련하여) 그리고 스트림 처리를 잘못하면(예: 파일 열기의 성공 여부를 확인하지 않음) 종종 버그와 취약점의 원인이 됩니다.
해결책:
파일을 열 때는 세 개의 인수를 사용하는 open을 사용하여 보다 안전하고 보편적이며(경로와 모드 해석과 관련된 취약점을 피합니다) 올바른 인코딩과 상호작용하기 위해 레이어를 적용해야 합니다(예: "<:encoding(UTF-8)"). 항상 열기/닫기의 성공 여부를 확인하고 필요한 작업 모드를 명시적으로 설정해야 합니다.
예:
open my $fh, '<:encoding(UTF-8)', $filename or die "Cannot open $filename: $!"; while (my $line = <$fh>) { chomp $line; # 줄 바꿈 제거 print "$line "; } close $fh or warn "Cannot close $filename: $!";
주요 특성:
검증 없이 사용자 입력을 open에 직접 전달할 수 있습니까?
답변: 불가능합니다! 이는 취약점을 초래합니다(예: 안전하지 않은 별칭으로 쉘 명령 실행) 및 경로 작업에서 오류를 발생시킵니다. 명시적 삼항 인수 구문을 사용하십시오.
인코딩 레이어를 지정하지 않으면 UTF-8 파일은 어떻게 됩니까?
답변: Perl은 바이트를 latin1로 해석하려 하여, 출력/읽기에서 왜곡된 기호가 발생하며 특별히 국가 알파벳을 사용할 경우 더욱 그렇습니다.
단순히 close를 호출하는 것으로 파일이 올바르게 기록되었는지 확인할 수 있습니까?
답변: 아닙니다. close 후에는 반환 값을 확인해야 합니다. 쓰기 오류가 발생하면 Perl은 실패한 close 이후에만 $!를 통해 알립니다. 예:
close $fh or die "Write failed: $!";
로그 핸들러가 open FILE, "file.txt"를 통해 파일을 읽고 성공 여부를 확인하지 않으며, 바이트 단위로 데이터를 처리하여 결과적으로 키릴 문자들이 해독되지 않거나 일부 줄이 손실됩니다.
장점:
단점:
파일 작업은 항상 인코딩을 지정한 삼항 open을 통해 수행되며, 모든 오류가 처리되고 로깅되어 결과 데이터는 항상 로케일에 맞습니다.
장점:
단점: