使用相同的fstream读取和写入同一个文件 [英] Reading and writing to the same file using the same fstream

查看:209
本文介绍了使用相同的fstream读取和写入同一个文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个已经包含一些数据的文件(比如8 kB)。我想从文件的开头读取一些东西,然后从我完成阅读的地方开始覆盖数据。所以我尝试使用下面的代码:

I have a file that already contains some data (say, 8 kB). I want to read something from the beginning of the file, and then overwrite data starting where I finished reading. So I try to use the following code:

std::fstream stream("filename", std::ios::in | std::ios::out | std::ios::binary);

char byte;
stream.read(&byte, 1);

// stream.seekp(1);

int bytesCount = 4096;

auto bytesVec = std::vector<char>(bytesCount, 'c');
char* bytes = bytesVec.data();

std::cout << stream.bad() << std::endl;

stream.write(bytes, bytesCount);

std::cout << stream.bad() << std::endl;

如果我执行这个代码,第一个 bad()返回 false ,但第二个返回 true ,实际上没有写入。

If I execute this code, the first bad() returns false, but the second one returns true and nothing actually gets written.

如果我将 bytesCount 减小到小于4096(可能是一些内部缓冲区的大小),第二个坏()返回 false ,但仍然没有写入。

If I decrease bytesCount to anything smaller than 4096 (presumably the size of some internal buffer), the second bad() returns false, but still nothing gets written.

如果我取消注释 seekp()行,写入开始工作: bad()返回 false

If I uncomment the seekp() line, the writing starts working: bad() returns false and the bytes actually get written.

为什么 seekp()必须在这里?为什么没有它没有它工作? seekp()正确的方法吗?

Why is the seekp() necessary here? Why doesn't it work without it? Is the seekp() the right way to do this?

我在Windows 7上使用Visual Studio 2012 。

I'm using Visual Studio 2012 on Windows 7.

推荐答案

您正在下载犯罪,对读取和
写操作混合的限制对打开的文件更新模式,MS的 fstream
库继承自其C < stdio.h> 实现。

You are falling foul of a restriction upon the intermixing of read and write operations on a file opened in update mode that MS's fstream library inherits from from the its C <stdio.h> implementation.

C标准(我引用C99,但在这一点上与C89没有区别)
at 7.19.5.3/6状态:

The C Standard (I cite C99, but it doesn't differ in this point from C89) at 7.19.5.3/6 states:


当使用更新模式打开文件('+'作为模式参数值列表中的
中的第二个或第三个字符) ,可以在
相关联流上执行输入和输出。然而,输出不应该直接跟随输入,而没有$ f $ f中间调用fflush函数或文件定位函数(fseek,
fsetpos或rewind),并且输入不应该是直接的,除非输入操作遇到end-
of-file。

When a file is opened with update mode ('+' as the second or third character in the above list of mode argument values), both input and output may be performed on the associated stream. However, output shall not be directly followed by input without an intervening call to the fflush function or to a file positioning function (fseek, fsetpos, or rewind), and input shall not be directly followed by output without an intervening call to a file positioning function, unless the input operation encounters end- of-file.

(我的重点)。

所以你的 stream.seekp(1)解决方案,它转移到一个C fseek ,是正确的。

So your stream.seekp(1) solution, which devolves to a C fseek, is correct.

GNU C库没有这个标准限制,因此您的代码如同使用GCC构建时所预期的那样工作

The GNU C library does not have this Standard limitation, so your code as posted works as expected when built with GCC.

MS < fstream> 库符合C ++标准在继承
这个限制。 fstream 使用 basic_filebuf< charT,traits> 实现。在(C ++ 11)标准的这个模板的帐户中,在§27.9.1.1/2,它只是说:

The MS <fstream> library is compliant with the C++ Standard in inheriting this restriction. fstreams are implemented using basic_filebuf<charT,traits>. In the (C++11) Standard's account of this template, at § 27.9.1.1/2, it simply says:


读取和写入由basic_filebuf类的对象控制的序列与使用标准C库FILE读取和写入的序列相同。

The restrictions on reading and writing a sequence controlled by an object of class basic_filebuf are the same as for reading and writing with the Standard C library FILEs.

这篇关于使用相同的fstream读取和写入同一个文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆