C# 写入平面文件US区域性,是否将程序集加载到不同的区域性中

C# 写入平面文件US区域性,是否将程序集加载到不同的区域性中,c#,localization,culture,C#,Localization,Culture,我有一个类库,它读取从Delphi遗留应用程序编写的平面文件,然后处理数据并写回平面文件 当用户有不同的操作系统文化时,问题就来了,我们也本地化了dll,将本地化字符串写入平面文件 当我们根据文化(即1,60而不是1.60)编写双阀门时,问题就出现了。由于遗留应用程序使用“,”作为分隔符,我们无法写入1,60 在美国文化中,有没有一种方式可以让我们写下双重价值观 同时,我们正在将Delphi应用程序转换为C#。我在想,让一个有罗马尼亚文化的人创建一个文件,该文件的双倍值为1,25,当它被发送到一

我有一个类库,它读取从Delphi遗留应用程序编写的平面文件,然后处理数据并写回平面文件

当用户有不同的操作系统文化时,问题就来了,我们也本地化了dll,将本地化字符串写入平面文件

当我们根据文化(即1,60而不是1.60)编写双阀门时,问题就出现了。由于遗留应用程序使用“,”作为分隔符,我们无法写入1,60

在美国文化中,有没有一种方式可以让我们写下双重价值观


同时,我们正在将Delphi应用程序转换为C#。我在想,让一个有罗马尼亚文化的人创建一个文件,该文件的双倍值为1,25,当它被发送到一个美国文化的人时,他的大会期望值为1.25,所以在尝试从字符串转换为双倍值时,会崩溃。因此,在这种情况下,始终从En-US区域性文件中进行写入和读取也会有所帮助,大家怎么说?

您可以设置当前线程的本地化,以便它将遵循您选择的本地化规则

使用以下命令:

Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");

如果您不想跟踪文件编写的区域性,那么您可以选择在文件中使用统一格式来表示数字,而不考虑区域性。要实现此目标,可以使用接受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();
}

我意识到这个问题很久以前就被问过了,原来的海报可能不再需要这个了,但我也看不到任何可以接受的答案。由于我遇到了与原始海报问题类似的问题,我想我应该发布我发现的答案。

这就是我的想法,但在编写输出文件时,我还编写了一个日志文件,指出对该文件所做的更改,并且该日志必须本地化。因此,设置整个线程的文化是行不通的。我所想的是,将为double-like(number.ToString(“c”,new CultureInfo(“En-US”));)创建一个扩展方法ToString,因此当我将要写入平面文件时,我将使用double.ToString(),当writind to log时,将使用double.ToString()。你所说的……这种方法将非常缺乏活力,如果另一个国家加入俱乐部会发生什么:)所以我将在美国文化中记录文件,并在美国写作。其他的一切都是一样的same@Mohit:我的理解正确吗?当你写文件的时候,你也写日志文件,两个写过程都可以在不同的文化中完成?@Roy T:是的,我知道这是非动态的。但当我面对这样的问题时,我找到了我所写的解决方案。你有不同的建议吗?
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();
}