こんにちは。
Centos5.7環境でのC言語に関する質問です。
下記にソースコードがあります。
実行フォルダに「For_nfs_bug.txt」というファイルがあります。中身は適当です。
これをコピーして、「For_nfs_bug_XXXXXX」(XXXXXXはランダム)という名前のファイルが生成されます。
そして「For_nfs_bug_XXXXXX」をremoveします。
プログラムを終了させないためwhile(1){}で止めています。
エラー等はなく、削除も問題なくできます。しかし、隠しファイルで
「.nfs0000000008a9800f000017d8」のようなファイルができています。nfs以下の文字列はランダムかと思われます。
質問は、この.nfsファイルができないように削除する方法はないか、ということです。
一応考えているのは、コピーの作業を関数にして、その関数を別にコンパイルし、
systemで実行させるということです。(Linuxのcpコマンドのような感じです)
一応追記で何が問題かを書きます。
実際に使うプログラムではFor_nfs_bug.txtのサイズが10MB~30MBと巨大です。さらに、コピーは
1回のプログラムで100回~2000回程度になります。
そのため回数が増えるごとに巨大な.nfsができてしまい、途中でプログラムが止まってしまいます。
おそらくHDの容量を超えるのだと思います。
以上です。
非常に困っています。よろしくお願いします。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int i, c;
char str[512];
char file2[512];
char tmp[512];
char test[]="For_nfs_bug";
FILE *fp,*fp2;
sprintf(str, "%s.txt", test);
strcpy(tmp, "XXXXXX");
mkstemp(tmp);
sprintf(file2, "%s_%s", test, tmp);
rename(tmp, file2);
//コピー元open
fp = fopen( str, "r" );
if( fp == NULL ){
fputs( "file open error(1)\n", stderr );
exit( EXIT_FAILURE );
}
//コピー先open
fp2 = fopen(file2, "w");
if( fp2 == NULL ){
fputs( "file open error(2)\n", stderr );
exit( EXIT_FAILURE );
}
//コピー実行
while( 1 ){
c = fgetc( fp );
if( c == EOF ){
if( feof( fp ) ){
break;
}
else if( ferror( fp ) ){
fputs( "error(3)\n", stderr );
exit( EXIT_FAILURE );
}
}
fputc( c, fp2 );
}
i = fclose( fp );
if( i != 0 ){
fputs( "error(4)\n", stderr );
exit( EXIT_FAILURE );
}
i = fclose( fp2 );
if( i != 0 ){
fputs( "error(5)\n", stderr );
exit( EXIT_FAILURE );
}
sprintf(str, "rm %s", file2);
system(str);
printf("%s\n", str);
while(1){}
return 0;
}
C言語Linux:fcloseしたファイルを消すと.nfsファイルができてしまう
Re: C言語Linux:fcloseしたファイルを消すと.nfsファイルができてしまう
想像ですが、mkstempで作成されたファイルをオープンしたまま、名前変更・書き込みオープンしているのが問題なのでは?
mkstempから返るファイルディスクリプタを使ってコピー先をオープンするように書き換えてみました。
想像が当たっていたなら、これで直るはずですが。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int i, c;
char str[512];
char file2[512];
char test[]="For_nfs_bug";
int fd2;
FILE *fp,*fp2;
sprintf(str, "%s.txt", test);
sprintf(file2, "%s_XXXXXX", test);
fd2 = mkstemp(file2);
if( fd2 == -1 ) {
fputs( "tempfile make error\n", stderr );
exit( EXIT_FAILURE );
}
//コピー元open
fp = fopen( str, "r" );
if( fp == NULL ) {
fputs( "file open error(1)\n", stderr );
exit( EXIT_FAILURE );
}
//コピー先open
fp2 = fdopen(fd2, "w");
if( fp2 == NULL ) {
fputs( "file open error(2)\n", stderr );
exit( EXIT_FAILURE );
}
//コピー実行
while( 1 ) {
c = fgetc( fp );
if( c == EOF ) {
if( feof( fp ) ) {
break;
}
else if( ferror( fp ) ) {
fputs( "error(3)\n", stderr );
exit( EXIT_FAILURE );
}
}
fputc( c, fp2 );
}
i = fclose( fp );
if( i != 0 ) {
fputs( "error(4)\n", stderr );
exit( EXIT_FAILURE );
}
i = fclose( fp2 );
if( i != 0 ) {
fputs( "error(5)\n", stderr );
exit( EXIT_FAILURE );
}
sprintf(str, "rm %s", file2);
system(str);
printf("%s\n", str);
while(1) {}
return 0;
}
想像が当たっていたなら、これで直るはずですが。
Re: C言語Linux:fcloseしたファイルを消すと.nfsファイルができてしまう
ISLe様
回答ありがとうございます。
想像で理解できるとは羨ましい限りです。
仰るとおりで、.nfsファイルはなくなりました。
最後に一つだけ質問させてください。
fdopen関数にはあまり馴染みがありません。
また、このプログラムは他人が見る可能性もあり、
fdopenは避けてfopenに統一しようと考えました。
そこで、 私の元のプログラム内のmkstemp部分を
としました。これで.nfsファイルは出現しなくなりました。
この書き方は正しいものでしょうか?
それともISLe様の通りfdopenで開いて、その後fcloseで閉じる方法でないと
いけないでしょうか。
よろしくお願いします。
回答ありがとうございます。
想像で理解できるとは羨ましい限りです。
仰るとおりで、.nfsファイルはなくなりました。
最後に一つだけ質問させてください。
fdopen関数にはあまり馴染みがありません。
また、このプログラムは他人が見る可能性もあり、
fdopenは避けてfopenに統一しようと考えました。
そこで、 私の元のプログラム内のmkstemp部分を
オフトピック
fd = mkstemp(tmp);
close(fd);
close(fd);
この書き方は正しいものでしょうか?
それともISLe様の通りfdopenで開いて、その後fcloseで閉じる方法でないと
いけないでしょうか。
よろしくお願いします。
Re: C言語Linux:fcloseしたファイルを消すと.nfsファイルができてしまう
馴染みがないのはmkstemp関数にも言えるのではないでしょうか。
mkstemp関数が使えてfdopen関数が使えないようなことはないと思いますが。
書き方として正しいか正しくないかと言ったら正しいです。
ただし期待するように動くかどうかは別の話です。
いったんクローズしたら、同じファイル名でオープンできない可能性が増すのではないでしょうかね。
mkstemp関数が使えてfdopen関数が使えないようなことはないと思いますが。
書き方として正しいか正しくないかと言ったら正しいです。
ただし期待するように動くかどうかは別の話です。
いったんクローズしたら、同じファイル名でオープンできない可能性が増すのではないでしょうかね。