#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);}}// 去除尾部的0size_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;
}