プログラミング言語のファイル操作まとめ

プログラミング

プログラミングでは、何らかのデータを読み出したり、書き出したりすることが数多くあります。

データの保存先は、データベースが用いられることが一般的ですが、まとまった文章や構造化されていないデータなどはファイルで保存されることも多くあります。

そのため、ファイル操作はプログラミングを学習する中で重要項目の1つとなります。

本ブログでは、JavaScript、Python、Java、Ruby、Goの5つの言語のファイル操作について解説してきました。

本記事では、各言語のファイル操作についてまとめます。

プログラミング初心者の方の学習や、忘れてしまった方の復習として、参考にしていただければ幸いです。

各言語の詳しい説明とソースコードは、各記事に記載しています。本記事の最後に関連記事として記載していますので、気になる方はチェックしてみてください。

プログラミング言語のファイル操作まとめ

ファイル操作として、以下の内容を採り上げます。

  • ファイル操作を扱うモジュールやパッケージ
  • ファイルの読み込み
  • ファイルの書き込み
  • ファイルの削除
  • ファイルの存在確認
  • ファイルのコピー
  • ディレクトリの一覧取得
  • ディレクトリの作成
  • ディレクトリの削除

ファイル操作を扱うモジュールやパッケージ

言語 ファイル操作を扱うモジュールやパッケージ
JavaScript
  • fsモジュール:ファイルの読み書き・操作、ディレクトリ操作
Python
  • 組込みのopen関数:ファイルの読み書き
  • os、os.pathモジュール:ファイル操作、ディレクトリ操作
  • shutilモジュール:再帰処理などの便利な操作
Java
  • java.nioパッケージ:ファイルの読み書き・操作、ディレクトリ操作
Ruby
  • 組込みモジュール:ファイルの読み書き・操作、ディレクトリ操作
  • FileUtilsモジュール:再帰処理などの便利な操作
Go
  • osパッケージ:ファイル操作、ディレクトリ操作
  • io、ioutilパッケージ:ファイルの読み書き、便利な操作
  • bufioパッケージ:バッファリング

どの言語も特別なライブラリなどは必要なく、標準で用意されているモジュールやパッケージで基本的な読み書きや操作を行うことができます。

ファイルの読み込み

言語 ファイルの読み込み
JavaScript
  • 一括読み込み:fs.readFileSync
  • 分割読み込み:fs.createReadStreamでストリームを取得
Python
  • 一括読み込み:openしてread
  • 分割読み込み:openしてreadlineで1行取得
Java
  • 一括読み込み:Files.readString
  • 分割読み込み:Files.linesでストリームを取得
Ruby
  • 一括読み込み:openしてread
  • 分割読み込み:openしてgetsで1行取得
Go
  • 一括読み込み:ioutil.ReadFile
  • 分割読み込み:bufio.NewScannerでバッファリングして取得

ファイルの読み込みには、一括ですべてのデータを読み込む方式と、分割して読み込む方式があります。

一括で読み込む方式のほうが簡単ですが、メモリの消費量が大きかったり、処理に時間がかかったりするため、小さいサイズと分かっている時に以外には使わないほうが賢明です。

分割して読み込む方式は、1行ずつ読み込む方法や、バイト単位で読み込む方法など様々あります。
また、処理を効率よく行うために、読み込みデータを溜め込むようなバッファリング処理を行うこともあります。(自動的に実施する言語もあります)

ファイルの書き込み

言語 ファイルの書き込み
JavaScript
  • 新規書き込み:fs.writeFileSync
  • 追記書き込み:fs.appendFileSync
Python
  • 新規書き込み:書き込みモードでopenしてwrite
  • 追記書き込み:追記モードでopenしてwrite
Java
  • 新規書き込み:Files.writeString
  • 追記書き込み:追記オプションを指定してFiles.writeString
Ruby
  • 新規書き込み:書き込みモードでopenしてputs
  • 追記書き込み:追記モードでopenしてputs
Go
  • 新規書き込み:ioutil.WriteFile
  • 追記書き込み:追記モードでOpenFileしてFprintln

新規書き込みは、どの言語でもファイルが存在しなければ新規に作成し、すでに存在する場合には新たに先頭から書き込みをおこないます。

追記書き込みは、専用のメソッドが用意されている言語とモードやオプションを指定すると追記となる言語など様々で、ファイルが存在しない場合には、新たに作成するものとエラーとなるもので様々ですので、よく確認する必要があります。

また、読み込みと同様で、大量データを一括で書き込むと効率が悪くなるため、分割書き込みやバッファリングするなどの対策を行う必要があります。

ファイルの削除

言語 ファイルの削除
JavaScript
  • fs.unlinkSync
Python
  • os.remove
Java
  • Files.delete
  • Files.deleteInfExists(ファイルが存在しない場合でもエラーとならない)
Ruby
  • File.delete、File.unlink
Go
  • os.Remove

ファイルの削除は、どの言語でもファイルが存在しない場合は、エラーとなりますので、削除前に存在チェックをすることや、例外処理を適切に行うなどの対応が必要となります。

ファイルの存在確認

言語 ファイルの存在確認、ファイルかディレクトリかの判別
JavaScript
  • 存在確認:fs.existsSync
  • 種類判別:fs.statSyncで取得した情報に対してisFileまたはisDirectory
Python
  • 存在確認:os.path.exists
  • 種類判別:os.path.isfileまたはos.path.isdir
Java
  • 存在確認:Files.exists
  • 種類判別:Files.isRegularFileまたはFiles.isDirectory
Ruby
  • 存在確認:File.exist?
  • 種類判別:File.file?またはFile.directory?
Go
  • 存在確認:os.Statで取得したエラー情報に対してos.IsNotExist
  • 種類判別:os.Statで取得した情報に対してIsDir

ほとんどの言語が存在する場合はtrue、存在しない場合はfalseを返す専用のメソッドがあるのに対して、Go言語だけは少し特殊な確認方法となります。

どの言語もディレクトリも含めての存在確認となります。

ファイルのコピー

言語 ファイルのコピー
JavaScript
  • fs.copyFileSync
Python
  • shutil.copy
Java
  • Files.copy
Ruby
  • FileUtils.copy
Go
  • io.Copy

コピー先にファイルが存在する場合は、どの言語も上書き処理を行います。
言語によっては、オプションの指定などにより、コピー先にファイルが存在する場合はエラーにしたりすることもできます。

また、普通にコピーすると、ファイルの作成日時や更新日時はコピーされませんが、それらも含めてコピーするための方法も提供されていたりします。

ディレクトリの一覧取得

言語 ディレクトリの一覧取得
JavaScript
  • 直下のみ取得:fs.readdirSync
  • 再帰的に取得:自分で再帰処理を実装
Python
  • 直下のみ取得:os.listdir
  • 再帰的に取得:glob.globのrecursiveオプションを指定
Java
  • 直下のみ取得:Files.list
  • 再帰的に取得:Files.walk、Files.find
Ruby
  • 直下のみ取得:Dir.children
  • 再帰的に取得:Dir.glob
Go
  • 直下のみ取得:ioutil.ReadDir
  • 再帰的に取得:filepath.Walk

ディレクトリの一覧取得は、取得対象のディレクトリ直下のみを取得するか、配下のすべてを再帰的に取得するかで方法が分かれます。

再帰的に取得する方法もほとんどの言語で方法が提供されていますが、取得対象を絞り込む条件を指定できるなど、便利な方法が提供されているものもあります。

ディレクトリの作成

言語 ディレクトリの作成
JavaScript
  • 対象のみ作成:fs.mkdirSync
  • 親も含めて一括作成:fs.mkdirSyncにrecursiveオプション指定
  • 一時ディレクトリとして作成:fs.mkdtempSync
Python
  • 対象のみ作成:os.mkdir
  • 親も含めて一括作成:os.makedirs
  • 一時ディレクトリとして作成:tempfile.TemporaryDirectory
Java
  • 対象のみ作成:Files.createDirectory
  • 親も含めて一括作成:Files.createDirectories
  • 一時ディレクトリとして作成:Files.createTempDirectory
Ruby
  • 対象のみ作成:Dir.mkdir
  • 親も含めて一括作成:FilesUtils.makedirs
  • 一時ディレクトリとして作成:Dir.mktmpdir
Go
  • 対象のみ作成:os.Mkdir
  • 親も含めて一括作成:os.MkdirAll
  • 一時ディレクトリとして作成:ioutil.TempDir

指定したディレクトリのみ作成する場合は、親ディレクトリが存在しなかったり、すでに作成対象が存在する場合はエラーとなります。

親ディレクトリも含めて一括で作成する場合は、作成対象がすでに存在していてもエラーにならないなどの違いがあります。

一時ディレクトリの作成は、どの言語も基本的にランダムな文字列を作成してディレクトリ名とします。
作成したディレクトリを処理後に残すか、自動的に削除するかは言語によって違いがあります。

ディレクトリの削除

言語 ディレクトリの削除
JavaScript
  • 対象のみ削除:fs.rmdirSync
  • 再帰的に削除:fs.rmSyncにrecursiveオプションを指定
Python
  • 対象のみ削除:os.rmdir
  • 再帰的に削除:shutil.rmtree
Java
  • 対象のみ削除:Files.delete
  • 再帰的に削除:Files.walkで削除対象を再帰取得してFiles.delete
Ruby
  • 対象のみ削除:Dir.rmdir
  • 再帰的に削除:FileUtils.remove_entry_secure
Go
  • 対象のみ削除:os.Remove
  • 再帰的に削除:os.RemoveAll

対象ディレクトリのみ削除する場合は、配下にファイルやディレクトリが存在する場合はエラーとなります。

再帰的に削除する場合は、基本的にエラーの発生が抑制されますが、オプションなどにより指定することが可能な言語もあります。

複数の処理で1つのファイル操作を行う場合は要注意

ファイルはデータを保存しておく場所として使いやすいのですが、複数のプロセスやスレッドなどから同じファイルを操作しようとすると思わぬことが発生することがあるので注意が必要です。

僕がこれまでに携わったプロジェクトでも以下のようなことがありました。

  • 複数のプロセスから同一のログファイルに書き込んだらファイルが壊れた
  • 参照しようとしたら別の処理が先に消していた
  • あるサーバが作成したファイルを別のサーバから参照しようとしたら、存在するはずのファイルが見えない状態だった

これらは、設計ミスやOSのファイル管理方法を理解出来ていないことが原因で発生したものでした。

ファイルはOSと密接に関わっているため、ローカル環境では上手く動いても、別の環境では意図通りに動かないといったことがあります。

ファイルを扱う際は、設計時点で問題ないかをきちんと議論することをおすすめします。

 

今回はプログラミング言語のファイル操作についてまとめました。

以上、参考になれば幸いです。

関連記事

各言語の詳しい解説とソースコードは下記の記事をご覧ください。

JavaScriptのファイル操作【プログラミング初心者向け教材】
プログラミングでは、何らかのデータを読み出したり、書き出したりすることが数多くあります。 そのため、ファイル操作はプログラミングを学習する中で重要項目の1つとなります。 本記事では、JavaScriptでよく使われるファイル操作について解説します。
Pythonのファイル操作【プログラミング初心者向け教材】
プログラミングでは、何らかのデータを読み出したり、書き出したりすることが数多くあります。 そのため、ファイル操作はプログラミングを学習する中で重要項目の1つとなります。 本記事では、Pythonでよく使われるファイル操作について解説します。
Javaのファイル操作【プログラミング初心者向け教材】
プログラミングでは、何らかのデータを読み出したり、書き出したりすることが数多くあります。 そのため、ファイル操作はプログラミングを学習する中で重要項目の1つとなります。 本記事では、Javaでよく使われるファイル操作について解説します。
Rubyのファイル操作【プログラミング初心者向け教材】
プログラミングでは、何らかのデータを読み出したり、書き出したりすることが数多くあります。 そのため、ファイル操作はプログラミングを学習する中で重要項目の1つとなります。 本記事では、Rubyでよく使われるファイル操作について解説します。
Goのファイル操作【プログラミング初心者向け教材】
プログラミングでは、何らかのデータを読み出したり、書き出したりすることが数多くあります。 そのため、ファイル操作はプログラミングを学習する中で重要項目の1つとなります。 本記事では、Goでよく使われるファイル操作について解説します。

コメント

タイトルとURLをコピーしました