Now I have a file with many data in it. And I know the data I need begins at position (long)x and has a given size sizeof(y) How can I get this data?
You should use fseek() to change your "current position" in the file to the desired offset. So, if "f" is your FILE* variable and offset is the offset this is how the call should look like (modulo my leaky memory):
fseek(f, offset, SEEK_SET);
Use the seek
method:
ifstream strm;
strm.open ( ... );
strm.seekg (x);
strm.read (buffer, y);
Besides the usual seek-and-read techniques mentioned above, you can also map the file into your process space using something like mmap() and access the data directly.
For example, given the following data file "foo.dat":
one two three
The following code will print all text after the first four bytes using an mmap() based approach:
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <iostream>
int main()
{
int result = -1;
int const fd = open("foo.dat", O_RDONLY);
struct stat s;
if (fd != -1 && fstat(fd, &s) == 0)
{
void * const addr = mmap(0, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (addr != MAP_FAILED)
{
char const * const text = static_cast<char *>(addr);
// Print all text after the first 4 bytes.
std::cout << text + 4 << std::endl;
munmap(addr, s.st_size);
result = 0;
}
close(fd);
}
return result;
}
You can even use this approach to write directly to a file (remember to msync() if necessary).
Libraries like Boost and ACE provide nice C++ encapsulations for mmap() (and the equivalent Windows function).
This approach is probably overkill for small files, but it can be huge win for large files. As usual, profile your code to determine which approach is best.