ファイルシステムの関数
Nette\Utils\FileSystem は、ファイルシステムを扱う便利な関数を集めたクラスです。ネイティブの PHP 関数と比べた利点のひとつは、エラー時に例外を投げることです。
ディスク上のファイルを探したい場合は Finderを使ってください。
インストール:
composer require nette/utils
以下の例では、次のクラスの別名が定義されているものとします。
use Nette\Utils\FileSystem;
操作
copy (string $origin, string $target, bool $overwrite=true): void
ファイルまたはディレクトリ全体をコピーします。既定では既存のファイルやディレクトリを上書きします。$overwrite
を false にしていて、対象のファイルやディレクトリ $target
がすでに存在する場合は Nette\InvalidStateException を投げます。エラー時には
Nette\IOException を投げます。
FileSystem::copy('/path/to/source', '/path/to/dest', overwrite: true);
createDir (string $dir, int $mode=0777): void
ディレクトリが存在しなければ、親ディレクトリも含めて作ります。エラー時には
Nette\IOException を投げます。
FileSystem::createDir('/path/to/dir');
delete (string $path): void
ファイルまたはディレクトリ全体が存在すれば削除します。ディレクトリが空でない場合は、まずその中身を削除します。エラー時には
Nette\IOException を投げます。
FileSystem::delete('/path/to/fileOrDir');
makeWritable (string $path, int $dirMode=0777, int $fileMode=0666): void
ファイルの権限を $fileMode に、ディレクトリの権限を $dirMode
に設定します。ディレクトリの中身も再帰的に辿って権限を設定します。
FileSystem::makeWritable('/path/to/fileOrDir');
open (string $path, string $mode): resource
ファイルを開き、リソースのハンドルを返します。$mode パラメータはネイティブの fopen()
関数と同じように働きます。エラー時には Nette\IOException を投げます。
$res = FileSystem::open('/path/to/file', 'r');
read (string $file): string
ファイル $file の内容を読み込みます。エラー時には
Nette\IOException を投げます。
$content = FileSystem::read('/path/to/file');
readLines (string $file, bool $stripNewLines=true): \Generator
ファイルの内容を 1 行ずつ読み込みます。ネイティブの file()
関数と違い、ファイル全体をメモリに読み込まず、少しずつ読むので、使えるメモリより大きなファイルも読めます。$stripNewLines
は改行文字 \r と \n を取り除くかどうかを指定します。エラー時には
Nette\IOException を投げます。
$lines = FileSystem::readLines('/path/to/file');
foreach ($lines as $lineNum => $line) {
echo "Line $lineNum: $line\n";
}
rename (string $origin, string $target, bool $overwrite=true): void
$origin で指定したファイルやディレクトリの名前を $target
に変える、あるいはそこへ移動します。既定では既存のファイルやディレクトリを上書きします。$overwrite
を false にしていて、対象のファイルやディレクトリ $target
がすでに存在する場合は Nette\InvalidStateException を投げます。エラー時には
Nette\IOException を投げます。
FileSystem::rename('/path/to/source', '/path/to/dest', overwrite: true);
write (string $file, string $content, ?int $mode=0666): void
文字列 $content をファイル $file
に書き込みます。親ディレクトリが存在しなければ自動的に作られます。既定ではファイルの権限も設定します。chmod
の呼び出しを飛ばすには $mode に null を渡してください。エラー時には
Nette\IOException を投げます。
FileSystem::write('/path/to/file', $content);
writeAtomic (string $file, string $content, ?int $mode=0666): void
文字列 $content をファイル $file
にアトミックに書き込みます。内容はまず一時ファイルに書かれ、それが 1
段階で対象を置き換えます。ですから、同じ瞬間にファイルを読む側が、書きかけや切り詰められた状態を目にすることは決してありません。それ以外は
write() とまったく同じように振る舞います。エラー時には
Nette\IOException を投げます。
FileSystem::writeAtomic('/path/to/file', $content);
パス
isAbsolute (string $path): bool
パス $path が絶対パスかどうかを判定します。
FileSystem::isAbsolute('../backup'); // false
FileSystem::isAbsolute('/backup'); // true
FileSystem::isAbsolute('C:/backup'); // true
isValidFilename (string $name): bool
$name
がパス情報を含まない、プラットフォームをまたいで有効なファイル名かどうかを調べます。空文字列、.
と ..、制御文字、<>:"|?*\/ の文字、ピリオドや空白で終わる名前、Windows
の予約名(CON、NUL、COM1 など)を拒否します。
FileSystem::isValidFilename('photo.jpg'); // true
FileSystem::isValidFilename('../photo.jpg'); // false
FileSystem::isValidFilename('CON'); // false
joinPaths (string …$segments): string
すべてのパスの断片をつなぎ、結果を正規化します。
FileSystem::joinPaths('a', 'b', 'file.txt'); // 'a/b/file.txt'
FileSystem::joinPaths('/a/', '/b/'); // '/a/b/'
FileSystem::joinPaths('/a/', '/../b'); // '/b'
normalizePath (string $path): string
パスの中の
..、.、ディレクトリの区切りをシステムの標準に正規化します。
FileSystem::normalizePath('/file/.'); // '/file'
FileSystem::normalizePath('\file\..'); // '/'
FileSystem::normalizePath('/file/../..'); // '/..'
FileSystem::normalizePath('file/../../bar'); // '../bar'
unixSlashes (string $path): string
スラッシュを Unix 系システムで使う / に変換します。
$path = FileSystem::unixSlashes($path);
platformSlashes (string $path): string
スラッシュを現在のプラットフォーム固有の文字、つまり Windows では
\、それ以外では / に変換します。
$path = FileSystem::platformSlashes($path);
resolvePath (string $basePath, string $path): string
基準となるディレクトリ $basePath からの相対で $path
の最終的なパスを解決します。絶対パス(/foo、C:/foo)はそのまま(スラッシュの正規化だけ)で、相対パスは基準のパスに付け足されます。
// Windows では出力のスラッシュが逆向き(\)になります
FileSystem::resolvePath('/base/dir', '/abs/path'); // '/abs/path'
FileSystem::resolvePath('/base/dir', 'rel'); // '/base/dir/rel'
FileSystem::resolvePath('base/dir', '../file.txt'); // 'base/file.txt'
FileSystem::resolvePath('base', ''); // 'base'
静的な使い方と非静的な使い方
テストのためにこのクラスを別のもの(モックなど)に簡単に差し替えられるよう、非静的に使いましょう。
class AnyClassUsingFileSystem
{
public function __construct(
private FileSystem $fileSystem,
) {
}
public function readConfig(): string
{
return $this->fileSystem->read(/* ... */);
}
// ...
}