1

上記のシステムコールを使用して、あるファイルから別のファイルに 512 バイトをコピーするプログラムを作成しようとしています (いくつかのバッファー、memcpy()、次に fwrite() を作成できますが、Unix 固有の低レベル I/ O)。コードの冒頭は次のとおりです。

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

int main(int argc, char **argv)
{
     int src, dest, bytes_read;
     char tmp_buf[512];

     if (argc < 3)
        printf("Needs 2 arguments.");

     printf("And this message I for some reason don't see.... o_O");

     if ((src = open(argv[1], O_RDWR, 0)) == -1 || (dest = open(argv[2], O_CREAT, 0)) == -1)
         perror("Error");

     while ((bytes_read = read(src, tmp_buf, 512)) != -1)
         write(dest, tmp_buf, 512);

   return 0;
}

読み取ったファイルのサイズが 512 の倍数にならないという事実に対処していないことはわかっています。しかし、最初に私は本当に2つのことを理解する必要があります:

  1. メッセージが表示されないのはなぜですか? セグメンテーション フォールトも発生しないので、プログラムから Cc で抜ける必要があります。

  2. これらの低レベル関数はどのように機能しますか? たとえば、FILE *file を fwrite で使用している場合、*file は自動的にインクリメントされますが、ファイル ポインタを手動でインクリメントする必要がありますか? もしそうなら、open() などがファイル ID だけではなく、ファイル ポインタを指定しないと仮定すると、どのようにアクセスするのでしょうか?

どんな助けでも素晴らしいでしょう。お願いします。ありがとうございました!

4

2 に答える 2

3

出力されたメッセージが表示されないのは、バッファーをフラッシュしていないためです。ただし、プログラムが完了すると、テキストが表示されるはずです(これは決して発生せず、その理由は、trojanfoe のコメントと paxdiablo の回答で説明されています)。文字列の最後に改行を追加するだけで表示できます。

そして、読み取り/書き込みループに重大なエラーがあります。要求されたバイトよりも少ない数を読み取った場合512でも、バイトは書き込まれ512ます。

また、開くときにエラーをチェックしますが、どのopen呼び出しが失敗したかはわかりません。エラーが発生しても、プログラムを続行します。

そして最後に、関数は非常に単純です。すべてを処理するカーネル内の関数を呼び出します。X バイトを読み取ると、呼び出しが完了した後、ファイル ポインタが X バイト前方に移動します。

于 2013-11-14T08:20:40.883 に答える
2

このメッセージが表示されないのは、ライン バッファ モードになっているためです。改行文字が検出された場合にのみフラッシュされます。

なぜ永遠に待っているのかというと、エラーの場合は -1 しか返されません

ファイルの最後まで正常に読み取ると、0 の戻り値が返されます。

より良いループは、次の行に沿ったものになります。

int bytes_left = 512;
while ((bytes_left > 0) {
    bytes_read = read(src, tmp_buf, bytes_left);
    if (bytes_read < 1) break;
    write(dest, tmp_buf, bytes_read);
    bytes_left -= bytes_read;
}
if (bytes_left < 0)
    ; // error of some sort
于 2013-11-14T08:21:38.353 に答える