472,950 Members | 2,395 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,950 software developers and data experts.

file length...

Hi,
I'm trying to read a binary file into a buffer:

std::ifstream ifs(fileName,
std::ios::in|std::ios::binary);
if (!ifs)
return;
ifs.seekg(0,std::ios::end);
int len = ifs.tellg();
ifs.seekg(0,std::ios::beg);
char* buf = new char[len];
memcpy(buf,ifs.rdbuf(),len);

However, this is not working as expected since
buf contains not what the original file contains...

I do not want to read character-by-character from
file and the above does not work. So what is the
correct way of doing this "simple" stuff?

Thanks,
Steve
Jul 23 '05 #1
10 3113
Steve wrote:
Hi,
I'm trying to read a binary file into a buffer:
See:

http://www.cplusplus.com/ref/iostream/istream/read.html

std::ifstream ifs(fileName,
std::ios::in|std::ios::binary);
if (!ifs)
return;
ifs.seekg(0,std::ios::end);
int len = ifs.tellg();
ifs.seekg(0,std::ios::beg);
char* buf = new char[len];
memcpy(buf,ifs.rdbuf(),len);

However, this is not working as expected since
buf contains not what the original file contains...

I do not want to read character-by-character from
file and the above does not work. So what is the
correct way of doing this "simple" stuff?

Thanks,
Steve

Jul 23 '05 #2
Steve wrote:
Hi,
I'm trying to read a binary file into a buffer:

std::ifstream ifs(fileName,
std::ios::in|std::ios::binary);
if (!ifs)
return;
ifs.seekg(0,std::ios::end);
int len = ifs.tellg();
ifs.seekg(0,std::ios::beg);
char* buf = new char[len];
memcpy(buf,ifs.rdbuf(),len);


ifs.rdbuf() returns a pointer to an instance of class basic_filebuf. Copying
the bytes that this objects is made of into an array of char doesn't make
any sense. But you can use its member function sgetn to get data.

Jul 23 '05 #3
Steve wrote:
ifs.seekg(0,std::ios::end);
int len = ifs.tellg();
ifs.seekg(0,std::ios::beg);
char* buf = new char[len];
This is a pretty dangerous approach: there is actually no
portable approach to determine the number of characters in a
file except counting them, e.g. like this:

/**/ std::streamsize len = std::distance(
/**/ std::istreambuf_iterator<char>(ifs),
/**/ std::istreambuf_iterator<char>());
memcpy(buf,ifs.rdbuf(),len);


This does not read the files, it copies the contents of
some struct. Don't do it! Probably the most efficient and
portable approach to reading a file in C++ is something like
this:

/**/ std::istringstream out;
/**/ out << ifs.rdbuf();
/**/ std::string buf = out.str();

My personally preferred notation would be this:

/**/ std::vector<char> buf;
/**/ std::copy(std::istreambuf_iterator<char>(ifs),
/**/ std::istreambuf_iterator<char>(),
/**/ std::back_inserter(buf));

.... but this is typically considerably slower than the other
approach although it could actually be made faster. :-(
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

Jul 23 '05 #4

"Dietmar Kuehl" <di***********@yahoo.com> wrote in message news:11*********************@z14g2000cwz.googlegro ups.com...
Steve wrote:
ifs.seekg(0,std::ios::end);
int len = ifs.tellg();
ifs.seekg(0,std::ios::beg);
char* buf = new char[len];


This is a pretty dangerous approach: there is actually no
portable approach to determine the number of characters in a
file except counting them, e.g. like this:

/**/ std::streamsize len = std::distance(
/**/ std::istreambuf_iterator<char>(ifs),
/**/ std::istreambuf_iterator<char>());

[snip]
Should a code below work too?
-----------------------
ofstream ofs;
std::streamsize len = std::distance(std::ostreambuf_iterator<char>(ofs), std::ostreambuf_oterator<char>());
-----------------------
--
Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn

Jul 23 '05 #5

"Alex Vinokur" <al****@big-foot.com> wrote in message news:36*************@individual.net...

"Dietmar Kuehl" <di***********@yahoo.com> wrote in message news:11*********************@z14g2000cwz.googlegro ups.com...
Steve wrote:
ifs.seekg(0,std::ios::end);
int len = ifs.tellg();
ifs.seekg(0,std::ios::beg);
char* buf = new char[len];


This is a pretty dangerous approach: there is actually no
portable approach to determine the number of characters in a
file except counting them, e.g. like this:

/**/ std::streamsize len = std::distance(
/**/ std::istreambuf_iterator<char>(ifs),
/**/ std::istreambuf_iterator<char>());

[snip]
Should a code below work too?
-----------------------
ofstream ofs;
std::streamsize len = std::distance(std::ostreambuf_iterator<char>(ofs), std::ostreambuf_oterator<char>());
-----------------------

[snip]

Class 'ostreambuf_iterator' doesn't have constructor ostreambuf_iterator().
So, the code above doesn't work.

Must we use 'seekp' and 'tellp' to get length of 'ofs'?
--
Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn

Jul 23 '05 #6
Alex Vinokur wrote:
Should a code below work too?
-----------------------
ofstream ofs;
std::streamsize len = std::distance(std::ostreambuf_iterator<char>(ofs),
std::ostreambuf_oterator<char>()); -----------------------

No. Output iterators don't cannot be compared to each other.
Class 'ostreambuf_iterator' doesn't have constructor
ostreambuf_iterator(). So, the code above doesn't work.
This is another issue. However:
Must we use 'seekp' and 'tellp' to get length of 'ofs'?


No. It is '0' because you haven't opened any file. Of course, if
you had opened a file for output but not for reading or appending,
it would still be '0' as it would be truncated. If you want to
know the size (e.g. the number of characters), open the file for
reading and use 'distance()'. You cannot determine the number of
character in a file using the result of seeks, e.g. because the
difference type may be too small to represent the result. Also,
depending on how you opened the file, you should use the results
as opaque handles to a position anyway because the difference
would not necessarily match the number of characters between them.

Actually, there is rarely any need to determine the file size in
the first place! If you need this information, you are probably
doing things with files which are non-portable anyway and thus
better addressed using a different, non-standard interface to
files, for example 'mmap()'.
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting
Jul 23 '05 #7

"Dietmar Kuehl" <di***********@yahoo.com> wrote in message news:11*********************@z14g2000cwz.googlegro ups.com...
Steve wrote:
ifs.seekg(0,std::ios::end);
int len = ifs.tellg();
ifs.seekg(0,std::ios::beg);
char* buf = new char[len];


This is a pretty dangerous approach: there is actually no
portable approach to determine the number of characters in a
file except counting them, e.g. like this:

/**/ std::streamsize len = std::distance(
/**/ std::istreambuf_iterator<char>(ifs),
/**/ std::istreambuf_iterator<char>());

[snip]
Those methods has different behavior (see program below).
There are another methods with once more behavior?

Compiler g++ 3.4.1
// ====== foo.cpp : BEGIN ======
#include <cassert>
#include <string>
#include <iostream>
#include <fstream>
using namespace std;

// ------------------
#define TXT_FILE_NAME "foo.txt"
#define BIN_FILE_NAME "foo.bin"

enum OpenMode { BIN_MODE, TXT_MODE };

// -----------------
size_t get_filesize_via_fseek_ftell (
const char * const filename_i,
OpenMode mode_i
)
{
FILE* fp = NULL;

assert ((mode_i == TXT_MODE) || (mode_i == BIN_MODE));
fp = fopen(filename_i, ((mode_i == TXT_MODE) ? "r" : "rb"));
assert (fp);

int rc = fseek(fp, 0, SEEK_END);
assert (rc == 0);

const size_t ret_filesize (ftell(fp));

rc = fclose(fp);
assert (rc == 0);

return ret_filesize;
}
// -----------------
size_t get_filesize_via_seekg_tellg (
const char * const filename_i,
OpenMode mode_i
)
{
ifstream fs;

assert ((mode_i == TXT_MODE) || (mode_i == BIN_MODE));

if (mode_i == TXT_MODE) fs.open (filename_i);
else fs.open (filename_i, ios::binary);

assert (fs);
assert (fs.is_open());
fs.seekg(0, ios::beg);
const ios::pos_type start_pos = fs.tellg();

fs.seekg(0, ios::end);
const ios::pos_type end_pos = fs.tellg();

const size_t ret_filesize (static_cast<size_t>(end_pos - start_pos));

fs.close();
assert (!fs.is_open());

return ret_filesize;
}
// -----------------
size_t get_filesize_via_distance (
const char * const filename_i,
OpenMode mode_i
)
{
ifstream fs;

assert ((mode_i == TXT_MODE) || (mode_i == BIN_MODE));

if (mode_i == TXT_MODE) fs.open (filename_i);
else fs.open (filename_i, ios::binary);

assert (fs);
assert (fs.is_open());

const size_t ret_filesize (static_cast<size_t>(distance(
istreambuf_iterator<char>(fs),
istreambuf_iterator<char>()
)
)
);

fs.close();
assert (!fs.is_open());

return ret_filesize;
}
// -----------------
void create_file (
const string& data_i,
const char * const filename_i,
OpenMode mode_i
)
{
remove (filename_i);

ofstream fs;

assert ((mode_i == TXT_MODE) || (mode_i == BIN_MODE));

if (mode_i == TXT_MODE) fs.open (filename_i);
else fs.open (filename_i, ios::binary);

assert (fs);
assert (fs.is_open());

fs << data_i;

fs.close();
assert (!fs.is_open());

}
int main ()
{
const char data[] = "\n";
create_file (data, TXT_FILE_NAME, TXT_MODE);
create_file (data, BIN_FILE_NAME, BIN_MODE);

// -------------------------------------------
cout << endl;

cout << "--- get_filesize_via_fseek_ftell" << endl;

cout << "Created in TXT mode, read in TXT mode: "
<< get_filesize_via_fseek_ftell (TXT_FILE_NAME, TXT_MODE)
<< endl;

cout << "Created in BIN mode, read in BIN mode: "
<< get_filesize_via_fseek_ftell (BIN_FILE_NAME, BIN_MODE)
<< endl;

cout << "Created in TXT mode, read in BIN mode: "
<< get_filesize_via_fseek_ftell (TXT_FILE_NAME, BIN_MODE)
<< endl;

cout << "Created in BIN mode, read in TXT mode: "
<< get_filesize_via_fseek_ftell (BIN_FILE_NAME, TXT_MODE)
<< endl;
// -------------------------------------------
cout << endl;

cout << "--- get_filesize_via_seekg_tellg" << endl;

cout << "Created in TXT mode, read in TXT mode: "
<< get_filesize_via_seekg_tellg (TXT_FILE_NAME, TXT_MODE)
<< endl;

cout << "Created in BIN mode, read in BIN mode: "
<< get_filesize_via_seekg_tellg (BIN_FILE_NAME, BIN_MODE)
<< endl;

cout << "Created in TXT mode, read in BIN mode: "
<< get_filesize_via_seekg_tellg (TXT_FILE_NAME, BIN_MODE) << endl;

cout << "Created in BIN mode, read in TXT mode: "
<< get_filesize_via_seekg_tellg (BIN_FILE_NAME, TXT_MODE)
<< endl;
// -------------------------------------------
cout << endl;

cout << "--- get_filesize_via_distance" << endl;

cout << "Created in TXT mode, read in TXT mode: "
<< get_filesize_via_distance (TXT_FILE_NAME, TXT_MODE)
<< endl;

cout << "Created in BIN mode, read in BIN mode: "
<< get_filesize_via_distance (BIN_FILE_NAME, BIN_MODE)
<< endl;

cout << "Created in TXT mode, read in BIN mode: "
<< get_filesize_via_distance (TXT_FILE_NAME, BIN_MODE)
<< endl;

cout << "Created in BIN mode, read in TXT mode: "
<< get_filesize_via_distance (BIN_FILE_NAME, TXT_MODE)
<< endl;

return 0;
}

// ====== foo.cpp : END ========

// ====== Run Log ========

--- get_filesize_via_fseek_ftell
Created in TXT mode, read in TXT mode: 2
Created in BIN mode, read in BIN mode: 1
Created in TXT mode, read in BIN mode: 2
Created in BIN mode, read in TXT mode: 1

--- get_filesize_via_seekg_tellg
Created in TXT mode, read in TXT mode: 2
Created in BIN mode, read in BIN mode: 1
Created in TXT mode, read in BIN mode: 2
Created in BIN mode, read in TXT mode: 1

--- get_filesize_via_distance
Created in TXT mode, read in TXT mode: 1
Created in BIN mode, read in BIN mode: 1
Created in TXT mode, read in BIN mode: 2
Created in BIN mode, read in TXT mode: 1

// =======================

--
Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn

Jul 23 '05 #8

"Alex Vinokur" <al****@big-foot.com> wrote in message news:36*************@individual.net...

"Dietmar Kuehl" <di***********@yahoo.com> wrote in message news:11*********************@z14g2000cwz.googlegro ups.com...
Steve wrote:
ifs.seekg(0,std::ios::end);
int len = ifs.tellg();
ifs.seekg(0,std::ios::beg);
char* buf = new char[len];


This is a pretty dangerous approach: there is actually no
portable approach to determine the number of characters in a
file except counting them, e.g. like this:

/**/ std::streamsize len = std::distance(
/**/ std::istreambuf_iterator<char>(ifs),
/**/ std::istreambuf_iterator<char>());

[snip]

[snip]
std::streampos len = ifs.rdbuf()->pubseekoff (0,ios::end,ios::in)));
ifs.rdbuf()->pubseekpos (0,ios::in);
--
Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn

Jul 23 '05 #9

"Alex Vinokur" <al****@big-foot.com> wrote in message news:37*************@individual.net...
[snip]

Once more method of getting file size.
std::streampos len = ifs.rdbuf()->pubseekoff (0,ios::end,ios::in)));
ifs.rdbuf()->pubseekpos (0,ios::in);

[snip]

Various methods of getting file size can be seen at
http://groups-beta.google.com/group/...464ce8b75f8417
--
Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn


Jul 23 '05 #10
Alex Vinokur wrote:
Various methods of getting file size can be seen at
http://groups-beta.google.com/group/...464ce8b75f8417


Actually, it is pretty obvious that you will get different results
with the various methods. The real question to ask first is what
you want to do with the file size and then use an adequat method
to determine that number - assuming that it is worth the effort to
determine it in the first place: at least on the systems I work
normally on (variants of UNIX) the file size is rather volatile
and effectively you cannot reliably assume that it does not change
even if you keep the file open. That is, for the intend of the
person who started this thread the file size is useless at best
and dangerous at worst: you may end up overwriting memory, get
less bytes than you wanted, etc.

If you just need the file size for informational purposes, e.g. to
display a progress bar, the seek methods should be OK. If you want
to determine the number of characters precisely (which, as I have
discussed above, is probably a pointless endeavour) you are stuck
with counting them: apart from text and binary mode, you also have
different encodings which may influence the number of characters.
Just install a locale with multi-byte encodings or contrive a
corresponding 'codecvt' facet and you get infinitely more fun into
the game.
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

Jul 23 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
by: Luiz Antonio Gomes Pican?o | last post by:
How i can store a variable length data in file ? I want to do it using pure C, without existing databases. I'm thinking to use pages to store data. Anyone has idea for the file format ? I...
1
by: Roy | last post by:
Hi, I have a problem that I have been working with for a while. I need to be able from server side (asp.net) to detect that the file i'm streaming down to the client is saved...
18
by: Jen | last post by:
I'm using Microsoft's own VB.NET FTP Example: http://support.microsoft.com/default.aspx?scid=kb;en-us;832679 I can get the program to create directories, change directories, etc., but I can't...
1
by: Jerry John | last post by:
I am working in ASP.NET with C#. I have a text file which contains datas with delimiters. For example:- MSH|^~\$|DISCHARGE|CLAY COUNTY MEMORIAL|||200502110939| I also have an XML file created...
9
by: Adi | last post by:
Hello eveyone, I wanna ask a very simple question here (as it was quite disturbing me for a long time.) My problem is to read a file line by line. I've tried following implementations but still...
7
by: ConfusedAlot | last post by:
This is my code for a database, whenever i save the database to the file 'database.txt' and display the results i get this; name - (correct, is what i put in) pin - 3435973836 slew rate -...
19
by: Lee Crabtree | last post by:
Is there a class in the framework that allows me read text from a file in an unbuffered manner? That is, I'd like to be able to read lines in the same manner as StreamReader.ReadLine(), but I also...
4
by: MikeJ | last post by:
make a While loop ofs = TextFileServer("somefile") string srow while (ofs=false) { srow=ofs.getRow(); Console.Writeline(srow); }
4
by: Vlad | last post by:
I am having problems using the file.create method within a function that is called when looping through an array of filepaths. If I call my function with a hardcoded file path --C:\Temp.txt the...
1
by: shyaminf | last post by:
hi everybody! iam facing a problem with the transfer of file using servlet programming. i have a code for uploading a file. but i'm unable to execute it using tomcat5.5 server. kindly help me how to...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Sept 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
0
by: Mushico | last post by:
How to calculate date of retirement from date of birth
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
4
NeoPa
by: NeoPa | last post by:
Hello everyone. I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report). I know it can be done by selecting :...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
0
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.