1

I have a piece of code for reading smaps into a buffer like this (for simplicity, I have removed error-control code and I have also assumed for this example that the buffer is big enough to fit the file entirely):

char* buff = (char*)malloc(2 * 1024 * 1024); // 2MB of buffer
int fd = open("/proc/self/smaps", O_RDONLY);

char* buff_it = buff;
char* buff_end = buff_it + buff_sz - 1;
ssize_t read_sz;

while ((read_sz = read(fd, buff_it, buff_end - buff_it)) > 0)
   buff_it += read_sz;

close(fd);
// Parse buff
free(buff);

However, if I want to move to using ifstream in C++, the code would look like this:

auto buff = std::make_unique<char[]>(2 * 1024 * 1024);
    
std::ifstream ifs("/proc/self/smaps", std::ios::binary);
ifs.read(buff.get(), 2 * 1024 * 1024); 
buff[ifs.gcount()] = '\0';

but my question is, do read internally use another private buffer to store intermediate input that is then copied to my supplied buffer? In other words, is that snippet of code using double buffering? Because that feels like a waste to be honest.

The kind of functionality I want is to say to ifstream: hey, take this 2 MB buffer as your internal buffer, and fill it as much as you can, and then close the file (that I will parse the buffer later).

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
ABu
  • 10,423
  • 6
  • 52
  • 103
  • Does this answer your question? [Setting the internal buffer used by a standard stream (pubsetbuf)](https://stackoverflow.com/questions/1494182/setting-the-internal-buffer-used-by-a-standard-stream-pubsetbuf) – Yksisarvinen Aug 23 '23 at 11:39
  • @Yksisarvinen I don't think so. If I set an internal buffer to ifstream, I still need to say: "hey, fill the buffer", which, for example with `read`, requires I supply a second buffer as argument to "copy-paste" whatever is in the internal buffer. – ABu Aug 23 '23 at 11:42
  • @ABu Why would you require a second buffer? I would assume that an istream does not purge a user-supplied buffer in its destructor, so you can supply your allocated memory to the istream and continue to use it (although, reading Yksi's link, that may not always work). – Peter - Reinstate Monica Aug 23 '23 at 11:44
  • @Peter-ReinstateMonica yes, but once I have set an internal buffer of my choosing, how do I tell the stream: fill now such internal buffer as much as you can up to 2MB. I have no way to force `ifstream` to just read from the underlying device. Every operation that could force `ifstream` to read from the underlying device requires me to pass a buffer as argument where to copy the read-data. – ABu Aug 23 '23 at 11:48
  • 1
    Do you want to read whole 2MB into the buffer on any read operation? I don't think any buffer in standard library will guarantee that. You'd have to write your own class (derived from `std::filebuf` I guess) – Yksisarvinen Aug 23 '23 at 12:01
  • @Yksisarvinen `ifstream::read` iterate until one of two conditions happen: buffer is fill or EOF has been found, which is exactly what I want, but without double buffering (without having me to pass a second buffer to where to copy characters). In other words, `ifstream::read` is not a single operation, it encapsulares a set of lower level reads. – ABu Aug 23 '23 at 12:04
  • Just put the `ifstream` and the read operation inside a block and `buff` outside the block. Then you do not have to care about the double-buffering, because when the read is over, the `ifstream` is disposed of and `buff` is the only buffer that remains. – j6t Aug 23 '23 at 12:27

0 Answers0