1

これは、fedora 19 で gcc を使用してコンパイルされた、ファイルまたはディレクトリのコピーを作成するための ac コードです。実行されますが、停止せず、作成された新しいファイルのサイズが途方もなく大きくなり続けることがわかります。このコードの何が問題になっていますか?

#include<fcntl.h>
#include<stdio.h>
#include<unistd.h>

char buffer[2048];

int version = 1;

int main(int argc, char *argv[])
{
    void copy (int, int);

    int fdold, fdnew;

    if (argc != 3)
    {
        printf("insufficient arguments !!! \n");
        return (1);
    }

    fdold = open(argv[1], O_RDONLY);
    if (fdold == -1)
    {
        printf("cannot open file %s\n",argv[1]);
        return (1);
    }

    fdnew = creat(argv[2],0666);
    if (fdnew == -1)
    {
        printf("cannot create file %s\n",argv[2]);
        return (1);
    }

    copy (fdold, fdnew)

    return (0);
}

void copy (int fdold, int fdnew)
{
    int count;
    count = read(fdold, buffer, sizeof(buffer));

    while (count > 0)
        write(fdnew, buffer, count);
}
4

1 に答える 1

5

更新することはなくcount、同じデータを何度も書き続けます。このコードでは:

count = read(fdold, buffer, sizeof(buffer));
while (count > 0)
    write(fdnew, buffer, count);

ファイル記述子から1回読み取り、countバイトを取得し、それがより大きい間0(おそらくそうである)、バッファを新しいファイルに書き続けます。古いファイルからそれ以上データを読み取ることはありません。ファイルがどんどん大きくなっていることがわかる場合は、(コンテンツがディスクにフラッシュされる方法によっては) 同じコンテンツが何度も繰り返されていることも確認できる可能性があります。

実際に行う必要があるのは、次のようなものです。

while there is data to read from the old file
  read it into a buffer
  while there is data in the buffer to write to the new file
    write data from the buffer into the new file

少し疑似コーディッシュではありませんが、非常にテストされていない形式では、次のようなものを探していると思います。

int count = 0;
int written;
while ( 0 < (count = read(fdold, buffer, sizeof(buffer))) ) {
  written = 0;
  while ( count > (written += write(fdnew, buffer+written, count-written))) );
}

外側のループは、読み取るものがなくなるまで読み取ることを確認し、内側の whileは、読み取るすべてのバイトを書き込むまで、までの大きさにwriteなるまで呼び出すことを確認します。これは「巧妙な」コードですが、実際には巧妙すぎます。であるかどうかを実際に確認する必要があります。そうしないと、奇妙なことを始めてしまいます。writtencountwritten-1

エラーチェックがより多く、できればより慣用的なものは、次のようになります。

  for ( int count_in = -1; count_in != 0; ) {
    if ( -1 == (count_in = read(fd, buf, bufsize))) {
      perror("Problem reading from file");
      exit(-1);
    }
    else { 
      for ( int count_out = 0, out = 0; count_out < count_in; count_out += out ) {
        if ( -1 == (out = write(fd, buf+count_out, count_in-count_out)) ) {
          perror("Problem writing to file");
          exit(-1);
        }
      }
    }
  }
于 2013-10-18T04:07:22.087 に答える