将char*写入basic_streambuf并将其分配给ifstream

Writing char* into a basic_streambuf and assign it to a ifstream

本文关键字:分配 ifstream char 写入 basic streambuf      更新时间:2023-10-16

我有问题,主要是因为我真的不明白如何处理这种情况。

我有一个char* X size的CC_1缓冲区,它是加密文件的内容,然后将其解密,然后由ifstream处理程序类解析,我不能编辑

所以我的想法是创建一个fstream对象,其中使用rdbuf()将缓冲区分配给sputn

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

但是,当然,它无法正常工作,缓冲区没有被写入fstream对象,您对如何做到这一点有任何想法吗?

我尝试了不同的方法,但我显然无法弄清楚该怎么做。

我正在尝试创建一个可以与ifstream类似的缓冲区类型。

您可能会尝试这样的事情(从评论中提供的链接采用(:

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用于将文本转换为二进制数据,e。G。但是,如果数据已经二进制,则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;
    }
};

您甚至可以将此类用于复杂的数据类型 - 但是,请确保正确控制这些类型的字节对齐,否则您可能会严重失败!

请看一下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 ''
    // Use the stream like a standard istream.
    std::string s;
    while( strm >> s )
        std::cout << s << "n";
}

coliru上的现场演示。