2016-07-18 5 views
0

のようにreadline()のように機能します。readline()のような行単位で読み込みファイルを実装するには

最初に私はread(fd, buf, 4096);のようなファイルを読まなければなりません。buf[i]if (buf[i] == '\n')のようにバイト単位で比較しなければなりません。

したがって、対応するiが見つかった場合は、lseek()を使用して最初のファイルオフセットに移動してから、もう一度read(fd, buf, i)に移動します。このような操作を行った後、もう一度readline()コールがこのメカニズムを再び実行します。

私はこの解決策を最初に考えましたが、buf[i](バイト単位で比較することを意味します)を比較すると、fdのすべての文字を読み取るには遅すぎます。私はこれと同じように比較しなければならないのですか?

+4

なぜfget/fgetsを使用しないのですか? – inzanez

+0

行ごとに読み込まれます。しかし、私はread()を使って解を知りたい。 fgetsやその他の標準I/O関数は、最終的にread()、write()システムコールを使用するためです。 – allen

+3

ちょっとしたアイデア: 'readline'ソースコードを閲覧して、どうやって見ているのか見ることができます。 – Siguza

答えて

-2

fgetcを1文字で '読み込み'を使用して実装する場合は、独自のgetcを使用してreadlineを実装しますか?

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

char my_getc() 
{ 
    unsigned char ch[1]; 

    read(1, ch, 1); 

    return ch[0]; 

} 

char *my_readline() 
{ 
     char line[4096]; 
     char *ret; 
     char c; 
     int position = 0; 

     while(c = my_getc() != '\n') 
       line[position++] += c; 

     line[position] = '\0'; 

     ret = malloc(sizeof(char) * strlen(line)); 


     return ret; 
} 



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

     printf("%s\n", my_readline()); 

} 

あなたは十分にテストソリューションを必要とする場合は、多分、既存の実装のソースを読んでください、...

+0

1) 'ret []'の内容は決して設定されない - コードは機能しない2)バッファオーバフローに対する保護がない、3) 'EOF'検出がない。 4)割り当てられたバッファはフリーではありません。 – chux

3

私はあなたがfgets()を使用できない理由は、これはの練習であるということであることを想定していますPOSIXの低レベルのI/O関数について何かを学ぶことになっています。バッファリングについては少し参考にしてください。実際にデータを取得するだけの場合は、fdopen()でストリームをファイルディスクリプタで囲み、次にfgets()を使用して読み込むようにしてください。

私はこの解決策を最初に考えましたが、バイトごとの比較を意味するbuf [i]を比較すると、fdのすべての文字を読み取るには遅すぎます。私はこれと同じように比較しなければならないのですか?

指定されたバイトの最初の外観を読み取る必要があります。あなたが読んだ各バイトを調べることなく、どうやってそれをすることができると思いますか?おそらくハードウェアのサポートを除いて可能ではありません。そうは思わないでしょう。

あなたの懸念は、とにかく置き換えられていると思います。後でメモリ内のデータを調べるよりも、ディスクからメモリにデータを移動する方がはるかにコストがかかります。あなたが提案した低いレベルで作業し、良いパフォーマンスが必要な場合は、read()ベースのアプローチのように、適切な大きさのチャンクでディスクからデータを読み取る必要があります。

一方、でもはデータを再読み込みしないようにしています。そのため、パフォーマンスが良好であれば、lseek()は不適切です。さらに、パイプなどのシーク不可能なファイルを処理する必要がある場合は、lseek()は完全に問題になりません。どちらの場合でも、バッファを何らかの形で維持し、その内容から複数の要求に対応できるようにする必要があります。さらに、行境界がバッファ境界に対応しない可能性があること、改行を見つけるために複数の読み込みが必要なこと、行がバッファよりも長くなることが考えられることあれは。

したがって、fgets()と他のストリームベースのI/Oの選択肢はあなたの選択肢ではない場合、解決するバッファ管理の問題があります。私はそこから始めることをお勧めします。一度それがうまくいけば、そのバッファリングの点でfgets()のアナログを書くのは簡単です。

関連する問題