C # - Обнаружение кодировки в файле, записать изменения в файл, используя найденную кодировку - PullRequest
10 голосов
/ 08 декабря 2010

Я написал небольшую программу для перебора большого количества файлов и внесения некоторых изменений, когда найдено определенное совпадение строк, у меня проблема в том, что разные файлы имеют разные кодировки.Поэтому я хотел бы проверить кодировку, а затем перезаписать файл в его исходной кодировке.

Какой самый красивый способ сделать это в C # .net 2.0?

Мой кодна данный момент выглядит очень просто;

String f1 = File.ReadAllText(fileList[i]).ToLower();

if (f1.Contains(oPath))
{
    f1 = f1.Replace(oPath, nPath);
    File.WriteAllText(fileList[i], f1, Encoding.Unicode);
}

Я посмотрел на Автоматическое обнаружение кодирования в C # , которое заставило меня понять, как я могу обнаружить кодирование, но я не уверен, как я могиспользуйте эту информацию для записи в той же кодировке.

Буду очень признателен за любую помощь здесь.

Ответы [ 4 ]

16 голосов
/ 08 декабря 2010

К сожалению, кодирование - одна из тех тем, где не всегда есть однозначный ответ.Во многих случаях это гораздо ближе к угадыванию кодировки, чем к ее обнаружению.Рэймонд Чен сделал отличную запись в блоге на эту тему, которую стоит прочесть* Если спецификация (маркер порядка следования байтов) существует, значит, вы золотыевы связаныПозвольте StreamReader угадать для вас против повторного изобретения колеса.Требуется лишь очень небольшая модификация вашего образца.

String f1;
Encoding encoding;
using (var reader = new StreamReader(fileList[i])) {
  f1 = reader.ReadToEnd().ToLower();
  encoding = reader.CurrentEncoding;
}

if (f1.Contains(oPath))
{
  f1 = f1.Replace(oPath, nPath);
  File.WriteAllText(fileList[i], f1, encoding);
}
2 голосов
/ 08 декабря 2010

По умолчанию .Net использует UTF8. Трудно обнаружить кодировку символов, потому что большую часть времени .Net будет читать как UTF8. У меня всегда есть проблема с ANSI.

Мой трюк в том, что я буду читать файл как поток, так как заставлю его читать как UTF8 и обнаружу обычный символ, который должен быть в тексте. Если найдено, то UTF8 еще ANSI ... и сказать пользователю, что вы можете использовать только 2 кодировки: ANSI или UTF8. автоопределение не совсем работает на моем языке: p

1 голос
/ 08 декабря 2010

Боюсь, вам нужно знать кодировку. Для кодировок на основе UTF вы можете использовать встроенную функциональность StreamReader.

Принятая форма здесь .

Что касается кодировок - вы будете необходимо определить кодировку для использования StreamReader.

Однако сам StreamReader может помочь, если вы создаете его с одним из перегрузки конструктора, что позволяет поставить флаг обнаружитьEncodingFromByteOrderMarks как правда (или вы можете использовать Encoding.GetPreamble и посмотрите на байтная преамбула самостоятельно).

Оба эти метода помогут только хотя автоопределение кодировки на основе UTF - поэтому любые кодировки ANSI с указанной кодовой страницей, вероятно, не быть разобран правильно.

0 голосов
/ 10 сентября 2013

Возможно, немного поздно, но я сам столкнулся с той же проблемой, используя предыдущие ответы. Я нашел решение, которое подходит мне вернемся с изменениями, используя найденную кодировку. Также удаляет \ повторно добавляет флаг ReadOnly

        string file = "File to open";
        string text;
        Encoding encoding;
        string oldValue = "string to be replaced";
        string replacementValue = "New string";

        var attributes = File.GetAttributes(file);
        File.SetAttributes(file, attributes & ~FileAttributes.ReadOnly);

        using (StreamReader reader = new StreamReader(file, Encoding.Default))
        {
            text = reader.ReadToEnd();
            encoding = reader.CurrentEncoding;
            reader.Close();
        }

        bool changedValue = false;
        if (text.Contains(oldValue))
        {
            text = text.Replace(oldValue, replacementValue);
            changedValue = true;
        }

        if (changedValue)
        {
            using (StreamWriter write = new StreamWriter(file, false, encoding))
            {
                write.Write(text.ToString());
                write.Close();
            }
            File.SetAttributes(file, attributes | FileAttributes.ReadOnly);
        }
...