How to Read N Bytes from a File and Put Them into a Vector<Uint8_T> Using Iterators

How do you read n bytes from a file and put them into a vectoruint8_t using iterators?

You can use ifstream::read for that.

std::vector<BYTE> v(100);
while ( file.read(reinterpret_cast<char*>(v.data()), 100) )
{
// Find out how many characters were actually read.
auto count = file.gcount();

// Use v up to count BTYEs.
}

How to read a binary file into a vector of unsigned chars

When testing for performance, I would include a test case for:

std::vector<BYTE> readFile(const char* filename)
{
// open the file:
std::ifstream file(filename, std::ios::binary);

// Stop eating new lines in binary mode!!!
file.unsetf(std::ios::skipws);

// get its size:
std::streampos fileSize;

file.seekg(0, std::ios::end);
fileSize = file.tellg();
file.seekg(0, std::ios::beg);

// reserve capacity
std::vector<BYTE> vec;
vec.reserve(fileSize);

// read the data:
vec.insert(vec.begin(),
std::istream_iterator<BYTE>(file),
std::istream_iterator<BYTE>());

return vec;
}

My thinking is that the constructor of Method 1 touches the elements in the vector, and then the read touches each element again.

Method 2 and Method 3 look most promising, but could suffer one or more resize's. Hence the reason to reserve before reading or inserting.

I would also test with std::copy:

...
std::vector<byte> vec;
vec.reserve(fileSize);

std::copy(std::istream_iterator<BYTE>(file),
std::istream_iterator<BYTE>(),
std::back_inserter(vec));

In the end, I think the best solution will avoid operator >> from istream_iterator (and all the overhead and goodness from operator >> trying to interpret binary data). But I don't know what to use that allows you to directly copy the data into the vector.

Finally, my testing with binary data is showing ios::binary is not being honored. Hence the reason for noskipws from <iomanip>.

convert vector of uint8_t to bitset

Since you don't want to write a hand-coded loop, you can use std::for_each:

#include <bitset>
#include <cstdint>
#include <vector>
#include <algorithm>

int main()
{
std::vector <uint8_t> buffer(100, 0);
std::bitset<37> b;
std::size_t i = 0;
std::for_each(buffer.begin() + 20, buffer.begin() + 57, [&](uint8_t val)
{ b[i] = val; ++i; });
}

The underlying issue is that std::bitset doesn't have iterators, so the familiar STL algorithm functions such as std::copy, std::copy_n, std::transform, etc. that require iterators are difficult, if not impossible to be used if std::bitset is a source (or target) in the algorithm function. Thus it seems that std::for_each with a lambda that increments an index will work.

How to cast, in C++, a byte vector (std::vectoruint8_t) into different uint32_t, uint16_t and uint8_t variables

You can take the address of the element in the vector to achieve what you want:

std::memcpy(&a, &bytes[0], sizeof(std::uint32_t));
// ^
//or use .data() instead
std::memcpy(&a, bytes.data() + 0, sizeof(std::uint32_t));

Read Every 2 Bytes from Data file and compare in a vector

Basically your approach is not bad. And there is no optimum solution. There are roundabout 42 million solutions :-)

There are some necessary optimizations. They are all shown in the comments under your question.

Ands the while loop can simply be done with testing the filestream variable. The "bool operator !" is overloaded for that variable type. The result will be false in case of error. Also for eof (end of file).

I would like to show you the more "C++" or "Object Oriented" approach. You start thinking what you want to do and then derive the howto from that. Obviously you want to read something like 2 bytes and compare that 2 bytes with some given value. OK, then let us define a new class TwoBytes. We add some functions, so that the 2 bytes can be read from any istream. And since we want to compare later, we add the comparison operator. All very straight forward. And only one possible solution. You can add many more functions . . .

This should later give you the idea about software design or software architecture. When you a bit more experienced, you will maybe notice that this is the fun part.

So, please see the below as just an example.

#include <iostream>
#include <vector>
#include <array>
#include <fstream>
#include <algorithm>
#include <iterator>

using Byte = char;

// An ultra simple class
struct TwoBytes {
// Hold 2 bytes
std::array<Byte,2> tb;

// Define comparison operator
bool operator == (const TwoBytes& other) { return tb == other.tb; }

// And overlaod extractor operatror >> . With tha we can easily read 2 bytes
friend std::istream& operator >> (std::ifstream& ifs, TwoBytes& b) {
// In case of odd file size, we set the 2nd value to 0
b.tb[1] = 0;
return ifs >> b.tb[0] >> b.tb[1];
}
};


int main(void)
{
const TwoBytes compareValue1 = { '1', '2' };
const TwoBytes compareValue2 = { 0x34, 0x45 };

// Open the file
std::ifstream inputFileBinary("r:\\abc.dat", std::ios::binary);

// We will read the input data to this value
TwoBytes twoBytes{};

// This is the loop to read the values
while (inputFileBinary) {

// Read 2 bytes
inputFileBinary >> twoBytes;

// In case of odd file size, inputFileBinary would be false. So you could check with "if (inputFileBinary)"

// Compare values and show result
if (twoBytes == compareValue1 || twoBytes == compareValue2) {
std::cout << "Found value\n";
}
else {
std::cout << "Did not find value\n";
}
}
return 0;
}

I hope this helps a little . . .

What is the most suitable type of vector to keep the bytes of a file?

There are 3 problems in your code:

  • You use the char type and return a char *. Yet the return value is not a proper C string as you do not allocate an extra byte for the '\0' terminator nor null terminate it.

  • If the file may contain null bytes, you should probably use type unsigned char or uint8_t to make it explicit that the array does not contain text.

  • You do not return the array size to the caller. The caller has no way to tell how long the array is. You should probably use a std::vector<uint8_t> or std::vector<unsigned char> instead of an array allocated with new.



Related Topics



Leave a reply



Submit