C++ 获取一个文件的所有字节到一个字符数组中?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36658734/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ Get all bytes of a file in to a char array?
提问by mezamorphic
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()。
回答by user4581301
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);
NOTE: seekg
and tellg
to get the size of the file falls into the category of "usually works". This is not guaranteed. tellg
only promises a number that can be used to return to a particular point. That said,
注意:seekg
并tellg
获取文件的大小属于“通常有效”的类别。这不能保证。tellg
只承诺一个可用于返回特定点的数字。那说,
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++. length
can be greater than the number of characters ultimately placed in buffer
.
注意:该文件不是以二进制模式打开的。可能有一些幕后字符转换,例如\r\n
转换为\n
C++ 使用的 Windows 换行符。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 的回答中的建议。
回答by 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:
另一种选择是使用 astd::vector
作为缓冲区,然后使用 astd::istreambuf_iterator
从 anstd::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);
}
回答by Charles Pehlivanian
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);