Convertissez «1,5 To», «500 Mo» en une seule unité de taille de fichier

Je souhaite autoriser un utilisateur à entrer une taille de fichier à l’aide de l’un des suffixes standard (tels que To, Mo, Go)

Je voudrais obtenir la valeur d’une manière que je puisse les comparer à une taille de dossier.

L’idée est d’avoir un programme qui préviendra si un dossier dépasse une certaine taille, la taille étant dictée par une chaîne entrée par l’utilisateur.

Le framework .net 400GB -il quelque chose qui me permette d’parsingr des chaînes telles que 400GB , 1.9GB 400GB , 1.9GB et 0.5KB ?

C’est un bon candidat pour un interprète simple.

Un tel code est un début simple, vous devrez peut-être gérer plus de cas et prendre en compte les différences de casse ( Gb vs GB par exemple).

Vous commencez avec une définition pour un contexte et une expression:

 public class FileSizeContext { private ssortingng input; private long output; public FileSizeContext(ssortingng input) { this.Input = input; } public ssortingng Input { get; set; } public long Output { get; set; } } public abstract class FileSizeExpression { public abstract void Interpret(FileSizeContext value); } 

Ensuite, vous définissez votre expression de terminal et toutes les variantes:

 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(),Ssortingng.Empty)); var fileSize = (long)(amount*1024); value.Input = Ssortingng.Format("{0}{1}",fileSize,this.NextPattern()); value.Output = fileSize; } } protected abstract ssortingng ThisPattern(); protected abstract ssortingng NextPattern(); } public class KbFileSizeExpression : TerminalFileSizeExpression { protected override ssortingng ThisPattern(){return "KB";} protected override ssortingng NextPattern() { return "bytes"; } } public class MbFileSizeExpression : TerminalFileSizeExpression { protected override ssortingng ThisPattern() { return "MB"; } protected override ssortingng NextPattern() { return "KB"; } } public class GbFileSizeExpression : TerminalFileSizeExpression { protected override ssortingng ThisPattern() { return "GB"; } protected override ssortingng NextPattern() { return "MB"; } } public class TbFileSizeExpression : TerminalFileSizeExpression { protected override ssortingng ThisPattern() { return "TB"; } protected override ssortingng NextPattern() { return "GB"; } } 

Ensuite, vous ajoutez une expression non-terminale (ceci représente la majeure partie du travail):

 public class FileSizeParser : FileSizeExpression { private List expressionTree = new List() { new TbFileSizeExpression(), new GbFileSizeExpression(), new MbFileSizeExpression(), new KbFileSizeExpression() }; public override void Interpret(FileSizeContext value) { foreach (FileSizeExpression exp in expressionTree) { exp.Interpret(value); } } } 

Enfin, voici le type de code client:

 var ctx = new FileSizeContext("10Mb"); var parser = new FileSizeParser(); parser.Interpret(ctx); Console.WriteLine("{0} bytes", ctx.Output); // 10485760 bytes 

Exemple en direct: http://rextester.com/rundotnet?code=WMGOQ13650

Modifications. Changé en Mo à partir de Mo (l’un est officiellement MegaByte, l’autre est MegaBit). Modifié en long pour tenir compte des grandes tailles.

Réponse courte: non, il n’y a pas de méthode intégrée.

Réponse longue: utilisez mon convertisseur.

 public class FileSizeConverter { private static System.Globalization.NumberFormatInfo numberFormat; private static Dictionary knownUnits; static FileSizeConverter() { knownUnits = new Dictionary { { "", 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(ssortingng value) { // ignore spaces around the actual value value = value.Trim(); ssortingng unit = ExtractUnit(value); ssortingng sizeAsSsortingng = value.Subssortingng(0, value.Length - unit.Length).Trim(); // sortingm spaces long multiplicator = MultiplicatorForUnit(unit); decimal size; if (!decimal.TryParse(sizeAsSsortingng, 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 ssortingng ExtractUnit(ssortingng 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 : voici une démonstration en direct: http://rextester.com/rundotnet?code=BQYCB2587 (merci @Jamiec pour le lien, très pratique pour exécuter une source C # en ligne)

Je ne pouvais pas trouver une telle fonctionnalité dans le .NET Framework avec une recherche rapide dans Google, alors je suppose que c’est à vous de la mettre en œuvre.

Je pense que scinder la chaîne en valeurs numériques et un point (ou une virgule, penser international) en tant que première partie et extraire le KB / MB / etc en tant que deuxième partie et parsingr chaque partie manuellement sera la meilleure solution.