বেট সংক্ষিপ্তসার .NET ব্যবহার করে আমি কীভাবে একটি মানব-পঠনযোগ্য ফাইলের আকার পেতে পারি?
উদাহরণ : 7,326,629 ইনপুট নিন এবং 6.98 এমবি প্রদর্শন করুন
বেট সংক্ষিপ্তসার .NET ব্যবহার করে আমি কীভাবে একটি মানব-পঠনযোগ্য ফাইলের আকার পেতে পারি?
উদাহরণ : 7,326,629 ইনপুট নিন এবং 6.98 এমবি প্রদর্শন করুন
উত্তর:
এটি করার সর্বাধিক দক্ষ উপায় নয়, তবে আপনি যদি লগের গণিতের সাথে পরিচিত না হন তবে এটি পড়া সহজ এবং বেশিরভাগ পরিস্থিতিতে আপনার পক্ষে যথেষ্ট দ্রুত হওয়া উচিত।
string[] sizes = { "B", "KB", "MB", "GB", "TB" };
double len = new FileInfo(filename).Length;
int order = 0;
while (len >= 1024 && order < sizes.Length - 1) {
order++;
len = len/1024;
}
// Adjust the format string to your preferences. For example "{0:0.#}{1}" would
// show a single decimal place, and no space.
string result = String.Format("{0:0.##} {1}", len, sizes[order]);
The unit was established by the International Electrotechnical Commission (IEC) in 1998 and has been accepted for use by all major standards organizations
সমস্যার সমাধান করতে লগ ব্যবহার করুন ....
static String BytesToString(long byteCount)
{
string[] suf = { "B", "KB", "MB", "GB", "TB", "PB", "EB" }; //Longs run out around EB
if (byteCount == 0)
return "0" + suf[0];
long bytes = Math.Abs(byteCount);
int place = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024)));
double num = Math.Round(bytes / Math.Pow(1024, place), 1);
return (Math.Sign(byteCount) * num).ToString() + suf[place];
}
সি # তেও, তবে রূপান্তর করতে একটি স্ন্যাপ হওয়া উচিত। পাঠযোগ্যতার জন্য আমি 1 দশমিক স্থানে গোল করেছি।
মূলত বেস 1024 এ দশমিক জায়গাগুলির সংখ্যা নির্ধারণ করুন এবং তারপরে 1024 ^ দশমিক বিভাজন দ্বারা ভাগ করুন।
এবং ব্যবহার এবং ফলাফলের কয়েকটি নমুনা:
Console.WriteLine(BytesToString(9223372036854775807)); //Results in 8EB
Console.WriteLine(BytesToString(0)); //Results in 0B
Console.WriteLine(BytesToString(1024)); //Results in 1KB
Console.WriteLine(BytesToString(2000000)); //Results in 1.9MB
Console.WriteLine(BytesToString(-9023372036854775807)); //Results in -7.8EB
সম্পাদনা: চিহ্নিত করা হয়েছিল যে আমি একটি গণিত মিস করেছি lo ফ্লোর, তাই আমি এটি অন্তর্ভুক্ত করেছি। (রূপান্তর। টুআইন্ট 32 রাউন্ডিং ব্যবহার করে, ছাঁটাই নয় এবং এজন্য মেঝে প্রয়োজনীয়)) ক্যাচের জন্য ধন্যবাদ।
সম্পাদনা 2: নেতিবাচক আকার এবং 0 বাইট মাপ সম্পর্কে বেশ কয়েকটি মন্তব্য ছিল, তাই আমি সেই 2 টি মামলা পরিচালনা করতে আপডেট করেছি।
double.MaxValue
(স্থান = 102) এর জন্য ব্যর্থ
অনুরোধ করা ফাংশনের একটি পরীক্ষিত এবং উল্লেখযোগ্যভাবে অনুকূলিত সংস্করণ এখানে পোস্ট করা হয়েছে:
সি # মানব পঠনযোগ্য ফাইলের আকার - অনুকূলিত ফাংশন
সোর্স কোড:
// Returns the human-readable file size for an arbitrary, 64-bit file size
// The default format is "0.### XB", e.g. "4.2 KB" or "1.434 GB"
public string GetBytesReadable(long i)
{
// Get absolute value
long absolute_i = (i < 0 ? -i : i);
// Determine the suffix and readable value
string suffix;
double readable;
if (absolute_i >= 0x1000000000000000) // Exabyte
{
suffix = "EB";
readable = (i >> 50);
}
else if (absolute_i >= 0x4000000000000) // Petabyte
{
suffix = "PB";
readable = (i >> 40);
}
else if (absolute_i >= 0x10000000000) // Terabyte
{
suffix = "TB";
readable = (i >> 30);
}
else if (absolute_i >= 0x40000000) // Gigabyte
{
suffix = "GB";
readable = (i >> 20);
}
else if (absolute_i >= 0x100000) // Megabyte
{
suffix = "MB";
readable = (i >> 10);
}
else if (absolute_i >= 0x400) // Kilobyte
{
suffix = "KB";
readable = i;
}
else
{
return i.ToString("0 B"); // Byte
}
// Divide by 1024 to get fractional value
readable = (readable / 1024);
// Return formatted number with suffix
return readable.ToString("0.### ") + suffix;
}
double readable = (i < 0 ? -i : i);
কোথাও মান ব্যবহার করবেন না তাই এটি মুছে ফেলুন। আরও একটি জিনিস, castালাই আবার রৌদ্রাদাত
Math.Abs
করবেন না ?
[DllImport ( "Shlwapi.dll", CharSet = CharSet.Auto )]
public static extern long StrFormatByteSize (
long fileSize
, [MarshalAs ( UnmanagedType.LPTStr )] StringBuilder buffer
, int bufferSize );
/// <summary>
/// Converts a numeric value into a string that represents the number expressed as a size value in bytes, kilobytes, megabytes, or gigabytes, depending on the size.
/// </summary>
/// <param name="filelength">The numeric value to be converted.</param>
/// <returns>the converted string</returns>
public static string StrFormatByteSize (long filesize) {
StringBuilder sb = new StringBuilder( 11 );
StrFormatByteSize( filesize, sb, sb.Capacity );
return sb.ToString();
}
থেকে: http://www.pinvoke.net/default.aspx/shlwapi/StrformatByteSize.html
কোনও ধরণের লুপ ছাড়াই এবং নেতিবাচক আকারের সমর্থন ছাড়াই এটি চামড়ার আরও একটি উপায় (ফাইলের আকারের ডেল্টাসের মতো জিনিসগুলি বোঝায়):
public static class Format
{
static string[] sizeSuffixes = {
"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
public static string ByteSize(long size)
{
Debug.Assert(sizeSuffixes.Length > 0);
const string formatTemplate = "{0}{1:0.#} {2}";
if (size == 0)
{
return string.Format(formatTemplate, null, 0, sizeSuffixes[0]);
}
var absSize = Math.Abs((double)size);
var fpPower = Math.Log(absSize, 1000);
var intPower = (int)fpPower;
var iUnit = intPower >= sizeSuffixes.Length
? sizeSuffixes.Length - 1
: intPower;
var normSize = absSize / Math.Pow(1000, iUnit);
return string.Format(
formatTemplate,
size < 0 ? "-" : null, normSize, sizeSuffixes[iUnit]);
}
}
এবং এখানে পরীক্ষার স্যুটটি রয়েছে:
[TestFixture] public class ByteSize
{
[TestCase(0, Result="0 B")]
[TestCase(1, Result = "1 B")]
[TestCase(1000, Result = "1 KB")]
[TestCase(1500000, Result = "1.5 MB")]
[TestCase(-1000, Result = "-1 KB")]
[TestCase(int.MaxValue, Result = "2.1 GB")]
[TestCase(int.MinValue, Result = "-2.1 GB")]
[TestCase(long.MaxValue, Result = "9.2 EB")]
[TestCase(long.MinValue, Result = "-9.2 EB")]
public string Format_byte_size(long size)
{
return Format.ByteSize(size);
}
}
বাইটসাইজ লাইব্রেরি চেকআউট করুন । এটা System.TimeSpan
বাইট জন্য!
এটি আপনার জন্য রূপান্তর এবং বিন্যাস পরিচালনা করে।
var maxFileSize = ByteSize.FromKiloBytes(10);
maxFileSize.Bytes;
maxFileSize.MegaBytes;
maxFileSize.GigaBytes;
এটি স্ট্রিং প্রতিনিধিত্ব এবং পার্সিংও করে।
// ToString
ByteSize.FromKiloBytes(1024).ToString(); // 1 MB
ByteSize.FromGigabytes(.5).ToString(); // 512 MB
ByteSize.FromGigabytes(1024).ToString(); // 1 TB
// Parsing
ByteSize.Parse("5b");
ByteSize.Parse("1.55B");
আমি নিম্নলিখিত পদ্ধতিটি ব্যবহার করতে চাই (এটি টেরাবাইট পর্যন্ত সমর্থন করে যা বেশিরভাগ ক্ষেত্রে যথেষ্ট, তবে এটি সহজেই বাড়ানো যেতে পারে):
private string GetSizeString(long length)
{
long B = 0, KB = 1024, MB = KB * 1024, GB = MB * 1024, TB = GB * 1024;
double size = length;
string suffix = nameof(B);
if (length >= TB) {
size = Math.Round((double)length / TB, 2);
suffix = nameof(TB);
}
else if (length >= GB) {
size = Math.Round((double)length / GB, 2);
suffix = nameof(GB);
}
else if (length >= MB) {
size = Math.Round((double)length / MB, 2);
suffix = nameof(MB);
}
else if (length >= KB) {
size = Math.Round((double)length / KB, 2);
suffix = nameof(KB);
}
return $"{size} {suffix}";
}
দয়া করে মনে রাখবেন যে এটি সি # 6.0 (2015) এর জন্য লেখা হয়েছে, সুতরাং এটি পূর্ববর্তী সংস্করণগুলির জন্য সামান্য সম্পাদনার প্রয়োজন হতে পারে।
int size = new FileInfo( filePath ).Length / 1024;
string humanKBSize = string.Format( "{0} KB", size );
string humanMBSize = string.Format( "{0} MB", size / 1024 );
string humanGBSize = string.Format( "{0} GB", size / 1024 / 1024 );
Math.Ceiling
বা কিছু বা কিছু ব্যবহার করতে পারেন ।
এখানে একটি সংক্ষিপ্ত উত্তর যা ইউনিটটি স্বয়ংক্রিয়ভাবে নির্ধারণ করে।
public static string ToBytesCount(this long bytes)
{
int unit = 1024;
string unitStr = "b";
if (bytes < unit) return string.Format("{0} {1}", bytes, unitStr);
else unitStr = unitStr.ToUpper();
int exp = (int)(Math.Log(bytes) / Math.Log(unit));
return string.Format("{0:##.##} {1}{2}", bytes / Math.Pow(unit, exp), "KMGTPEZY"[exp - 1], unitStr);
}
"বি" বিটের জন্য, "বি" বাইটের জন্য এবং "কেএমজিপিটিজি" যথাক্রমে কিলো, মেগা, গিগা, তেরা, পেটা, এক্সা, জিটা এবং ইয়োটার জন্য
আইএসও / আইসিসি 80000 অ্যাকাউন্টে নিতে কেউ এটিকে প্রসারিত করতে পারে :
public static string ToBytesCount(this long bytes, bool isISO = true)
{
int unit = 1024;
string unitStr = "b";
if (!isISO) unit = 1000;
if (bytes < unit) return string.Format("{0} {1}", bytes, unitStr);
else unitStr = unitStr.ToUpper();
if (isISO) unitStr = "i" + unitStr;
int exp = (int)(Math.Log(bytes) / Math.Log(unit));
return string.Format("{0:##.##} {1}{2}", bytes / Math.Pow(unit, exp), "KMGTPEZY"[exp - 1], unitStr);
}
o
KMGTPE পর: এর ফরাসি ( byte
হয় octet
ফরাসি মধ্যে)। অন্য কোন ভাষা শুধু প্রতিস্থাপন জন্য o
সঙ্গেb
string[] suffixes = { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
int s = 0;
long size = fileInfo.Length;
while (size >= 1024)
{
s++;
size /= 1024;
}
string humanReadable = String.Format("{0} {1}", size, suffixes[s]);
আপনি যদি উইন্ডোজ এক্সপ্লোরারের বিস্তারিত ভিউতে দেখানো মাপের সাথে মেলে চেষ্টা করছেন তবে এটি আপনার চাই কোডটি:
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
private static extern long StrFormatKBSize(
long qdw,
[MarshalAs(UnmanagedType.LPTStr)] StringBuilder pszBuf,
int cchBuf);
public static string BytesToString(long byteCount)
{
var sb = new StringBuilder(32);
StrFormatKBSize(byteCount, sb, sb.Capacity);
return sb.ToString();
}
এটি কেবল এক্সপ্লোরারকেই মেলে না তবে আপনার জন্য অনুবাদ করা স্ট্রিং সরবরাহ করবে এবং উইন্ডোজ সংস্করণগুলিতে পার্থক্য মেলে (উদাহরণস্বরূপ উইন 10, কে = 1000 বনাম পূর্ববর্তী সংস্করণ কে = 1024) match
সমস্ত সমাধানের মিশ্রণ :-)
/// <summary>
/// Converts a numeric value into a string that represents the number expressed as a size value in bytes,
/// kilobytes, megabytes, or gigabytes, depending on the size.
/// </summary>
/// <param name="fileSize">The numeric value to be converted.</param>
/// <returns>The converted string.</returns>
public static string FormatByteSize(double fileSize)
{
FileSizeUnit unit = FileSizeUnit.B;
while (fileSize >= 1024 && unit < FileSizeUnit.YB)
{
fileSize = fileSize / 1024;
unit++;
}
return string.Format("{0:0.##} {1}", fileSize, unit);
}
/// <summary>
/// Converts a numeric value into a string that represents the number expressed as a size value in bytes,
/// kilobytes, megabytes, or gigabytes, depending on the size.
/// </summary>
/// <param name="fileInfo"></param>
/// <returns>The converted string.</returns>
public static string FormatByteSize(FileInfo fileInfo)
{
return FormatByteSize(fileInfo.Length);
}
}
public enum FileSizeUnit : byte
{
B,
KB,
MB,
GB,
TB,
PB,
EB,
ZB,
YB
}
একটি ওপেন সোর্স প্রকল্প রয়েছে যা এটি করতে পারে এবং আরও অনেক কিছু করতে পারে।
7.Bits().ToString(); // 7 b
8.Bits().ToString(); // 1 B
(.5).Kilobytes().Humanize(); // 512 B
(1000).Kilobytes().ToString(); // 1000 KB
(1024).Kilobytes().Humanize(); // 1 MB
(.5).Gigabytes().Humanize(); // 512 MB
(1024).Gigabytes().ToString(); // 1 TB
@ নেট 3 এর সমাধানটি পছন্দ করুন। বিভাগের পরিবর্তে শিফট ব্যবহার করুন এর ব্যাপ্তি পরীক্ষা করতে bytes
, কারণ বিভাগে আরও সিপিইউ খরচ লাগে।
private static readonly string[] UNITS = new string[] { "B", "KB", "MB", "GB", "TB", "PB", "EB" };
public static string FormatSize(ulong bytes)
{
int c = 0;
for (c = 0; c < UNITS.Length; c++)
{
ulong m = (ulong)1 << ((c + 1) * 10);
if (bytes < m)
break;
}
double n = bytes / (double)((ulong)1 << (c * 10));
return string.Format("{0:0.##} {1}", n, UNITS[c]);
}
আমি ধরে নিয়েছি আপনি কি "1468006 বাইট" এর পরিবর্তে "1.4 এমবি" খুঁজছেন?
NET- এ করার জন্য অন্তর্নির্মিত উপায় আছে বলে আমি মনে করি না। আপনাকে কোন ইউনিট উপযুক্ত তা নির্ধারণ করতে হবে এবং এটি ফর্ম্যাট করতে হবে।
সম্পাদনা করুন: এখানে কিছু নমুনা কোড যা কেবল তা করতে:
কিছু পুনরাবৃত্তি সম্পর্কে:
private static string ReturnSize(double size, string sizeLabel)
{
if (size > 1024)
{
if (sizeLabel.Length == 0)
return ReturnSize(size / 1024, "KB");
else if (sizeLabel == "KB")
return ReturnSize(size / 1024, "MB");
else if (sizeLabel == "MB")
return ReturnSize(size / 1024, "GB");
else if (sizeLabel == "GB")
return ReturnSize(size / 1024, "TB");
else
return ReturnSize(size / 1024, "PB");
}
else
{
if (sizeLabel.Length > 0)
return string.Concat(size.ToString("0.00"), sizeLabel);
else
return string.Concat(size.ToString("0.00"), "Bytes");
}
}
তারপরে আপনি এটি কল করুন:
return ReturnSize(size, string.Empty);
আমার 2 সেন্ট:
string.Format(CultureInfo.CurrentCulture, "{0:0.##} {1}", fileSize, unit);
এটির মূল্য কী, তার জন্য আরও একটি পদ্ধতি আমি @ হাম্বাদকে সর্বোত্তম সমাধানটি উপরে উল্লিখিত পছন্দ করেছি, তাই নীতিটি অনুলিপি করেছি, তবে আমি এটি কিছুটা ভিন্নভাবে প্রয়োগ করেছি।
আমি মনে করি এটি একটি এক্সটেনশন পদ্ধতি হওয়া উচিত কিনা তা নিয়ে বিতর্কযোগ্য (যেহেতু সমস্ত দীর্ঘস্থায়ী আবশ্যকভাবে বাইট আকারগুলি নয়) তবে আমি সেগুলি পছন্দ করি এবং এর পরে আমার যখন প্রয়োজন হবে তখন এই পদ্ধতিটি খুঁজে পেতে পারি!
ইউনিটগুলি সম্পর্কে, আমি মনে করি না যে আমি জীবনে কখনও 'কিবিবাইট' বা 'মেবিবাইট' বলেছি, এবং আমি যখন বিকশিত মানগুলির চেয়ে এই জাতীয় প্রয়োগের বিষয়ে সন্দেহ করি, তবে আমি মনে করি এটি দীর্ঘমেয়াদে বিভ্রান্তি এড়াবে ।
public static class LongExtensions
{
private static readonly long[] numberOfBytesInUnit;
private static readonly Func<long, string>[] bytesToUnitConverters;
static LongExtensions()
{
numberOfBytesInUnit = new long[6]
{
1L << 10, // Bytes in a Kibibyte
1L << 20, // Bytes in a Mebibyte
1L << 30, // Bytes in a Gibibyte
1L << 40, // Bytes in a Tebibyte
1L << 50, // Bytes in a Pebibyte
1L << 60 // Bytes in a Exbibyte
};
// Shift the long (integer) down to 1024 times its number of units, convert to a double (real number),
// then divide to get the final number of units (units will be in the range 1 to 1023.999)
Func<long, int, string> FormatAsProportionOfUnit = (bytes, shift) => (((double)(bytes >> shift)) / 1024).ToString("0.###");
bytesToUnitConverters = new Func<long,string>[7]
{
bytes => bytes.ToString() + " B",
bytes => FormatAsProportionOfUnit(bytes, 0) + " KiB",
bytes => FormatAsProportionOfUnit(bytes, 10) + " MiB",
bytes => FormatAsProportionOfUnit(bytes, 20) + " GiB",
bytes => FormatAsProportionOfUnit(bytes, 30) + " TiB",
bytes => FormatAsProportionOfUnit(bytes, 40) + " PiB",
bytes => FormatAsProportionOfUnit(bytes, 50) + " EiB",
};
}
public static string ToReadableByteSizeString(this long bytes)
{
if (bytes < 0)
return "-" + Math.Abs(bytes).ToReadableByteSizeString();
int counter = 0;
while (counter < numberOfBytesInUnit.Length)
{
if (bytes < numberOfBytesInUnit[counter])
return bytesToUnitConverters[counter](bytes);
counter++;
}
return bytesToUnitConverters[counter](bytes);
}
}
আমি মানব পঠনযোগ্য আকারের স্ট্রিংয়ে রূপান্তর করতে নীচের লং এক্সটেনশন পদ্ধতিটি ব্যবহার করি । এই পদ্ধতিটি এখানে স্ট্যাক ওভারফ্লোতে পোস্ট করা একই প্রশ্নের জাভা সমাধানের সি # বাস্তবায়ন ।
/// <summary>
/// Convert a byte count into a human readable size string.
/// </summary>
/// <param name="bytes">The byte count.</param>
/// <param name="si">Whether or not to use SI units.</param>
/// <returns>A human readable size string.</returns>
public static string ToHumanReadableByteCount(
this long bytes
, bool si
)
{
var unit = si
? 1000
: 1024;
if (bytes < unit)
{
return $"{bytes} B";
}
var exp = (int) (Math.Log(bytes) / Math.Log(unit));
return $"{bytes / Math.Pow(unit, exp):F2} " +
$"{(si ? "kMGTPE" : "KMGTPE")[exp - 1] + (si ? string.Empty : "i")}B";
}