Perl Language
ファイルI / O(ファイルの読み書き)
サーチ…
パラメーター
モード | 説明 |
---|---|
> | 書き込み(trunc) 。既存のファイルを上書きします。ファイルが見つからなかった場合は新しいファイルを作成します。 |
>> | 書き込み(追加) 。ファイルを上書きしませんが、最後に新しいコンテンツを追加します。存在しないファイルを開くために使用される場合にもファイルを作成します。 |
< | 読む 。読み取り専用モードでファイルを開きます。 |
+< | 読み取り/書き込み 。ファイルを作成または切り捨てません。 |
+> | 読み取り/書き込み(trunc) 。ファイルを作成して切り捨てます。 |
+>> | 読み取り/書き込み(追加) 。作成しますが、ファイルを切り捨てません。 |
備考
chomp
は、ファイルから読み込むときによく使われます。デフォルトでは、改行文字を完全に機能させるためにperldocsを参照しますが、改行文字をトリムします。
文字とバイトの違いに注意してください:すべてのエンコード、特にUTF-8では1バイト文字を使用するわけではありません。これはPerlIOによって完全に処理されますが、潜在的な落とし穴が1つあります。
-
read
は、その長さとオフセットのパラメータに文字を使用します -
seek
とtell
常に バイトを使用して位置決めを行います
したがって、これらの混合値に基づいて算術演算を使用しないでください。代わりに、例えばEncode::encode('utf8',$value_by_read)
を使ってread
結果からオクテット(バイト)を取得します。そのカウントはtell
とseek
使用できます。
ファイルからの読み込み
my $filename = '/path/to/file';
open my $fh, '<', $filename or die "Failed to open file: $filename";
# You can then either read the file one line at a time...
while(chomp(my $line = <$fh>)) {
print $line . "\n";
}
# ...or read whole file into an array in one go
chomp(my @fileArray = <$fh>);
入力ファイルがUTF-8であることがわかっている場合は、エンコーディングを指定できます。
open my $fh, '<:encoding(utf8)', $filename or die "Failed to open file: $filename";
ファイルからの読み込みが終了したら、ファイルハンドルを閉じます。
close $fh or warn "close failed: $!";
参照: ファイルを変数に読み込む
ファイルを読み込むためのもう一つの速い方法は、File :: Slurper Moduleを使うことです。多くのファイルを扱う場合に便利です。
use File::Slurper;
my $file = read_text("path/to/file"); # utf8 without CRLF transforms by default
print $file; #Contains the file body
参照: [slurpでファイルを読む]
ファイルに書き込む
このコードは、書き込み用のファイルを開きます。ファイルを開くことができなかった場合はエラーを返します。また、最後にファイルを閉じます。
#!/usr/bin/perl
use strict;
use warnings;
use open qw( :encoding(UTF-8) :std ); # Make UTF-8 default encoding
# Open "output.txt" for writing (">") and from now on, refer to it as the variable $fh.
open(my $fh, ">", "output.txt")
# In case the action failed, print error message and quit.
or die "Can't open > output.txt: $!";
これで、 $fh
(この変数はファイルハンドルと呼ばれます )を介してアクセスする書き込み用のオープンファイルが作成されました。次に、 print
演算子を使用して出力をそのファイルに出力できます。
# Print "Hello" to $fh ("output.txt").
print $fh "Hello";
# Don't forget to close the file once we're done!
close $fh or warn "Close failed: $!";
open
演算子は、最初のパラメータとしてスカラー変数(この場合は$fh
)を持ちます。これはopen
演算子で定義されてopen
ため、 ファイルハンドルとして扱われます 。 2番目のパラメータ">"
(より大きい)は、ファイルが書き込み用に開かれていることを定義します。最後のパラメータは、データを書き込むファイルのパスです。
ファイルにデータを書き込むには、 ファイルハンドルとともにprint
演算子が使用されます 。 print
演算子には、 ファイルハンドルと文自体の間にコンマはなく、空白だけがあることに注意してください。
読むためのFileHandleを開く
一般的なASCIIテキストファイルを開く
open my $filehandle, '<', $name_of_file or die "Can't open $name_of_file, $!";
これは "デフォルトの"ファイルIOの基本的なイディオムで、 $filehandle
はデフォルトのシステム固有のデコーダでフィルタリングされたbytes
読み込み可能な入力ストリームを作成しbytes
。これはopen
プラグマでローカルに設定することができます
Perl自体はファイルを開く際にエラーを処理しないので、 open
終了条件をチェックすることでそれらを処理する必要がありopen
。 $!
オープンに失敗したエラーメッセージが入力されます。
Windowsでは、デフォルトのデコーダは "CRLF"フィルタで、入力の "\ r \ n"シーケンスを "\ n"にマップします。
バイナリファイルを開く
open my $filehandle, '<:raw', 'path/to/file' or die "Can't open $name_of_file, $!";
これは、PerlがWindows上でCRLF
変換を実行しないように指定します。
UTF8テキストファイルを開く
open my $filehandle, '<:raw:encoding(utf-8)', 'path/to/file'
or die "Can't open $name_of_file, $!";
これは、Perlは避けるべき両方のことを指定CRLF
(内部255を超えることが整数のアレイとして実装されている)の翻訳を、次に文字の文字列に、得られたバイトをデコードする、代わりのバイトのストリング
ファイルの読み書き
テキストファイルを読み書きする前に、使用するエンコーディングを知っておく必要があります。 エンコーディングの詳細については、Perl Unicodeのドキュメントを参照してください 。ここでは、関数open
デフォルトのエンコーディングとデコードとしてのUTF-8の設定を示します。これは、コードの先頭近くにあるopen
プラグマを使用することによって行われます( use strict;
をuse strict;
直後で、 use warnings;
をuse warnings;
することが適切です)。
use strict;
use warnings;
use open qw( :encoding(UTF-8) :std );
open
関数は、ファイルの読み書きに使用されるファイルハンドルを作成します。 open
関数には署名があります
open(FILEHANDLE, MODE, FILEPATH)
、操作が失敗した場合はfalseを返します。エラーの説明は$!
保存され$!
。
読書
#!/usr/bin/perl
use strict;
use warnings;
use open qw( :encoding(UTF-8) :std ); # Make UTF-8 default encoding
my $file_path = "/path/to/file";
open(my $file_handle, '<', $file_path) or die "Could not open file! $!";
while(my $row = <$file_handle>) {
print chomp($row), "\n";
}
close $file_handle
or warn "Close failed!";
書き込み
#!/usr/bin/perl
use strict;
use warnings;
use open qw( :encoding(UTF-8) :std ); # Make UTF-8 default encoding
my $file_path = "/path/to/file";
open(my $file_handle, '>', $file_path) or die "Could not open file! $!";
print $file_handle "Writing to a file";
close $file_handle
or warn "Close failed!";
チャンクを読む
大きなファイルを開いたり読んだりするのには、時間とリソースが必要です。コンテンツのほんの一部だけが必要な場合は、署名を持つread
関数を使用してチャンク内のコンテンツを読むことをお勧めします
read(FILEHANDLE, SCALAR, LENGTH, OFFSET)
FILEHANDLE
はオープンされたファイルハンドルでなければならず、 SCALAR
は操作後に読み取りデータを保持します。 LENGTH
は、 OFFSET
から読み出す文字数を指定します。この関数は、読み込まれた文字の数、ファイルの終わりに達した場合は0
、エラーの場合はundef
を返します。
read($file_handle, $data, 16, 0);
ファイルの先頭から16文字を$data
読み込み$data
。
"autodieを使用"し、ファイルのオープン/クローズの失敗をチェックする必要はありません
autodie
使用すると、オープン/クローズの失敗を明示的にチェックしなくても、ファイルをautodie
ことができます。
Perl 5.10.1以来、 autodie
プラグマはコアPerlで利用できました。使用すると、Perlはファイルを開いたり閉じたりするときにエラーを自動的にチェックします。
ここでは、1つのファイルのすべての行を読み取り、ログファイルの最後に書き込む例を示します。
use 5.010; # 5.010 and later enable "say", which prints arguments, then a newline
use strict; # require declaring variables (avoid silent errors due to typos)
use warnings; # enable helpful syntax-related warnings
use open qw( :encoding(UTF-8) :std ); # Make UTF-8 default encoding
use autodie; # Automatically handle errors in opening and closing files
open(my $fh_in, '<', "input.txt"); # check for failure is automatic
# open a file for appending (i.e. using ">>")
open( my $fh_log, '>>', "output.log"); # check for failure is automatic
while (my $line = readline $fh_in) # also works: while (my $line = <$fh_in>)
{
# remove newline
chomp $line;
# write to log file
say $fh_log $line or die "failed to print '$line'"; # autodie doesn't check print
}
# Close the file handles (check for failure is automatic)
close $fh_in;
close $fh_log;
ところで、技術的に常にprint
文をチェックするべきです。多くの人はそうしないが、 perl
(Perlの通訳者)はこれを自動的に行いませんし、 autodie
もしませautodie
。
ファイルハンドルを巻き戻す
読んだ後にバックトラックする必要があることがあります。
# identify current position in file, in case the first line isn't a comment
my $current_pos = tell;
while (my $line = readline $fh)
{
if ($line =~ /$START_OF_COMMENT_LINE/)
{
push @names, get_name_from_comment($line);
}
else {
last; # break out of the while loop
}
$current_pos = tell; # keep track of current position, in case we need to rewind the next line read
}
# Step back a line so that it can be processed later as the first data line
seek $fh, $current_pos, 0;
gzip圧縮ファイルの読み書き
gzippedファイルの作成
、gzipで圧縮されたファイルを書き込むにはuse
モジュールIO::Compress::Gzip
との新しいインスタンス作成することにより、ファイルハンドルを作成するIO::Compress::Gzip
所望の出力ファイルに対して:
use strict;
use warnings;
use open qw( :encoding(UTF-8) :std ); # Make UTF-8 default encoding
use IO::Compress::Gzip;
my $fh_out = IO::Compress::Gzip->new("hello.txt.gz");
print $fh_out "Hello World!\n";
close $fh_out;
use IO::Compress::Gzip;
gzippedファイルからの読み込み
gzipファイルから読み込むには、 IO::Uncompress::Gunzip
モジュールをuse
して、入力ファイルのIO::Uncompress::Gunzip
新しいインスタンスを作成してファイルハンドルを作成します。
#!/bin/env perl
use strict;
use warnings;
use open qw( :encoding(UTF-8) :std ); # Make UTF-8 default encoding
use IO::Uncompress::Gunzip;
my $fh_in = IO::Uncompress::Gunzip->new("hello.txt.gz");
my $line = readline $fh_in;
print $line;
IOのデフォルトエンコーディングの設定
# encode/decode UTF-8 for files and standard input/output
use open qw( :encoding(UTF-8) :std );
このpragma
は、テキスト(ファイル、標準入力、標準出力、および標準エラー)の読み取りと書き込みのデフォルトモードをUTF-8に変更します。これは通常、新しいアプリケーションを作成するときに必要なものです。
ASCIIはUTF-8のサブセットであるため、従来のASCIIファイルでは問題は発生しないと予想され、UTF-8ファイルをASCIIとして扱う際に起こりうる偶発的なファイル破損を防ぐのに役立ちます。
しかし、ファイルのエンコーディングがあなたが扱っているものが何であるかを知ってそれに応じて処理することが重要です。 ( Unicodeを無視してはならない理由 ) Unicodeの深い扱いについては、 Perl Unicodeのトピックを参照してください。