7

私はCプログラム(Linux)を開発しました。このプログラムは新しいファイルを作成して書き込み、その後PCを再起動します。

再起動後、プログラムによって作成されたファイルが失われました。再起動機能を無効にすると、プログラムによって作成されたファイルがまだ存在します。

この動作は Linux で見られます: - VirtualBox (ファイルシステム ext2) 上の OpenWrt (Backfire 10.03) - Linux (Ubuntu) (ファイルシステム ext4)

この動作の説明はありますか?どうすれば修正できますか?

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

int main ()
{
    FILE    *pFile;
    char    mybuffer[80];

    pFile = fopen ("/home/user/Desktop/example.txt","w");
    if (pFile == NULL) perror ("Error opening file");
    else
    {
        fputs ("test",pFile);
        fclose (pFile);
    }
    rename("/home/user/Desktop/example.txt","/home/user/Desktop/example123.txt");
    reboot(RB_AUTOBOOT);
    return 0;
}
4

4 に答える 4

7

fcloseのマニュアルページには次のように書かれています。

fclose()は、Cライブラリによって提供されるユーザースペースバッファーのみをフラッシュすることに注意してください。データが物理的にディスクに保存されるようにするには、たとえばsync(2)またはfsync(2)を使用して、カーネルバッファーもフラッシュする必要があります。

つまり、ファイル記述子を閉じる前にfsyncを呼び出す必要があります。

于 2012-05-14T15:10:14.970 に答える
1

ここで重要なことは、再起動が戻らないため、プログラムが実際に正常に終了しないことです。

通常の状態 (つまり、fclose を呼び出した後に終了またはクラッシュするプログラム) では、FILE * の下にあるファイル記述子が閉じられ、カーネル バッファーがフラッシュされます。

ただし、この場合、再起動が返されないため、カーネルバッファーが通常の方法でクリーンアップされていないため、ディスクにデータが書き込まれていないと思われます。

fsync 呼び出しがおそらくそれを処理します。偏執的になりたい場合は、fsync を実行してから、fileno() を使用してファイル記述子を取得し、sync() を使用してバッファーが確実にフラッシュされるようにします。その時点で、プロセスのアドレス空間にファイルが残っていないはずであり、再起動の呼び出しによってこれ以上問題が発生することはありません。

于 2012-05-14T15:20:22.490 に答える
0

別の解決策は、再起動のマニュアル ページに従って sync を呼び出すことです。

LINUX_REBOOT_CMD_POWER_OFF (RB_POWER_OFF、0x4321fedc; Linux 2.1.30 以降)。「パワーダウン」というメッセージ。が出力され、システムが停止し、可能であればシステムからすべての電源が切断されます。sync(2) が先行しない場合、データは失われます。

于 2015-10-14T19:01:45.750 に答える