2

低レベルのI/O(read()、write()、lseek())とperror()の使用のみを許可する割り当てに取り組んでいます。

必要なinファイルとoutファイルを正しいアクセス許可で開くことができましたが、出力すると、inファイルの内容が無限ループになります。以下のスニペットを参照してください...

void *buf = malloc(1024);
while((n = read(in, buf, 1024)) > 0){
    if(lseek(in, n, SEEK_CUR) == -1){
        perror("in file not seekable");
        exit(-1);
    }
    while((m = write(out, buf, n)) > 0){
        if(lseek(out, m, SEEK_CUR) == -1){
            perror("out file not seekable");
            exit(-1);
        }
    }
    if(m == -1){ perror("error writing out"); exit(-1); }
}
if(n == -1){ perror("error reading in"); exit(-1); }

コードからエラートラップをいくつか削除しました。変数が初期化され、includeステートメントが存在すると想定できます。

4

2 に答える 2

2

問題は内部ループです:

while((m = write(out, buf, n)) > 0){

本当にする必要があります

if((m = write(out, buf, n)) > 0){

buf何度も何度も書くのではなく、一度だけ書きたいのです。また、処理する必要があるのは短い書き込みです。つまり、書き込みがm <n &&m>0で返される場合です。

また、lseek()呼び出しは間違っていますが、ループにはなりません。すでに現在のファイルオフセットを進めていますread()write()入力ファイルまたは出力ファイルのバイトをスキップする場合を除いて、手動で進める必要はありません(出力ファイルの場合、UNIXでは、バイトをスキップすると、ファイルにいわゆる「穴」が生じる可能性があります。ゼロですが、ディスク領域を占有しません)。

于 2012-03-19T00:41:14.163 に答える
0

読んだ後、なぜ入力ファイルを探しているのですか?最大で1024バイト(つまり、0から1024の間のどこかになります)を読み取るため、転送中にデータが失わnれるように、入力ファイルポインターを残した場所を超えて、継続的に検索します(おそらく、ファイルの終わりに近づいたときに、ファイルの終わりを超えています)。

これが無限ループの原因の1つかもしれませwhileんが、はるかに陰湿なのは書き込みに使用することです。これは成功するとゼロより大きい値を返すため、最初のチャンクをファイルに何度も繰り返し書き込みます。少なくとも、ディスク容量やその他のリソースが不足するまでは。

seekまた、書き込みも必要ありません。readandwrite呼び出しは、実行する必要があることを実行し、次のファイルポインタに正しく進むか手動で実行する必要はありません。readwrite

あなたはおそらく全体を次のように単純化することができます:

while ((n = read (in, buf, 1024)) > 0) {
    if ((m = write (out, buf, n)) != n) {
        perror ("error writing out");
        exit (-1);
    }
}

これには次の利点があります。

  • seek呼び出しを取り除く;
  • 「無限」ループを削除します。
  • 要求されたすべてのバイトを書き込んだことを確認します。
于 2012-03-19T00:38:40.070 に答える