在C++; 来自C,我正在C++中做实验,遇到了一个简单的问题:用一个文件读取二进制数据到一个缓冲区,使用 IFSturi。在我看来,从文件中读取数据有三种选择: get(),它只获取一个字符,在将大量数据读入内存缓冲区时,这个字符看起来很奇怪,效率很低 read(),它不返回实际读取的字符数;及 readsome(),如果我理解正确,它只返回以前缓冲过的数据,但不从实际文件中读取任何新数据

在C++; 来自C,我正在C++中做实验,遇到了一个简单的问题:用一个文件读取二进制数据到一个缓冲区,使用 IFSturi。在我看来,从文件中读取数据有三种选择: get(),它只获取一个字符,在将大量数据读入内存缓冲区时,这个字符看起来很奇怪,效率很低 read(),它不返回实际读取的字符数;及 readsome(),如果我理解正确,它只返回以前缓冲过的数据,但不从实际文件中读取任何新数据,c++,iostream,C++,Iostream,让我感到特别奇怪的是read()函数,在我看来,它完全无法使用,因为它无法告诉我它实际将多少字节放入提供的缓冲区。然而,我看到的所有使用it的示例代码似乎都验证了这一点,并且通常会在文件末尾获取文件大小,然后分配缓冲区。显然,这不适用于流式数据 P>那么,在C++中,如何使用非文本数据流文件/管道/套接字?是否有比ifstream更好的设施 “让我感到特别奇怪的是read()函数,在我看来,它完全无法使用,因为它无法告诉我它实际放入提供的缓冲区中的字节数。” 好的,您可以指定一次读取的最大字节数

让我感到特别奇怪的是
read()
函数,在我看来,它完全无法使用,因为它无法告诉我它实际将多少字节放入提供的缓冲区。然而,我看到的所有使用it的示例代码似乎都验证了这一点,并且通常会在文件末尾获取文件大小,然后分配缓冲区。显然,这不适用于流式数据

P>那么,在C++中,如何使用非文本数据流文件/管道/套接字?是否有比ifstream更好的设施

“让我感到特别奇怪的是
read()
函数,在我看来,它完全无法使用,因为它无法告诉我它实际放入提供的缓冲区中的字节数。”

好的,您可以指定一次读取的最大字节数,并且可以使用
std::ifstream::eof()
检查流是否已经耗尽

如果您想知道文件中已经有多少字节可用,并相应地分配读取缓冲区,您可以事先检查整个文件大小,如前所述,只需稍微修改以下示例代码:

//将整个文件读入字符串
std::ifstream是(“test.txt”,std::ifstream::binary);
如果(是){
//获取文件的长度:
is.seekg(0,is.end);
int length=is.tellg();
is.seekg(0,is.beg);
std::字符串str;
str.resize(长度“”);//*******保留空间********
char*begin=&*str.begin();
is.read(开始,长度);
is.close();
标准::cout
让我感到特别奇怪的是read()函数,在我看来,它完全无法使用,因为它无法告诉我它实际将多少字节放入提供的缓冲区

read()

退出
read()
后,如果读取成功,您可以调用
gcount()
以了解缓冲区中读取了多少字符。如果读取期间达到EOF,则流的
eofbit
状态将设置为true,并且
gcount()
返回的字符数将少于您请求的字符数

如果读取失败,则流的
failbit
和/或
badbit
状态设置为true

std::ifstream ifs(...);
if (is) {
    // stream opened...
    //...
    ifs.read(buffer, sizeof(buffer));
    if (ifs) {
        // read succeeded, EOF may have been reached...
        std::streamsize numInBuf = ifs.gcount();
        //...
    } else {
        // read failed...
    }
    //...
} else {
    // stream not opened...
}
如果使用流的
exceptions()
方法通过异常启用错误报告,则如果故障与启用异常的错误位匹配,则可能会引发
std::ios_base::failure
异常

std::ifstream ifs;
ifs.exceptions(std::ifstream::badbit | std::ifstream::failbit);
try {
    ifs.open(...);
    // stream opened...
    //...
    ifs.read(buffer, sizeof(buffer));
    // read succeeded, EOF may have been reached...
    std::streamsize numInBuf = ifs.gcount();
    //...
} catch (const std::ios_base::failure &e) {
    // stream failure...
}

那么,在C++中,如何使用非文本数据流文件/管道/套接字?是否有比IFFILE更好的功能,也许?


std::ifstream
是为基于文件的流而设计的。对于管道,如果您的平台可以通过标准文件API访问管道,
std::ifstream
应该可以工作。但是对于套接字,您需要使用更合适的
std::basic_istream
派生类,或者至少使用标准的
std::istream
自定义
std::streambuf
附加到它的派生类()。

is.seekg(0,is.end);
--但这在管道或套接字上不起作用。@Dolda2000好吧,你应该在你的问题中澄清这个问题。不过,我更喜欢使用和一个循环来读取任何输入流。好吧,这就是我谈论“流”的原因。我想这已经足够清楚了。特别是因为我明确反对这个问题中的特定案例。:)啊,
gcount()
似乎是我真正缺少的。谢谢!
std::ifstream ifs;
ifs.exceptions(std::ifstream::badbit | std::ifstream::failbit);
try {
    ifs.open(...);
    // stream opened...
    //...
    ifs.read(buffer, sizeof(buffer));
    // read succeeded, EOF may have been reached...
    std::streamsize numInBuf = ifs.gcount();
    //...
} catch (const std::ios_base::failure &e) {
    // stream failure...
}