2017-04-22 57 views
0

我有一個問題,主要是因爲我無法真正理解如何處理這種情況。將char *寫入basic_streambuf並將其分配給ifstream

X大小的char*緩衝,這是誰擁有解密並將被ifstream處理類,我不能編輯進行解析,然後加密文件的內容。

所以我的想法是創建一個fstream對象,其中rdbuf()sputn分配緩衝區。

fstream _handle2; _handle2.rdbuf()->sputn(_buffer, _size); _handle2.flush();

當然但是,它不工作和緩衝區不會被寫進fstream對象,你有如何使它所以任何想法?

我試過不同的方法,但我顯然不知道該怎麼做。

+1

你爲什麼不使用寫? 'handle2.write(buffer,size);' – Aconcagua

+0

我試過了,它沒有工作......如果我嘗試讀取它沒有的緩衝區。 – d3vil401

+0

你是如何打開你的fstream的? fstreams旨在將數據寫入文件或讀取數據。如果它沒有連接到一個文件,你將不會得到任何輸出。但是你究竟想要在現實中達到什麼目的?將整個文件內容讀入某種數據緩衝區? ifstream讀取文件的內容,您可以閱讀它。 G。逐字節通過'char c;流>> c;'。 – Aconcagua

回答

0

我想創建一個類似於ifstream的解析緩衝區類型。

你可以嘗試這樣的事情(從link採納我的意見提供了的話):

std::ifstream ifs("test.txt", std::ifstream::binary); 
if (ifs) 
{ 
    ifs.seekg (0, ifs.end); 
    int length = ifs.tellg(); 
    ifs.seekg (0, ifs.beg); 

    std::string buffer; 
    buffer.resize(length); 
    ifs.read(const_cast<char*>(buffer.data()), length); 
    if (ifs) 
    { 
     // de-crypt the buffer here! 
     // something like: 
     // buffer[i] = decryptChar(buffer[i]); 

     std::istringstream iss(buffer); 

     // now you can use iss just the same way as ifs, 
     // if the file was not encrypted... 

    } 
    else 
    { 
     std::cout << "error: only " << ifs.gcount() << " bytes could be read"; 
    } 
    ifs.close(); 
} 

編輯迴應您的評論:

std::istringstream用於將文本轉換成二進制數據,例如, G。 int n; iss >> n;會將ascii序列0x32,0x30,0x31,0x30,0x32,0x30,0x31,0x32表示的字符串「20102012」轉換爲相應的四字節整數值0x0132bb7c。但是如果數據已經是二進制的,則std::istringstream不適用。這時,你可能寧願嘗試寫類似這樣的例子你自己的流類:

class DecryptionStream 
{ 
    std::unique_ptr<char> mBuffer; 
    char* mEnd; 
    char* mPos; 
    unsigned int flags; 

    unsigned int const eofbit = 1 << 0; 
    unsigned int const failbit = 1 << 1; 
    // other flag bits as needed 

public: 
    // fail/eof bits as needed 
    DecryptionStream(char const* fileName) : mPos(nullptr) 
    { 
     std::ifstream ifs(fileName, std::ifstream::binary); 
     if (ifs) 
     { 
      ifs.seekg (0, ifs.end); 
      int length = ifs.tellg(); 
      ifs.seekg (0, ifs.beg); 

      mBuffer.reset(new char[length]); 
      ifs.read(mBuffer.get(), length); 
      if (ifs) 
      { 
       // de-crypt the buffer here! 
       // something like: 
       // buffer[i] = decryptChar(buffer[i]); 
       mPos = mBuffer.get(); 
       mEnd = mBuffer.get() + length; 
      } 
      else 
      { 
       flags |= failbit; 
      } 
      ifs.close(); 
     } 
    } 

    template<typename T> 
    DecryptionStream& operator >>(T& t) 
    { 
     // fail, if any fail bit set already 
     size_t avail = mPos - mEnd; 
     if (avail < sizeof(t)) 
     { 
      flags |= eofbit | failbit; 
     } 
     else 
     { 
      if(avail == sizeof(t)) 
      { 
       flags |= eofbit; 
      } 
      memcpy(&t, mPos, sizeof(t)); 
      mPos += sizeof(t); 
     } 
     return *this; 
    } 

    operator bool() 
    { 
     return flags == 0; 
    } 
}; 

你甚至可以使用這個類具有複雜數據類型 - 然後確保,雖然,你適當地控制這些字節對齊,否則你可能會失敗!

+0

與我所要求的不完全一樣,但通過編寫一部分代碼,我已經能夠完成我所做的一切;謝謝。 – d3vil401

+0

現在,事情是我不handlng字符串,但原始的二進制緩衝區,我添加了ios ::二進制標誌,但恐怕它不正確讀取部分緩衝區。 – d3vil401

+0

二進制內容? 'std :: istringstream'則不適用。適當地延長我的指尖。 – Aconcagua

0

看一看boost::iostreams::array_source

它允許您將數組視爲std::istream。與std::istringstream相比,該優勢在於數組不會被複制到流中,從而減少內存使用並提高性能。 array_source將只存儲一個指向現有緩衝區的指針。

#include <iostream> 
#include <string> 
#include <boost/iostreams/device/array.hpp> 
#include <boost/iostreams/stream.hpp> 
namespace io = boost::iostreams; 

int main() 
{ 
    // Create an array and wrap a stream interface around it. 
    const char buffer[] = "hello stackoverflow"; 
    io::stream<io::array_source> strm(buffer, sizeof(buffer) - 1); //-1 to strip '\0' 

    // Use the stream like a standard istream. 
    std::string s; 
    while(strm >> s) 
     std::cout << s << "\n"; 
} 

Live Demo on Coliru.

相關問題