Как сохранить текстовый файл в нужной кодировке?

140
18 января 2019, 03:50

Как известно строки в С# все в Unicode. Как сохранить текстовый файл в нужной кодировке ?

Вот такой пример:

static void Main(string[] args)
{
    string file = @"C:\Temp\test.txt";
    string[] str = { "первая строка", "вторая строка", "последняя строка" };
    using (StreamWriter writer = new StreamWriter(new FileStream(file, FileMode.OpenOrCreate), Encoding.ASCII))
    {
        foreach (string row in str)
        {
            writer.WriteLine(row);
        }
    }
}

Создает файл, но с кодировкой проблемы, она точно не ASCII. Первая мысль, нужно строки преобразовать в ASCII перед записью. отлично, беру пример с MSDN, получается так:

static void Main(string[] args)
{
    string file = @"C:\Temp\test.txt";
    string[] str = { "первая строка", "вторая строка", "последняя строка" };
    using (StreamWriter writer = new StreamWriter(new FileStream(file, FileMode.OpenOrCreate), Encoding.ASCII))
    {
        foreach (string row in str)
        {
            writer.WriteLine(UnocodeToASCII(row));
        }
    }
}
private static string UnocodeToASCII(string source)
{
    // Create two different encodings.
    Encoding ascii = Encoding.ASCII;
    Encoding unicode = Encoding.Unicode;
    // Convert the string into a byte array.
    byte[] unicodeBytes = unicode.GetBytes(source);
    // Perform the conversion from one encoding to the other.
    byte[] asciiBytes = Encoding.Convert(unicode, ascii, unicodeBytes);
    // Convert the new byte[] into a char[] and then into a string.
    char[] asciiChars = new char[ascii.GetCharCount(asciiBytes, 0, asciiBytes.Length)];
    ascii.GetChars(asciiBytes, 0, asciiBytes.Length, asciiChars, 0);
    return new string(asciiChars);
}

На выходе тоже файл с непонятной кодировкой. что не я делаю не так?

Answer 1

Ваш код сохранения в ASCII работает правильно - он сохраняет русские символы как ?, т.к. в ASCII кодировке русских букв нет. Скоре всего вы хотите сохранить в 1251:

static void Main(string[] args)
{
    string file = @"C:\Temp\test.txt";
    string[] str = { "первая строка", "вторая строка", "последняя строка" };
    using (StreamWriter writer = new StreamWriter(new FileStream(file, FileMode.OpenOrCreate), Encoding.GetEncoding(1251)))
    {
        foreach (string row in str)
        {
            writer.WriteLine(row);
        }
    }
}

То же самое можно сделать одной строчкой:

File.WriteAllLines(file, str, Encoding.GetEncoding(1251));

Перекодировку, так, как вы делаете во втором примере, делать нельзя. Во первых, она пытается прочитать байты строки в Unicode как байты строки в ASCII. Во второых, такой код применим только в случае, если:

  • У вас уже битая строка - она была прочитана из байт с указанием неверной кодировки
  • Код, который ее читает с неверной кодировкой, исправить нельзя

Во всех остальных случаях нужно просто указывать кодировку в момент преобразования из строки в байты при записи и при обратном чтении.

READ ALSO
Управление компьютером через командную строку C#

Управление компьютером через командную строку C#

Возникла идея сделать управление компьютером через телефонУправлять планирую с помощью командной строки, то есть на телефоне сделать импровизированый...

115
Проблемы с Rigidbody, Unity

Проблемы с Rigidbody, Unity

Rigidbody ведёт себя неадекватно при трении об коллайдерНесколько секунд двигаемся, прикасаясь к коллайдеру, потом то, что мы двигаем, дёргает...

133
Как подключить MS SQL к Unity

Как подключить MS SQL к Unity

При создании скрипта в Юнити, а потом загрузке в VS Когда пытаюсь подключить библиотеки SystemData

164