简体   繁体   English

C ++将文件的所有字节放入char数组中?

[英]C++ Get all bytes of a file in to a char array?

Given:鉴于:

const string inputFile = "C:\MyFile.csv";
char buffer[10000];

How do I read the chars of the file in to the above buffer?如何将文件的字符读入上述缓冲区? I have been looking around online but none of the answers seem to work.我一直在网上四处寻找,但似乎没有一个答案有效。 They all wish to call getline().他们都希望调用 getline()。

Note: Start with Remy Lebeau's answer .注意:Remy Lebeau 的回答开始。 For general file reading, this answer covers the hard way to do the job;对于一般文件阅读,这个答案涵盖了完成这项工作的艰难方法; it better matched the specific needs of this specific asker, but won't necessarily meet your needs as well as the std::vector and std::istreambuf_iterator approach Remy outlines.它更好地满足了这个特定询问者的特定需求,但不一定能满足您的需求以及 Remy 概述的std::vectorstd::istreambuf_iterator方法。


Most of the time they are right about getline , but when you want to grab the file as a stream of bytes, you want ifstream::read() .大多数情况下,他们对getline是正确的,但是当您想将文件作为字节流抓取时,您需要ifstream::read()

//open file
std::ifstream infile("C:\\MyFile.csv");

//get length of file
infile.seekg(0, std::ios::end);
size_t length = infile.tellg();
infile.seekg(0, std::ios::beg);

// don't overflow the buffer!
if (length > sizeof (buffer))
{
    length = sizeof (buffer);
}

//read file
infile.read(buffer, length);

Docs for ifstream::seekg() ifstream::seekg()的文档

Docs for ifstream::tellg() ifstream::tellg()的文档

NOTE: seekg() and tellg() to get the size of the file falls into the category of "usually works".注意: seekg()tellg()获取文件大小属于“通常有效”的类别。 This is not guaranteed.这不能保证。 tellg() only promises a number that can be used to return to a particular point. tellg()只承诺一个可用于返回特定点的数字。 That said...那就是说...

Note: The file was not opened in binary mode.注意:该文件不是以二进制模式打开的。 There can be some behind-the-scenes character translations, for example the Windows newline of \r\n being converted to the \n used by C++.可能会有一些幕后字符翻译,例如 Windows 换行符\r\n被转换为 C++ 使用的\n length can be greater than the number of characters ultimately placed in buffer . length可以大于最终放入buffer的字符数。

2019 rethink 2019年重新思考

size_t chars_read;
//read file
if (!(infile.read(buffer, sizeof(buffer)))) // read up to the size of the buffer
{
    if (!infile.eof()) // end of file is an expected condition here and not worth 
                       // clearing. What else are you going to read?
    {
        // something went wrong while reading. Find out what and handle.
    }
}
chars_read = infile.gcount(); // get amount of characters really read.

If you're looping on buffered reads until you consume the whole file, you'll want some extra smarts to catch that.如果您在使用整个文件之前循环缓冲读取,那么您将需要一些额外的智能来捕捉它。

If you want to read the whole file in one shot, and can afford to use resizable buffers, take the advice in Remy Lebeau's answer .如果您想一次性读取整个文件,并且可以负担得起使用可调整大小的缓冲区,请参考Remy Lebeau 的回答中的建议。

Another option would be to use a std::vector for the buffer, then use a std::istreambuf_iterator to read from an std::ifstream directly into the std::vector , eg:另一种选择是使用std::vector作为缓冲区,然后使用std::istreambuf_iteratorstd::ifstream直接读取到std::vector ,例如:

const std::string inputFile = "C:\\MyFile.csv";
std::ifstream infile(inputFile, std::ios_base::binary);

std::vector<char> buffer( std::istreambuf_iterator<char>(infile),
                          std::istreambuf_iterator<char>() );

Alternatively:或者:

const std::string inputFile = "C:\\MyFile.csv";
std::ifstream inFile(inputFile, std::ios_base::binary);

inFile.seekg(0, std::ios_base::end);
size_t length = inFile.tellg();
inFile.seekg(0, std::ios_base::beg);

std::vector<char> buffer;
buffer.reserve(length);
std::copy( std::istreambuf_iterator<char>(inFile),
           std::istreambuf_iterator<char>(),
           std::back_inserter(buffer) );

If you go with @user4581301's solution, I would still suggest using std::vector for the buffer, at least:如果您使用@user4581301 的解决方案,我仍然建议使用std::vector作为缓冲区,至少:

//open file
std::ifstream infile("C:\\MyFile.csv");
std::vector<char> buffer;

//get length of file
infile.seekg(0, infile.end);
size_t length = infile.tellg();
infile.seekg(0, infile.beg);

//read file
if (length > 0) {
    buffer.resize(length);    
    infile.read(&buffer[0], length);
}

If you're concerned with efficiency (you rejected getline() ) then a C-style mmap is probably best:如果您关心效率(您拒绝了getline() ),那么 C 风格的mmap可能是最好的:

#include <sys/stat.h>
#include <sys/mman.h>

struct stat s;
stat(inputFile.c_str(), &s);
size_t file_size = st.st_size;

int fhand = open(inputFile);
char* file_buf = (char*)mmap(0, file_size, PROT_READ, MAP_FILE|MAP_PRIVATE, fhand, 0);
...
munmap(file_buf, file_size);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM