473,224 Members | 1,310 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

Handling file sizes correctly

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
5 3424
"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
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

"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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

115
by: J | last post by:
I've run CSSCheck on my style sheets and I always get a warning similar to this: "font: bold 9pt/100% sans-serif Warning: Absolute length units should not generally be used on the Web ..." ...
21
by: Anthony England | last post by:
Everyone knows that global variables get re-set in an mdb when an un-handled error is encountered, but it seems that this also happens when the variable is defined as private at form-level. So...
4
by: Vagabond Software | last post by:
Apparently, the Split method handles consecutive tabs as a single delimiter. Does anyone have any suggestions for handling consecutive tabs? I am reading in text files that contain lines of...
34
by: rawCoder | last post by:
I have read that Exception Handling is expensive performance wise ( other than Throw ) , but exactly how ? Please consider the following example ... ////////////////// Code Block 1...
9
by: Jay Kim | last post by:
Hi, We're implementing a Windows application using Visual Basic .NET. One of the key features we need to implement is that we should be able to get the accurate byte offset of user selected...
4
by: Al Williams | last post by:
Hi, I have error handling in place throughout my application. I also start the application wrapped in error handling code to catch any unexpected exceptions (i.e. exceptions that occur where I...
3
by: Binu C | last post by:
hi am new to VB. I need to develop an application. The requirements are as follows: We have a notepad which consists of some data(Say A). Now we have a form in which we have some text fields & a...
3
by: kayahr | last post by:
Hi there, I have a strange problem in Internet Explorer (IE6 and IE7). I'm writing a JavaScript application which allows the user to edit a photo composition. So when the user selects a photo then...
10
by: deciacco | last post by:
I'm writing a command line utility to move some files. I'm dealing with thousands of files and I was wondering if anyone had any suggestions. This is what I have currently: $arrayVirtualFile =...
1
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
0
by: veera ravala | last post by:
ServiceNow is a powerful cloud-based platform that offers a wide range of services to help organizations manage their workflows, operations, and IT services more efficiently. At its core, ServiceNow...
0
by: VivesProcSPL | last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: mar23 | last post by:
Here's the situation. I have a form called frmDiceInventory with subform called subfrmDice. The subform's control source is linked to a query called qryDiceInventory. I've been trying to pick up the...
2
by: jimatqsi | last post by:
The boss wants the word "CONFIDENTIAL" overlaying certain reports. He wants it large, slanted across the page, on every page, very light gray, outlined letters, not block letters. I thought Word Art...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....

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.