先頭へ戻る

ファイルを移動する | Programming Place Plus C言語編 逆引き

Programming Place Plus トップページ -- C言語編 -- 逆引き

先頭へ戻る

この章の概要

この章の概要です。

目的

ファイルを、別のディレクトリ(用語集)(フォルダ(用語集))に移動したいとします。

方法①(rename関数を使う)

C言語の標準ライブラリ関数である rename関数を使います。

#include <stdio.h>

/*
    ファイルを移動する。

    srcPath:  移動元ファイルのパス
    destPath: 移動先ファイルのパス
    戻り値:   成功したら 0以外、失敗したら 0
*/
int moveFile(const char* srcPath, const char* destPath)
{
    return !rename(srcPath, destPath);
}

int main(void)
{
    if (moveFile("test.txt", "dir/test.txt")) {
        puts("移動しました。");
    }
    else {
        puts("移動に失敗しました。");
    }

    return 0;
}

実行結果:

移動しました。

rename関数は、その名前のとおり、ファイル名を変更することが目的の関数ですが、ファイルパスを指定できるので、変更後の名前として、移動先のファイルパスを指定すれば、ファイルの移動に使えます。

移動先として指定したファイルパスを持ったファイルがすでに存在している場合、どういう結果になるかは定義されていません。 Windows (Visual Studio) では失敗しますが、macOS (Xcode) では上書きされて、関数は成功します。

そのため、ファイルがすでに存在している場合の動作を制御したい場合は、追加の処理が必要になります。

失敗としたければ、直前でファイルの存在を確認して、 存在しているときは rename関数の実行自体を避けるようにします。 ファイルの存在を確認する方法は、「逆引き ファイルの存在を確認する」を参照してください。

#include <stdio.h>
#include <sys/stat.h>

/*
    ファイルの存在を確認する。

    path:   ファイルパス。
    戻り値: 存在したら 0以外、存在しなければ 0
*/
int existFile(const char* path)
{
    struct stat st;

    if (stat(path, &st) != 0) {
        return 0;
    }

    // ファイルかどうか
    // S_ISREG(st.st_mode); の方がシンプルだが、Visual Studio では使えない。
    return (st.st_mode & S_IFMT) == S_IFREG;
}

/*
    ファイルを移動する。

    srcPath:  移動元ファイルのパス
    destPath: 移動先ファイルのパス
    戻り値:   成功したら 0以外、失敗したら 0
*/
int moveFile(const char* srcPath, const char* destPath)
{
    // 移動先にファイルがすでに存在していたら、失敗とする
    if (existFile(destPath)) {
        return 0;
    }

    return !rename(srcPath, destPath);
}

int main(void)
{
    if (moveFile("test.txt", "dir/test.txt")) {
        puts("移動しました。");
    }
    else {
        puts("移動に失敗しました。");
    }

    return 0;
}

実行結果:

移動に失敗しました。

方法②(MoveFile関数を使う)[Windows]

Windows API には、ファイルの移動を行う MoveFile関数(⇒Microsoft Docs)が用意されています。また、より高度な機能を備えた MoveFileEx関数(⇒Microsoft Docs)があります。 ここでは MoveFile関数を取り上げます。

#include <stdio.h>
#include <Windows.h>

/*
    ファイルを移動する。

    srcPath:  移動元ファイルのパス
    destPath: 移動先ファイルのパス
    戻り値:   成功したら 0以外、失敗したら 0
*/
int moveFile(const char* srcPath, const char* destPath)
{
    return MoveFileA(srcPath, destPath);
}

int main(void)
{
    if (moveFile("test.txt", "dir/test.txt")) {
        puts("移動しました。");
    }
    else {
        puts("移動に失敗しました。");
    }

    return 0;
}

実行結果:

移動しました。

MoveFile関数を使用するには、Windows.h のインクルードが必要です。 また、MoveFile は実際にはマクロになっていて、UNICODEマクロの定義の有無によって、 ANSI版(char型)の MoveFileA と、Unicode版(wchar_t型)の MoveFileW のいずれかに置換されます。 上のサンプルプログラムでは、文字列を const char* で扱っているため、MoveFileA の方を直接呼び出すようにしています。

MoveFile関数の場合、移動先にファイルがすでに存在していた場合は失敗します。


参考リンク


更新履歴

'2018/4/2 「VisualC++」という表現を「VisualStudio」に統一。

'2017/6/21 新規作成。



逆引きのトップページへ

C言語編のトップページへ

Programming Place Plus のトップページへ



はてなブックマーク に保存 Pocket に保存 Facebook でシェア
Twitter でツイート Twitter をフォロー LINE で送る
rss1.0 取得ボタン RSS 管理者情報 プライバシーポリシー