转换为1.5TB", &;500MB"转换为文件大小的单个单位
本文关键字:转换 quot 单个 单位 文件大小 5TB 500MB | 更新日期: 2023-09-27 18:08:04
我想允许用户输入文件大小,使用任何标准后缀(如TB, MB, GB)
我想以一种可以将它们与文件夹大小进行比较的方式获得值。
这个想法是有一个程序,当一个文件夹超过一定的大小时,它会发出警告,而这个大小是由用户输入的字符串决定的。
是否有任何内置到。net框架,允许我解析字符串,如1.5TB
, 400GB
, 1.9GB
和0.5KB
?
这是一个很好的简单解释器候选。
像这样的代码是一个简单的开始,你可能需要处理更多的情况,并考虑大小写的差异(例如Gb
和GB
)。
从上下文和表达式的定义开始:
public class FileSizeContext
{
private string input;
private long output;
public FileSizeContext(string input)
{
this.Input = input;
}
public string Input { get; set; }
public long Output { get; set; }
}
public abstract class FileSizeExpression
{
public abstract void Interpret(FileSizeContext value);
}
然后定义你的终端表达式,a和所有的变体:
public abstract class TerminalFileSizeExpression : FileSizeExpression
{
public override void Interpret(FileSizeContext value)
{
if(value.Input.EndsWith(this.ThisPattern()))
{
double amount = double.Parse(value.Input.Replace(this.ThisPattern(),String.Empty));
var fileSize = (long)(amount*1024);
value.Input = String.Format("{0}{1}",fileSize,this.NextPattern());
value.Output = fileSize;
}
}
protected abstract string ThisPattern();
protected abstract string NextPattern();
}
public class KbFileSizeExpression : TerminalFileSizeExpression
{
protected override string ThisPattern(){return "KB";}
protected override string NextPattern() { return "bytes"; }
}
public class MbFileSizeExpression : TerminalFileSizeExpression
{
protected override string ThisPattern() { return "MB"; }
protected override string NextPattern() { return "KB"; }
}
public class GbFileSizeExpression : TerminalFileSizeExpression
{
protected override string ThisPattern() { return "GB"; }
protected override string NextPattern() { return "MB"; }
}
public class TbFileSizeExpression : TerminalFileSizeExpression
{
protected override string ThisPattern() { return "TB"; }
protected override string NextPattern() { return "GB"; }
}
然后添加一个非终结符表达式(这完成了大部分工作):
public class FileSizeParser : FileSizeExpression
{
private List<FileSizeExpression> expressionTree = new List<FileSizeExpression>()
{
new TbFileSizeExpression(),
new GbFileSizeExpression(),
new MbFileSizeExpression(),
new KbFileSizeExpression()
};
public override void Interpret(FileSizeContext value)
{
foreach (FileSizeExpression exp in expressionTree)
{
exp.Interpret(value);
}
}
}
最后,下面是客户端代码:
var ctx = new FileSizeContext("10Mb");
var parser = new FileSizeParser();
parser.Interpret(ctx);
Console.WriteLine("{0} bytes", ctx.Output); // 10485760 bytes
实例:http://rextester.com/rundotnet?code=WMGOQ13650
编辑。由MB改为MB(一个是兆字节,另一个是兆比特)。
简短的回答:没有,没有内置的方法。
长话短说:用我的转换器。
public class FileSizeConverter
{
private static System.Globalization.NumberFormatInfo numberFormat;
private static Dictionary<string, long> knownUnits;
static FileSizeConverter()
{
knownUnits = new Dictionary<string, long>
{
{ "", 1L }, // no unit is same as unit B(yte)
{ "B", 1L },
{ "KB", 1024L },
{ "MB", 1024L * 1024L},
{ "GB", 1024L * 1024L * 1024L},
{ "TB", 1024L * 1024L * 1024L * 1024L}
// fill rest as needed
};
// since I live in a locale where "," is the decimal separator I will enforce US number format
numberFormat = new System.Globalization.CultureInfo("en-US").NumberFormat;
}
public long Parse(string value)
{
// ignore spaces around the actual value
value = value.Trim();
string unit = ExtractUnit(value);
string sizeAsString = value.Substring(0, value.Length - unit.Length).Trim(); // trim spaces
long multiplicator = MultiplicatorForUnit(unit);
decimal size;
if (!decimal.TryParse(sizeAsString, System.Globalization.NumberStyles.Number, numberFormat, out size))
throw new ArgumentException("illegal number", "value");
return (long)(multiplicator * size);
}
private bool IsDigit(char value)
{
// we don't want to use char.IsDigit since it would accept esoterical unicode digits
if (value < '0') return false;
if (value > '9') return false;
return true;
}
private string ExtractUnit(string sizeWithUnit)
{
// start right, end at the first digit
int lastChar = sizeWithUnit.Length-1;
int unitLength = 0;
while (unitLength <= lastChar
&& sizeWithUnit[lastChar - unitLength] != ' ' // stop when a space
&& !IsDigit(sizeWithUnit[lastChar - unitLength])) // or digit is found
{
unitLength++;
}
return sizeWithUnit.Substring(sizeWithUnit.Length - unitLength).ToUpperInvariant();
}
private long MultiplicatorForUnit(string unit)
{
unit = unit.ToUpperInvariant();
if (!knownUnits.ContainsKey(unit))
throw new ArgumentException("illegal or unknown unit", "unit");
return knownUnits[unit];
}
}
EDIT:这里是现场演示:http://rextester.com/rundotnet?code=BQYCB2587(感谢@Jamiec提供的链接,非常方便在线运行c#源代码)
我在。net框架中找不到这样的功能,所以我想这取决于你来实现它。
我认为分割字符串的数值和点(或逗号,认为国际)作为第一部分,提取KB/MB等作为第二部分,并手动解析每个部分将是可行的方法。