簡體   English   中英

來自file_descriptor_source(boost :: iostreams)或文件的istream

[英]istream from file_descriptor_source (boost::iostreams) or file

我需要為我的程序輸入執行類似的操作:

stream input;
if (decompressed)
    input.open(filepath);
else {
    file_descriptor=_popen("decompressor "+filepath,"r");
    input.open(file_descriptor);
}
input.read(...)
...

我可以看到一個解決方案 - 在兩種情況下都使用_popen,如果它已經解壓縮,只需將文件復制到stdout,但這似乎不是很優雅。

有趣的是,與C相比有多難 - 我想標准庫錯過了它。 現在我迷失在神秘的boost :: iostreams文檔中。 如果有人知道如何,示例代碼會很棒。

這就是你所追求的:

#include <cstdio>
#include <string>
#include <iostream>
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>

namespace io = boost::iostreams;

int main()
{
    bool flag = false;

    FILE* handle = 0; 
    if (flag)
    {
        handle = _popen("dir", "r");
    }
    else
    {
        handle = fopen ("main.cpp", "r");
    }

    io::stream_buffer<io::file_descriptor_source> fpstream (fileno(handle));
    std::istream in (&fpstream);

    std::string line;
    while (in)
    {
        std::getline (in, line);
        std::cout << line << std::endl;
    }

    return 0;
}

添加到jon-hanson的答案,這是一個演示如何將file_descriptor_source與管道一起使用的簡單示例。

如何建立:

g++ -m32 -DBOOST_IOSTREAMS_NO_LIB -isystem ${BOOST_PATH}/include \
  ${BOOST_SRC_PATH}/libs/iostreams/src/file_descriptor.cpp blah.cc -o blah

代碼:

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

#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>

int main( int argc, char* argv[] ) {
  // if you just do 'using namespace...', there's a
  // namespace collision with the global 'write'
  // function used in the child
  namespace io = boost::iostreams;

  int pipefd[] = {0,0};
  pipe( pipefd, 0 );  // If you use O_NONBLOCK, you'll have to
                      // add some extra checks to the loop so
                      // it will wait until the child is finished.

  if( 0 == fork() ) {
    // child
    close( pipefd[0] ); // read handle
    dup2( pipefd[1], FILENO_STDOUT );
    printf( "This\nis\na\ntest\nto\nmake sure that\nit\nis\working as expected.\n" );
    return 0; // ya ya, shoot me ;p
  }

  // parent

  close( pipefd[1] ); // write handle

  char *buff = new char[1024];
  memset( buff, 0, 1024 );

  io::stream<io::file_descriptor_source> fds(
    io::file_descriptor_source( pipefd[0], io::never_close_handle ) );

  // this should work with std::getline as well
  while(   fds.getline( buff, 1024 )
        && fds.gcount() > 0 // this condition is not enough if you use
                            // O_NONBLOCK; it should only bail if this
                            // is false AND the child has exited
       ) {
    printf( "%s,", buff );
  }

  printf( "\n" );
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM