Если вы не хотите отслеживать культуру, в которую были записаны ваши файлы, то, как вы подразумеваете, используйте один и тот же формат для чисел независимо от культуры. Для достижения этой цели вы можете использовать функции, которые принимают IFormatProvider в качестве параметра. Эти функции включают (но не ограничиваются ими) Parse, TryParse и ToString для большинства типов данных. Таким образом, вам не нужно менять культуру вашей темы, но вы все равно можете читать или писать в другой культуре.
// Simulated file containing one number per line in en-US culture
string file = "2.3\n3.5\n5.7";
// Assumed that files all use en-US culture for numbers
System.Globalization.NumberFormatInfo numberFormat = CultureInfo.GetCultureInfo("en-US").NumberFormat;
foreach (string line in file.Split('\n'))
{
// Parse en-US string to double
double number = double.Parse(line, numberFormat);
// Debugging/Logging using thread's current culture
Debug.WriteLine(number.ToString("F1"));
// Write to console or possibly another file in en-US culture
Console.WriteLine(number.ToString("F1", numberFormat));
}
Однако, если вы обычно пишете плоские файлы в нескольких культурах, вам действительно следует пометить их той культурой, в которой они были написаны, будь то в имени файла или в заголовке файла. Таким образом, вы можете импортировать в зависимости от культуры файла. Это стандартная практика для файлов любого типа с несколькими кодировками.
Это также может быть полезно, если файлы читаемы человеком, таким образом, сохраняя то, что ожидает увидеть каждая культура, вместо того, чтобы выбирать одну культуру и заставлять всех остальных соответствовать ей.
Идея остается неизменной при использовании функций, которые принимают параметр IFormatProvider, таких как следующие:
public static void Main(string[] args)
{
// Simulated file containing one number per line in fr-CA culture
MemoryStream inputStream = new MemoryStream();
StreamWriter writer = new StreamWriter(inputStream);
writer.WriteLine("2,3");
writer.WriteLine("3,5");
writer.WriteLine("5,7");
writer.Flush();
inputStream.Seek(0, SeekOrigin.Begin);
// Simulated output file that we want in en-CA culture
MemoryStream outputStream = new MemoryStream();
Convert(inputStream, CultureInfo.GetCultureInfo("fr-CA"), outputStream, CultureInfo.GetCultureInfo("en-CA"));
// Print output file
outputStream.Seek(0, SeekOrigin.Begin);
StreamReader reader = new StreamReader(outputStream);
string line;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
public static void Convert(Stream inputStream, CultureInfo inputCulture, Stream outputStream, CultureInfo outputCulture)
{
// Get number format for input and output cultures
NumberFormatInfo inputNumberFormat = inputCulture.NumberFormat;
NumberFormatInfo outputNumberFormat = outputCulture.NumberFormat;
// Setup reader and writer for input and output streams
StreamReader reader = new StreamReader(inputStream);
StreamWriter writer = new StreamWriter(outputStream);
// Read each line of input stream and write to output stream, while preserving culture of thread, input, and output
string line;
while ((line = reader.ReadLine()) != null)
{
// Parse string from input stream to double using input culture
double number = double.Parse(line, inputNumberFormat);
// Debugging/Logging using thread's current culture
Debug.WriteLine(number.ToString("F1"));
// Write double to output stream using output culture
writer.WriteLine(number.ToString("F1", outputNumberFormat));
}
writer.Flush();
}
Я понимаю, что этот вопрос был задан некоторое время назад, и оригинальному постеру это может даже не понадобиться, но я также не вижу приемлемых ответов. И поскольку у меня была проблема, аналогичная проблеме оригинального плаката, я решил опубликовать ответ, который обнаружил.