目次
はじめに
C++で、プログラムからファイルやディレクトリの名前を変更したり、別のディレクトリへ移動させたりしたい場合があります。
C++17で導入された <filesystem> ライブラリは、このための**std::filesystem::rename()**という関数を提供しています。この関数は、OSの move コマンドのように振る舞い、ファイル/ディレクトリの名前変更と移動の両方の役割を果たします。
【前提】C++17とは?
C++17は、2017年に正式化されたC++言語の規格です。<filesystem> ライブラリはこのC++17で導入されたため、利用するにはC++17に対応したコンパイラと、適切なコンパイラ設定(および、一部の環境ではリンカ設定)が必要になります。
rename() を使ったサンプルコード
このコードは、まずテスト用のファイル old_name.txt を作成し、それを rename() を使って new_name.txt という新しい名前に変更します。
完成コード
#include <iostream>
#include <filesystem>
#include <fstream> // ofstream
// filesystem名前空間のエイリアス
namespace fs = std::filesystem;
int main() {
fs::path original_path = "old_name.txt";
fs::path new_path = "new_name.txt";
// 1. テスト用のファイルを作成
std::ofstream test_file(original_path);
test_file.close();
std::cout << "変更前: " << std::endl;
std::cout << "「" << original_path << "」は存在しますか? -> " << std::boolalpha << fs::exists(original_path) << std::endl;
std::cout << "「" << new_path << "」は存在しますか? -> " << std::boolalpha << fs::exists(new_path) << std::endl;
try {
// 2. rename()で、ファイル名を変更
fs::rename(original_path, new_path);
std::cout << "\n--- rename()実行後 ---" << std::endl;
std::cout << "「" << original_path << "」は存在しますか? -> " << std::boolalpha << fs::exists(original_path) << std::endl;
std::cout << "「" << new_path << "」は存在しますか? -> " << std::boolalpha << fs::exists(new_path) << std::endl;
} catch (const fs::filesystem_error& e) {
std::cerr << "エラーが発生しました: " << e.what() << std::endl;
}
// 3. 後片付け
if (fs::exists(new_path)) {
fs::remove(new_path);
}
return 0;
}
コードの解説
fs::rename(from, to)
- 機能: 第1引数
fromで指定されたパスを、第2引数toで指定されたパスに名前変更または移動します。 - 引数:
std::filesystem::pathオブジェクトだけでなく、パスを表す文字列リテラルを直接渡すこともできます。 - 動作:
- 名前の変更:
fromとtoが同じディレクトリにある場合、ファイル/ディレクトリの名前が変更されます。(今回の例) - 移動:
fromとtoが異なるディレクトリにある場合、toで指定された場所にファイル/ディレクトリが移動します。
- 名前の変更:
- エラー処理:
fromが存在しない場合や、toが既に存在するファイルである場合など、操作に失敗するとstd::filesystem::filesystem_error例外をスローします。
まとめ
今回は、C++17の <filesystem> ライブラリを使って、ファイルやディレクトリの名前変更・移動を行う rename() 関数について解説しました。
<filesystem>ヘッダーをインクルードする。fs::rename(変更前のパス, 変更後のパス)の形で呼び出す。- この関数は名前変更と移動の両方の機能を持つ。
- 操作に失敗すると例外を投げるため、
try-catchでのエラーハンドリングが推奨される。
OSのコマンドラインツールを呼び出す必要なく、C++の標準機能だけで、クロスプラットフォームなファイル/ディレクトリの名前変更・移動処理を安全に記述できます。
