이 단순하고, 내 손가락의 맨 위에 떨어져 있지만, 나는이 라인을 따라 뭔가가 해결 것이라고 생각 : 코멘트에
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);
}
};
, 당신은 당신이 큰 문자 버퍼를 만들지 않도록하고 싶었다 언급했다. read
시스템 호출을 사용할 때 일반적으로 많은 작은 읽기 대신 몇 개의 큰 읽기를 수행하는 것이 더 효율적입니다. 따라서 대부분의 구현은 효율성을 높이기 위해 대형 입력 버퍼를 선택합니다.
std::vector<char> input;
char in;
int r;
while ((r = read(fd, &in, 1)) == 1) input.push_back(in);
그러나 시스템 호출과 입력의 모든 바이트에 대해 적어도 하나의 바이트가 복사됩니다. 대조적으로, 내가 추가 한 코드는 여분의 데이터 복사본을 피한다.
나는 당신이 채택 할 해결책이 될 코드를 정말로 기대하지 않습니다. 방금 공간과 시간면에서 효율적이었던 자체 확장 객체를 만드는 방법을 보여주는 그림을 제공하려고했습니다. 귀하의 목적에 따라, 그것을 확장하거나 자신의 글을 쓸 수도 있습니다. 내 머리 위로 떨어져, 일부 개선 될 수있다 :
- 사용
std::list
대신,
- 이 API를 항상 적어도 수 있도록
- 사용
readv
을 읽는 방법 바이트 지정하는 매개 변수를 허용 크기를 조정 벡터를 피하기 위해 BUF_SIZE
바이트 (또는 BUF_SIZE
바이트 이상)를 한 번에 읽을 수 있습니다.
출처
2012-06-26 22:02:40
jxh
예. 꽤 많은 사람들이 소켓에 연결하는 스트림 버퍼를 작성했습니다. 처음에는 시원하게 보였지만 적어도 실제로는 잘 작동하지 않았습니다. 제대로 작동하려면 일종의 비동기 작업 (예 : ASIO처럼)을 추가해야합니다. http://socketstream.sourceforge.net/, http://www.pcs.cnu.edu/~dgame/sockets/socketsC++//sockets.html 등 –