#pragma once
#include <string>
#include <stdint.h>
#ifdef _UNICODE
using _tstring = std::wstring;
#else
using _tstring = std::string;
#endif
//
// @brief: 字节大小格式化
// @param: nBytesSize 输入字节大小
// @param: bSpace 输出是否需要空格
// @param: nPrecision 精度(指定小数点后多少位数字)
// @param: bTruncate 是否截断未显示的数字(true: 放弃未显示的数字 false: 舍入到最接近的显示数字)
_tstring FormatByteSize(
uint64_t nBytesSize,
bool bSpace/* = true*/,
int nPrecision/* = 3*/,
bool bTruncate
)
{
TCHAR szFormatBuf[MAX_PATH] = { 0 };
TCHAR szResultBuf[MAX_PATH] = { 0 };
_tstring strResult;
uint64_t nCurUtilSize = 1;
uint64_t nNextUtilSize = 1024;
LPCTSTR strUtilName[] = {
_T("Bytes"),
_T("KB"),
_T("MB"),
_T("GB"),
_T("TB"),
_T("PB"),
_T("EB"),
};
if (bTruncate)
{
::_stprintf_s(szFormatBuf, _countof(szFormatBuf), _T("%%.%dlf"), 16);
}
else
{
::_stprintf_s(szFormatBuf, _countof(szFormatBuf), _T("%%.%dlf"), nPrecision);
}
int nUtilIndex = 0;
for (int i = 0; i < _countof(strUtilName); i++)
{
if ((nBytesSize >= nCurUtilSize && nBytesSize < nNextUtilSize) || 0 == nNextUtilSize || 0 == nBytesSize)
{
double lfResult = (double)nBytesSize / (double)nCurUtilSize;
::_stprintf_s(szResultBuf, _countof(szResultBuf), szFormatBuf, lfResult);
strResult = szResultBuf;
nUtilIndex = i;
break;
}
nCurUtilSize *= 1024;
nNextUtilSize *= 1024;
}
if (bTruncate)
{
size_t nDotPos = strResult.find(_T('.'));
if (_tstring::npos != nDotPos)
{
strResult.resize(nDotPos + 1 + nPrecision);
}
}
// 去除尾部的0
size_t nLength = strResult.size();
for (auto item = strResult.crbegin(); item != strResult.crend(); item++)
{
if (_T('.') == *item)
{
nLength--;
break;
}
if (_T('0') != *item)
{
break;
}
nLength--;
}
strResult.resize(nLength);
if (bSpace)
{
strResult += _T(" ");
}
strResult += strUtilName[nUtilIndex];
return strResult;
}