アプリ版:「スタンプのみでお礼する」機能のリリースについて

FTPで書き込み中のファイルがあるとします。そのファイルが、書き込み中なのか、それとも、書き込みが完了したのかを、知りたいのですが、良い方法はありますでしょうか。書き込みファイル名はあらかじめ、わかっています。(書き込み中に読んだ場合、最後まで読み切ることが出来ないために書き込み完了迄待ちます)当方で、調査した限りでは、ファイル名を指定して、そのファイルが、他プロセスによってオープンされているか否かを知るシステムコールは存在しませんでした。OSは、sun solaris10を使用の予定ですが、UNIX系(linux含む)で実現可能であれば、かまいません。

A 回答 (13件中1~10件)

fopen(ファイル名,"r+")


オープンできれば書き込み終了、失敗ならば書き込み中。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。提示していただいた方法を当方にて確認しましたところ、他のプロセスが、書き込み中でも、正常にオープン出来てしましました。
以下、書き込み側のソースです。
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>

int main(int argc , char *argv[])
{
FILE *fp;
char area[256];
int i = 0;
if (argc == 1){
printf("%s 書き込みファイル名\n",argv[0]);
exit(0);
}
fp = fopen(argv[1],"w");
if (fp == NULL){
printf("fopen error\n");
exit(0);
}
while(1){
sprintf(area,"===============%d================\n",i++);
if (fputs(area,fp) == EOF){
printf("fputs error\n");
exit(0);
}
if (fflush(fp) == EOF){
printf("fflush error\n");
exit(0);
}
printf("%d完了\n",i);
sleep(10);
}
fclose(fp);
return(0);
}
以下、読み込み側のソースです。
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>

int main(int argc , char *argv[])
{
FILE *fp;
char area[256];
int i = 0;
if (argc == 1){
printf("%s 読み込みファイル名\n",argv[0]);
exit(0);
}
fp = fopen(argv[1],"r+");
if (fp == NULL){
printf("fopen error\n");
exit(0);
}
printf("オープン成功\n");
fclose(fp);
return(0);
}

動作確認は
Solaris10(INTEL版)
cent-os 4.4 で行いました。

お礼日時:2007/09/07 21:49

一般のUnix系のOSで、fopen() でチェックできるかどうかは疑問です^^



たしかに、Unix系のOSで、ファイルをオープンしているプロセスがあるかどうかを調べられるような標準的なシステムコールがあるという話は、あまり聞かないですよね。

http://www.mlb.co.jp/linux/mld-ml/200206/msg0002 … ←存在しないのがほんとに真実かどうかは知りませんが^^

ftp の際、get してくるファイルのサイズ情報をどこかに出力しておいて、そのサイズに達したか否かで、「書き込み中か、書き込み完了か」を判定するのがもっともポータブルな方法かと^^

※ 最初に lseek などして、見掛けのサイズを大きくしておいてから rewind して実際に書き込みを始めるみたいなことしてる ftp の実装なんてあるとまずいですけど^^;
    • good
    • 2
この回答へのお礼

ご回答ありがとうございます。やはり、無いと考えたほうが、良さそうでね。求めるシステムコールが、存在しない場合の対策案は、私のほうで、2、3検討済みです。
1案:対象ファイル送信後に、送信完了を示す、別なファイル(サイズ:0)をおくる。読み込み側は、サイズ:0のファイルの出現で、目的ファイルの送信完了を判定。
2案:対象ファイルを別の一時的な名前で書き込み、完了後に正規の名前にリネームする。リネームされて、求めるファイルが出現したときは、既に書き込みが完了されたファイルとなっている。
3案:実際のファイルの内容の最後に、ファイル終端であることを示す、あらかじめ決められた特定の文字列を書き込む。読み込み側は、その文字列まで読めれば、書き込みが完了したファイルと判定する。
などの方法がありますが、いずれもFTPの送信側(書き込み側)にある一定の操作が必要となります。できたら、そのような操作をさせたくなかったので、質問した次第です。

お礼日時:2007/09/07 22:05

なるほど、そういうことでしたか^^



わたしなら、ファイルサイズを受け取るか、tatsu99 さんの1案を採用しますね。2案はレースコンディションがありそうですし。。3案は、ターゲットのファイルの種類が決まっていて、終了文字がきちんと決められるなら一番簡単な方法ですね。

tatsu99 さんの、1案が一番確実・簡単でいいですかね。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
>2案はレースコンディションがありそうですし。。
とのことですが、具体的にどのような状態を想定されてますでしょうか?

お礼日時:2007/09/07 22:45

あぁ。

。すみません^^ ファイルをコピーするのか勘違いしてました^^; link()、unlink() を使ってやるなら大丈夫そうですね。
    • good
    • 0

あぁ、あと、ftp をプログラム内から fork()・exec() させてるなら、wait() したり、ほかに仕事があるなら waitpid() したり、 SIGCHILD をうけとるようにしたりする方法もありますね^^



tatsu99 さんは、詳しそうなのでご存知でしょうが^^ 蛇足として。。。(笑)
    • good
    • 0
この回答へのお礼

ファイルの送信側は、シェルスクリプトからftpコマンドを呼びだすことを、今は、考えています。ですので、あまり複雑なことは、出来ません。また、送信側にあまり、コストをかける訳にもいかないので、シェルから呼び出す程度になるかと思います。まあ、送信時のエラー検知ぐらいは、したほうが良いと考えていますが・・・。

お礼日時:2007/09/08 06:22

あぁ、なるど。

。。送り手側が、別マシンから受け手側のマシンに ftp でファイルを put しにくるわけですか。。「ssh などを使わないので、リモートでコマンド実行できるわけではないため、受け手側はファイルが置かれたかポーリングはするが、書き込みが終了しているかを確認する手軽な手段が欲しかった」というわけですね。
    • good
    • 1
この回答へのお礼

はい、まさに、その通りです。「受け手側はファイルが置かれたかポーリングはするが、書き込みが終了しているかを確認する手軽な手段」を実現するシステムコールがあればと思って、質問した次第です。

お礼日時:2007/09/08 08:31

それでは、ファイル名に、ファイルサイズを含めれば簡単じゃないですかね。

ファイル名の長さに余裕があるシステムだと仮定して、たとえば、123456Byte なら、filename_123456.txt とか^^ 安易すぎるかな(笑)
    • good
    • 0

で、あとは、受け手側は、ファイル名に含まれるバイトサイズを信用して、そのバイトサイズに達するまで読み続ける。

エラー処理が難しいですかね^^;
    • good
    • 0

すごく大雑把な方法ですが、statで最終修正時刻を調べて一定時間以上変更がなかったら書き込みが終了とみなすのはだめでしょうか?


信頼性と即時応答性は限りなく低いですが。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
>すごく大雑把な方法ですが、statで最終修正時刻を調べて一定時間以上変更がなかったら書き込みが終了とみなすのはだめでしょうか?
その方法と同じではないですがstatでファイルサイズを調べて、一定時間経過後、前回と同じなら、書き込み完了とみなす。
ということは、考えておりました。
statで調査する場合は以下の長所/短所になるかと思います。
長所:FTPの送信側によけいな処理をさせないで済む。
短所:>>「信頼性と即時応答性は限りなく低いですが。」
運用上、上記の短所が問題にならなければ、statを繰り返す方法もありかと考えております。

お礼日時:2007/09/08 11:03

なるほど。

。修正時刻のチェックしてもいいですね。各人各様で思いつくテクニックが異なっておもしろいですね^^

そういえば、ファイル名にファイルサイズを入れるとしても、バイナリモードで転送しないと、Windows⇔Unix⇔Macintoshなんかは、サイズが変わってしまいますねぇ。まぁ、でも、バイナリで転送するとして、stat()・lstat() を使うなら読み続けなくても、ファイルが置かれるディレクトリを舐めて、各ファイルの名前から取得したファイルサイズとstat()が返すファイルサイズをチェックするだけでいいですね^^
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
>バイナリで転送するとして、stat()・lstat() を使うなら読み続けなくても、ファイルが置かれるディレクトリを舐めて、各ファイルの名前から取得したファイルサイズとstat()が返すファイルサイズをチェックするだけでいいですね^^
上記の場合の長所と短所は以下になるかと思います。
長所:statが一回ですむ。
短所:FTP送信側での処理が多少発生する。
受信側でもファイル名にファイルサイズを含むため、ファイル名が固定にならずに、XXXXX_nnnnnn(nnnnnはファイルサイズ)にマッチするようなファイルを取得する必要がある。

運用上、上記の短所が問題にならなければ、採用の候補として検討したいと考えています。

お礼日時:2007/09/08 11:23

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A