Applied patch [ 1531615 ] size support for wxFileName

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@40659 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Julian Smart 2006-08-18 15:30:28 +00:00
parent 95f090310c
commit 23b8a26299
5 changed files with 203 additions and 1 deletions

View File

@ -137,7 +137,7 @@ See also: \helpref{Traverse}{wxdirtraverse}
\constfunc{bool}{GetFirst}{\param{wxString* }{filename}, \param{const wxString\& }{filespec = wxEmptyString}, \param{int }{flags = wxDIR\_DEFAULT}}
Start enumerating all files matching {\it filespec} (or all files if it is
empty) and flags, return true on success.
empty) and {\it flags}, return \true on success.
\membersection{wxDir::GetName}\label{wxdirgetname}
@ -156,6 +156,25 @@ Continue enumerating files which satisfy the criteria specified by the last
call to \helpref{GetFirst}{wxdirgetfirst}.
\membersection{wxDir::GetTotalSize}\label{wxdirgettotalsize}
\func{static wxULongLong}{GetTotalSize}{\param{const wxString\& }{dir}, \param{wxArrayString* }{filesSkipped = NULL}}
Returns the size (in bytes) of all files recursively found in {\tt dir} or
{\tt wxInvalidSize} in case of error.
In case it happens that while traversing folders a file's size can not be read,
that file is added to the {\tt filesSkipped} array, if not \NULL, and then
skipped.
This usually happens with some special folders which are locked by the operating system
or by another process. Remember that when {\tt filesSkipped->GetCount()} is not zero,
then the returned value is not 100\% accurate and, if the skipped files were big, it could be
far from real size of the directory.
See also: \helpref{wxFileName::GetHumanReadableSize}{wxfilenamegethumanreadablesize},
\helpref{wxGetDiskSpace}{wxgetdiskspace}
\membersection{wxDir::HasFiles}\label{wxdirhasfiles}
\func{bool}{HasFiles}{\param{const wxString\& }{filespec = wxEmptyString}}

View File

@ -513,6 +513,33 @@ This is the same as calling \helpref{GetPath}{wxfilenamegetpath}
Return the short form of the path (returns identity on non-Windows platforms).
\membersection{wxFileName::GetSize}\label{wxfilenamegetsize}
\constfunc{wxULongLong}{GetSize}{\void}
\func{static wxULongLong}{GetSize}{\param{const wxString\& }{filename}}
Returns the size of this file (first form) or the size of the given file (second form).
If the file does not exist or its size could not be read (because e.g. the file is locked
by another process) the returned value is {\tt wxInvalidSize}.
\membersection{wxFileName::GetHumanReadableSize}\label{wxfilenamegethumanreadablesize}
\constfunc{wxString}{GetHumanReadableSize}{\param{const wxString\& }{failmsg = "Not available"}, \param{int }{precision = 1}}
\func{static wxString}{GetHumanReadableSize}{\param{const wxULongLong\& }{bytes}, \param{const wxString\& }{nullsize = "Not available"}, \param{int }{precision = 1}}
Returns the size of this file (first form) or the given number of bytes (second form)
in a human-readable form.
If the size could not be retrieved the {\tt failmsg} string is returned (first form).
If {\tt bytes} is {\tt wxInvalidSize} or zero, then {\tt nullsize} is returned (second form).
In case of success, the returned string is a floating-point number with {\tt precision} decimal digits
followed by the size unit (B, kB, MB, GB, TB: respectively bytes, kilobytes, megabytes, gigabytes, terabytes).
\membersection{wxFileName::GetTimes}\label{wxfilenamegettimes}
\constfunc{bool}{GetTimes}{\param{wxDateTime* }{dtAccess}, \param{wxDateTime* }{dtMod}, \param{wxDateTime* }{dtCreate}}

View File

@ -145,6 +145,9 @@ public:
const wxString& filespec,
int flags = wxDIR_DEFAULT);
// returns the size of all directories recursively found in given path
static wxULongLong GetTotalSize(const wxString &dir, wxArrayString *filesSkipped = NULL);
private:
friend class wxDirData;

View File

@ -33,6 +33,7 @@
#endif //WX_PRECOMP
#include "wx/dir.h"
#include "wx/filename.h"
// ============================================================================
// implementation
@ -284,3 +285,73 @@ wxString wxDir::FindFirst(const wxString& dirname,
return wxEmptyString;
}
// ----------------------------------------------------------------------------
// wxDir::GetTotalSize()
// ----------------------------------------------------------------------------
class wxDirTraverserSumSize : public wxDirTraverser
{
public:
wxDirTraverserSumSize() { m_skippedFiles=false; }
virtual wxDirTraverseResult OnFile(const wxString& filename)
{
wxULongLong sz = wxFileName::GetSize(filename);
// wxFileName::GetSize won't use this class again as
// we're passing it a file and not a directory;
// thus we are sure to avoid an endless loop
if (sz == wxInvalidSize)
{
// if the GetSize() failed (this can happen because e.g. a
// file is locked by another process), we can proceed but
// we need to at least warn the user that the resulting
// final size could be not reliable (if e.g. the locked
// file is very big).
m_skippedFiles.Add(filename);
return wxDIR_CONTINUE;
}
m_sz += sz;
return wxDIR_CONTINUE;
}
virtual wxDirTraverseResult OnDir(const wxString& WXUNUSED(dirname))
{
return wxDIR_CONTINUE;
}
wxULongLong GetTotalSize() const
{ return m_sz; }
wxArrayString &FilesSkipped()
{ return m_skippedFiles; }
protected:
wxULongLong m_sz;
wxArrayString m_skippedFiles;
};
wxULongLong wxDir::GetTotalSize(const wxString &dirname, wxArrayString *filesSkipped)
{
if (!wxDirExists(dirname))
return wxInvalidSize;
// to get the size of this directory and its contents we need
// to recursively walk it...
wxDir dir(dirname);
if ( !dir.IsOpened() )
return wxInvalidSize;
wxDirTraverserSumSize traverser;
if (dir.Traverse(traverser) == (size_t)-1 ||
traverser.GetTotalSize() == 0)
return wxInvalidSize;
if (filesSkipped)
*filesSkipped = traverser.FilesSkipped();
return traverser.GetTotalSize();
}

View File

@ -139,6 +139,10 @@
#define MAX_PATH _MAX_PATH
#endif
wxULongLong wxInvalidSize = (unsigned)-1;
// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
@ -2019,6 +2023,84 @@ bool wxFileName::GetTimes(wxDateTime *dtAccess,
#endif // wxUSE_DATETIME
// ----------------------------------------------------------------------------
// file size functions
// ----------------------------------------------------------------------------
/* static */
wxULongLong wxFileName::GetSize(const wxString &filename)
{
if (!wxFileExists(filename))
return wxInvalidSize;
#ifdef __WIN32__
wxFileHandle f(filename, wxFileHandle::Read);
if (!f.IsOk())
return wxInvalidSize;
DWORD lpFileSizeHigh;
DWORD ret = GetFileSize(f, &lpFileSizeHigh);
if (ret == INVALID_FILE_SIZE)
return wxInvalidSize;
// compose the low-order and high-order byte sizes
return wxULongLong(ret | (lpFileSizeHigh << sizeof(WORD)*2));
#else // ! __WIN32__
wxStructStat st;
#ifndef wxNEED_WX_UNISTD_H
if (wxStat( filename.fn_str() , &st) != 0)
#else
if (wxStat( filename, &st) != 0)
#endif
return wxInvalidSize;
return wxULongLong(st.st_size);
#endif
}
/* static */
wxString wxFileName::GetHumanReadableSize(const wxULongLong &bs,
const wxString &nullsize,
int precision)
{
static const double KILOBYTESIZE = 1024.0;
static const double MEGABYTESIZE = 1024.0*KILOBYTESIZE;
static const double GIGABYTESIZE = 1024.0*MEGABYTESIZE;
static const double TERABYTESIZE = 1024.0*GIGABYTESIZE;
if (bs == 0 || bs == wxInvalidSize)
return nullsize;
double bytesize = bs.ToDouble();
if (bytesize < KILOBYTESIZE)
return wxString::Format(_("%s B"), bs.ToString().c_str());
if (bytesize < MEGABYTESIZE)
return wxString::Format(_("%.*f kB"), precision, bytesize/KILOBYTESIZE);
if (bytesize < GIGABYTESIZE)
return wxString::Format(_("%.*f MB"), precision, bytesize/MEGABYTESIZE);
if (bytesize < TERABYTESIZE)
return wxString::Format(_("%.*f GB"), precision, bytesize/GIGABYTESIZE);
return wxString::Format(_("%.*f TB"), precision, bytesize/TERABYTESIZE);
}
wxULongLong wxFileName::GetSize() const
{
return GetSize(GetFullPath());
}
wxString wxFileName::GetHumanReadableSize(const wxString &failmsg, int precision) const
{
return GetHumanReadableSize(GetSize(), failmsg, precision);
}
// ----------------------------------------------------------------------------
// Mac-specific functions
// ----------------------------------------------------------------------------
#ifdef __WXMAC__
const short kMacExtensionMaxLength = 16 ;