5

read()を使用してソケットからデータを読み取り、受信バッファーをファイル(ofstream)または同様の自己拡張オブジェクト(ベクトルなど)にするC / C ++の方法はありますか?

編集: たとえば10000バイト以上のファイルの内容を受信する可能性のあるストリームソケットを読み取る方法を検討しているときに、質問が発生しました。私は、ファイルに固執するまでファイルを一時的に保存できるバッファーとして、20000または50000バイト(今のところ十分な大きさ)をスタックに置くのが好きではありませんでした。スターを付けるために、ファイルに直接ストリーミングしてみませんか。

std:string内のchar *に到達できるのと同じように、私は次のようなことを考えました。

read( int fd, outFile.front(), std::npos );  // npos = INT_MAX

またはそのようなもの。

編集終了

ありがとう。

4

2 に答える 2

4

これは単純で、私の指の先ではありませんが、これらの線に沿った何かがうまくいくと思います:

template <unsigned BUF_SIZE>
struct Buffer {
    char buf_[BUF_SIZE];
    int len_;
    Buffer () : buf_(), len_(0) {}
    int read (int fd) {
        int r = read(fd, buf_ + len_, BUF_SIZE - len_);
        if (r > 0) len_ += r;
        return r;
    }
    int capacity () const { return BUF_SIZE - len_; }
}

template <unsigned BUF_SIZE>
struct BufferStream {
    typedef std::unique_ptr< Buffer<BUF_SIZE> > BufferPtr;
    std::vector<BufferPtr> stream_;
    BufferStream () : stream_(1, BufferPtr(new Buffer<BUF_SIZE>)) {}
    int read (int fd) {
        if ((*stream_.rbegin())->capacity() == 0)
            stream_.push_back(BufferPtr(new Buffer<BUF_SIZE>));
        return (*stream_.rbegin())->read(fd);
    }
};

コメントで、大きなcharバッファの作成を避けたいとおっしゃいました。システムコールを使用する場合、read一般に、多数の小さな読み取りよりも、いくつかの大きな読み取りを実行する方が効率的です。したがって、ほとんどの実装では、その効率を上げるために大きな入力バッファを選択します。次のようなものを実装できます。

std::vector<char> input;
char in;
int r;
while ((r = read(fd, &in, 1)) == 1) input.push_back(in);

ただし、これにはシステムコールが含まれ、入力のバイトごとに少なくとも1バイトがコピーされます。対照的に、私が提示したコードは、余分なデータコピーを回避します。

私が出したコードがあなたが採用する解決策になるとは本当に期待していません。かなりスペースと時間の効率が良い自己拡張オブジェクトを作成する方法の図を提供したかっただけです。目的に応じて、拡張することも、独自に作成することもできます。頭から離れて、いくつかの改善点は次のとおりです。

  • std::list代わりに、ベクトルのサイズ変更を避けるために使用してください
  • APIに、読み取るバイト数を指定するパラメーターを許可します
  • readv一度に少なくともBUF_SIZEバイト(またはバイト以上BUF_SIZE)の読み取りを常に許可するために使用します
于 2012-06-26T22:02:40.327 に答える
0

のストリームサポートをご覧くださいboost::asio

于 2012-06-26T21:29:10.973 に答える