C プログラミングの分野では、入力、出力、メモリを効果的に管理することが基本です。これらの重要な概念を理解するのに役立つように、get_next_line は、ファイル記述子を使用してファイルを 1 行ずつ読み取る関数を作成するプロジェクトです。関数を呼び出すたびにファイルから次の行が読み取られるため、ファイルの内容全体を一度に 1 行ずつ処理できます。
ファイル記述子は、システム内で開いているファイルを一意に識別する非負の整数です。プログラムがファイルを開くと、オペレーティング システムは、ファイルの読み取り、書き込み、閉じるなどの後続の操作でそのファイルを参照するために使用できるファイル記述子を返します。ファイル記述子は、ファイル、ソケット、パイプなどのさまざまな I/O リソースを管理するためにオペレーティング システムによって使用される抽象概念です。
プロセス A の0、1、および 2 (標準入力、標準出力、および標準エラー) は独立しており、プロセス B のファイル記述子から分離されています。この分離により、1 つのプロセスでのファイル操作が他のプロセスのファイル操作に干渉しないことが保証されます。別の。
各ファイル記述子は、ファイルに関する重要な情報を含むファイル記述子テーブル エントリに関連付けられます。これには、ファイル パス、アクセス許可、および読み取り/書き込み操作のファイル内の位置を追跡する現在のオフセットが含まれます。この構造により、オペレーティング システムは複数の開いているファイルを効率的に管理し、正しいアクセスとデータ操作を保証できます。
ファイル記述子 0、1、および 2 は、オペレーティング システムによって標準ストリーム用に予約されていることに注意してください。ファイル記述子 0 は標準入力 (stdin) に使用され、通常はキーボードからの入力を表します。ファイル記述子 1 は、画面または端末への出力を表す標準出力 (stdout) に使用されます。ファイル記述子 2 は標準エラー (stderr) に使用されます。これも画面または端末への出力を表しますが、特にエラー メッセージを目的としています。これらの予約されたファイル記述子により、さまざまなプログラムや環境にわたって基本的な入出力操作を一貫して管理できるようになります。 open 関数によって返されるファイル記述子はすべて 3 以上になり、これらの標準ストリームと競合しないことが保証されます。
'#include
'
'#include' int fd = open("example.txt", O_RDONLY);
if (fd == -1) {
perror("Error opening file");
return 1;
}
整数として表されるファイル記述子は、open 関数を使用して取得されます。この関数は、ファイル名 (またはパス) とファイルのアクセス許可を決定するフラグの 2 つのパラメーターを受け取ります。たとえば、ファイルの内容を読み取るには、O_RDONLY フラグ (読み取り専用) を使用します。読み取りと書き込みには、O_RDWR フラグを使用します。利用可能なフラグは多数ありますが、このプロジェクトでは O_RDONLY のみを使用します。 open 関数は、操作が成功した場合はファイル記述子である非負の整数を返します。それ以外の場合は、エラーを示す -1 を返します (example.txt にアクセスする権限がありません)。 open 関数は unistd.h ライブラリ内にあり、許可フラグは fcntl.h.
で定義されていることに注意してください。'#include
'
'#include'
'#include'
'#define BUFFER_SIZE 4'int fd = open("example.txt", O_RDONLY);
if (fd == -1) {
perror("Error opening file");
return 1;
}
char buffer[BUFFER_SIZE];
read(fd, buffer, sizeof(buffer)-1);
printf("1st call : %s\n", buffer);
// prints the first 3 bytes
read(fd, buffer, sizeof(buffer)-1);
printf("2nd call : %s\n", buffer);
read(fd, buffer, sizeof(buffer)-1);
printf("3rd call : %s\n", buffer);
read(fd, buffer, sizeof(buffer)-1);
printf("4th call : %s\n", buffer);
read(fd, buffer, sizeof(buffer)-1);
printf("5th call : %s\n", buffer);
コード結果
1回目のコール:HEL
2回目のコール:LO
3回目の呼び出し:WOR
4回目のコール:LD
5 回目の呼び出し: (null)
unistd.h ライブラリによって提供される読み取り関数は、ファイル記述子からデータを読み取るために使用されます。ファイル記述子、読み取りデータを保存するバッファ、ファイルから読み取るバイト数の 3 つのパラメーターを受け取ります。読み取り関数は、ファイルから読み取ったバイト数を返します。
ファイル記述子テーブルには、offset と呼ばれる属性があります。オフセットは、ファイル内の現在位置を追跡します。読み取り関数が呼び出されるたびに、現在のオフセットからデータを読み取り、読み取ったバイト数だけオフセットを進めます。これにより、後続の読み取りは最後の読み取りが中断されたところから継続されるようになります。
この例では:
2 番目の read 呼び出しは、更新されたオフセット (3) から始まる次の 3 バイトを読み取り、オフセットを 6 に更新します。
など ...
読み取りバッファへの 5 回目の呼び出しは null になり、読み取りはファイルの終わりを示す 0 を返します。
このプロセスは、ファイルからすべてのデータが読み取られるか、エラーが発生するまで継続されます。バッファは文字列として出力できるように、各読み取り後に null で終了します。
char *get_next_line(int fd) は、パラメータとしてファイルのファイル記述子を受け取り、呼び出しごとに 1 行を返します。ファイルの終わりに達すると、NULL を返します。
https://github.com/Its-JoeTheKing/get_next_line
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3