By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,234 Members | 1,889 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,234 IT Pros & Developers. It's quick & easy.

Handling file sizes correctly

P: n/a
Hello,

in my application, I want to print file sizes in a human readable
format. However, I remember a thread here which dealt with a similar
issue, and people said it'd be a bad idea to write numbers like 1024 and
so on explicitly. Unfortunately I can't remember the reason.

Can you elaborate on that?

Thanks.

--
Matthias Kaeppler
Jul 23 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
"Matthias Kaeppler" <no****@digitalraid.com> wrote in message
news:d3c265$6tr$05
in my application, I want to print file sizes in a human readable
format. However, I remember a thread here which dealt with a similar
issue, and people said it'd be a bad idea to write numbers like 1024 and
so on explicitly. Unfortunately I can't remember the reason.

Can you elaborate on that?


Hmmm. To write numbers in human readable format seems to be always safe. I
think by writing directly they might have meant writing the bit
representation to the file. Problem with this method is that it is not
portable, as different platforms has different sizeof for the same integer
type, and the endian-ness may be different too, plus there will be other
differences in floating point representation.
Jul 23 '05 #2

P: n/a
Matthias Kaeppler wrote:
Hello,

in my application, I want to print file sizes in a human readable
format. However, I remember a thread here which dealt with a similar
issue, and people said it'd be a bad idea to write numbers like 1024 and
so on explicitly. Unfortunately I can't remember the reason.

Can you elaborate on that?

Thanks.


Maybe it's a better idea after all if I post my code, and you tell me
whether it's okay or not. The function is supposed to create a string
from an integer holding the formatted size:

Glib::ustring FileBrowser::get_file_size( const boostfs::path& path )
{
Glib::ustring str_size;

try
{
if( boostfs::is_directory(path) )
return "0";

boost::intmax_t size = boostfs::file_size( path );

const int KILO_BYTE = 1024;
const int MEGA_BYTE = KILO_BYTE * 1024;
const int GIGA_BYTE = MEGA_BYTE * 1024;

if( size >= GIGA_BYTE )
{
size /= GIGA_BYTE;
str_size = boost::lexical_cast<Glib::ustring>(size) + " GB";
}
else if( size >= MEGA_BYTE )
{
size /= MEGA_BYTE;
str_size = boost::lexical_cast<Glib::ustring>(size) + " MB";
}
else if( size >= KILO_BYTE )
{
size /= KILO_BYTE;
str_size = boost::lexical_cast<Glib::ustring>(size) + " KB";
}
else
{
str_size = boost::lexical_cast<Glib::ustring>(size) + " B";
}
}
catch( const boostfs::filesystem_error& e )
{
std::cerr << e.what() << std::endl;
}

return str_size;
}

By the way, it would be cool if the file size wasn't reduced to a
rounded integer, but a float or double has too many digits.
Any idea how I can trim them to only one digit behind the dot, e.g.:

12.3 MB instead of 12.3xxxxxxx MB or such.

--
Matthias Kaeppler
Jul 23 '05 #3

P: n/a

"Matthias Kaeppler" <no****@digitalraid.com> wrote in message
news:d3*************@news.t-online.com...
Matthias Kaeppler wrote:
Hello,

in my application, I want to print file sizes in a human readable format.
However, I remember a thread here which dealt with a similar issue, and
people said it'd be a bad idea to write numbers like 1024 and so on
explicitly. Unfortunately I can't remember the reason.

Can you elaborate on that?

Thanks.


Maybe it's a better idea after all if I post my code, and you tell me
whether it's okay or not. The function is supposed to create a string from
an integer holding the formatted size:

Glib::ustring FileBrowser::get_file_size( const boostfs::path& path )
{
Glib::ustring str_size;

try
{
if( boostfs::is_directory(path) )
return "0";

boost::intmax_t size = boostfs::file_size( path );

const int KILO_BYTE = 1024;
const int MEGA_BYTE = KILO_BYTE * 1024;
const int GIGA_BYTE = MEGA_BYTE * 1024;

if( size >= GIGA_BYTE )
{
size /= GIGA_BYTE;
str_size = boost::lexical_cast<Glib::ustring>(size) + " GB";
}
else if( size >= MEGA_BYTE )
{
size /= MEGA_BYTE;
str_size = boost::lexical_cast<Glib::ustring>(size) + " MB";
}
else if( size >= KILO_BYTE )
{
size /= KILO_BYTE;
str_size = boost::lexical_cast<Glib::ustring>(size) + " KB";
}
else
{
str_size = boost::lexical_cast<Glib::ustring>(size) + " B";
}
}
catch( const boostfs::filesystem_error& e )
{
std::cerr << e.what() << std::endl;
}

return str_size;
}

By the way, it would be cool if the file size wasn't reduced to a rounded
integer, but a float or double has too many digits.
Any idea how I can trim them to only one digit behind the dot, e.g.:

12.3 MB instead of 12.3xxxxxxx MB or such.

--
Matthias Kaeppler


Matthias, I made the following function to print filesize formated like 625
b, 1.34 Kb, 12.8 Kb, 16.3 Mb, 4.23 Gb, etc. to fit in a table. Just send
the filesize as a function argument and the function couts the text. I'd be
easy enough to modify the function to return a string.

Sorry if my long lines don't print very well...

void printFileSize(unsigned long int lof_in){
cout.precision(3);
cout << setw(4) << setfill(' ');
(lof_in < (1 << 10))
? (cout << lof_in << " b\t")
: (lof_in < (1 << 20))
? (cout << (static_cast<float>(lof_in)/(1 << 10)) << " Kb\t")
: (lof_in < (1 << 30))
? (cout << (static_cast<float>(lof_in)/(1 << 20)) << "
Mb\t" )
: (cout << (static_cast<float>(lof_in)/(1 << 30)) << "
Gb\t");
}
Jul 23 '05 #4

P: n/a
Joe C wrote:
"Matthias Kaeppler" <no****@digitalraid.com> wrote in message
news:d3*************@news.t-online.com...
Matthias Kaeppler wrote:
Hello,

in my application, I want to print file sizes in a human readable format.
However, I remember a thread here which dealt with a similar issue, and
people said it'd be a bad idea to write numbers like 1024 and so on
explicitly. Unfortunately I can't remember the reason.

Can you elaborate on that?

Thanks.


Maybe it's a better idea after all if I post my code, and you tell me
whether it's okay or not. The function is supposed to create a string from
an integer holding the formatted size:

Glib::ustring FileBrowser::get_file_size( const boostfs::path& path )
{
Glib::ustring str_size;

try
{
if( boostfs::is_directory(path) )
return "0";

boost::intmax_t size = boostfs::file_size( path );

const int KILO_BYTE = 1024;
const int MEGA_BYTE = KILO_BYTE * 1024;
const int GIGA_BYTE = MEGA_BYTE * 1024;

if( size >= GIGA_BYTE )
{
size /= GIGA_BYTE;
str_size = boost::lexical_cast<Glib::ustring>(size) + " GB";
}
else if( size >= MEGA_BYTE )
{
size /= MEGA_BYTE;
str_size = boost::lexical_cast<Glib::ustring>(size) + " MB";
}
else if( size >= KILO_BYTE )
{
size /= KILO_BYTE;
str_size = boost::lexical_cast<Glib::ustring>(size) + " KB";
}
else
{
str_size = boost::lexical_cast<Glib::ustring>(size) + " B";
}
}
catch( const boostfs::filesystem_error& e )
{
std::cerr << e.what() << std::endl;
}

return str_size;
}

By the way, it would be cool if the file size wasn't reduced to a rounded
integer, but a float or double has too many digits.
Any idea how I can trim them to only one digit behind the dot, e.g.:

12.3 MB instead of 12.3xxxxxxx MB or such.

--
Matthias Kaeppler

Matthias, I made the following function to print filesize formated like 625
b, 1.34 Kb, 12.8 Kb, 16.3 Mb, 4.23 Gb, etc. to fit in a table. Just send
the filesize as a function argument and the function couts the text. I'd be
easy enough to modify the function to return a string.

Sorry if my long lines don't print very well...

void printFileSize(unsigned long int lof_in){
cout.precision(3);
cout << setw(4) << setfill(' ');
(lof_in < (1 << 10))
? (cout << lof_in << " b\t")
: (lof_in < (1 << 20))
? (cout << (static_cast<float>(lof_in)/(1 << 10)) << " Kb\t")
: (lof_in < (1 << 30))
? (cout << (static_cast<float>(lof_in)/(1 << 20)) << "
Mb\t" )
: (cout << (static_cast<float>(lof_in)/(1 << 30)) << "
Gb\t");
}


Ah, of course, the std::cout::precision thing is the key. Thanks a lot
for that function Joe!

--
Matthias Kaeppler
Jul 23 '05 #5

P: n/a
Joe C wrote:
"Matthias Kaeppler" <no****@digitalraid.com> wrote in message
news:d3*************@news.t-online.com...
Matthias Kaeppler wrote:
Hello,

in my application, I want to print file sizes in a human readable format.
However, I remember a thread here which dealt with a similar issue, and
people said it'd be a bad idea to write numbers like 1024 and so on
explicitly. Unfortunately I can't remember the reason.

Can you elaborate on that?

Thanks.


Maybe it's a better idea after all if I post my code, and you tell me
whether it's okay or not. The function is supposed to create a string from
an integer holding the formatted size:

Glib::ustring FileBrowser::get_file_size( const boostfs::path& path )
{
Glib::ustring str_size;

try
{
if( boostfs::is_directory(path) )
return "0";

boost::intmax_t size = boostfs::file_size( path );

const int KILO_BYTE = 1024;
const int MEGA_BYTE = KILO_BYTE * 1024;
const int GIGA_BYTE = MEGA_BYTE * 1024;

if( size >= GIGA_BYTE )
{
size /= GIGA_BYTE;
str_size = boost::lexical_cast<Glib::ustring>(size) + " GB";
}
else if( size >= MEGA_BYTE )
{
size /= MEGA_BYTE;
str_size = boost::lexical_cast<Glib::ustring>(size) + " MB";
}
else if( size >= KILO_BYTE )
{
size /= KILO_BYTE;
str_size = boost::lexical_cast<Glib::ustring>(size) + " KB";
}
else
{
str_size = boost::lexical_cast<Glib::ustring>(size) + " B";
}
}
catch( const boostfs::filesystem_error& e )
{
std::cerr << e.what() << std::endl;
}

return str_size;
}

By the way, it would be cool if the file size wasn't reduced to a rounded
integer, but a float or double has too many digits.
Any idea how I can trim them to only one digit behind the dot, e.g.:

12.3 MB instead of 12.3xxxxxxx MB or such.

--
Matthias Kaeppler

Matthias, I made the following function to print filesize formated like 625
b, 1.34 Kb, 12.8 Kb, 16.3 Mb, 4.23 Gb, etc. to fit in a table. Just send
the filesize as a function argument and the function couts the text. I'd be
easy enough to modify the function to return a string.

Sorry if my long lines don't print very well...

void printFileSize(unsigned long int lof_in){
cout.precision(3);
cout << setw(4) << setfill(' ');
(lof_in < (1 << 10))
? (cout << lof_in << " b\t")
: (lof_in < (1 << 20))
? (cout << (static_cast<float>(lof_in)/(1 << 10)) << " Kb\t")
: (lof_in < (1 << 30))
? (cout << (static_cast<float>(lof_in)/(1 << 20)) << "
Mb\t" )
: (cout << (static_cast<float>(lof_in)/(1 << 30)) << "
Gb\t");
}


Hmmm, based on your code, I have changed mine to look like this:

Glib::ustring FileBrowser::get_file_size( const boostfs::path& path )
{
std::ostringstream sstream;
sstream.precision( 2 );

try
{
if( boostfs::is_directory(path) )
return "0";

boost::intmax_t size = boostfs::file_size( path );

if( size >= GIGA_BYTE )
{
sstream << (static_cast<float>(size) / GIGA_BYTE);
sstream << " GB";
}
else if( size >= MEGA_BYTE )
{
sstream << (static_cast<float>(size) / MEGA_BYTE);
sstream << " MB";
}
else if( size >= KILO_BYTE )
{
sstream << (static_cast<float>(size) / KILO_BYTE);
sstream << " KB";
}
else
{
sstream << size;
sstream << " B";
}
}
catch( const boostfs::filesystem_error& e )
{
std::cerr << e.what() << std::endl;
}

return sstream.str();
}

However, it sometimes prints garbage, like "1.7e+02 KB" for a file which
is only a couple of KB large and I don't find my error.

--
Matthias Kaeppler
Jul 23 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.