web-dev-qa-db-ja.com

ISO-8859-1エンコーディングでXmlTextWriterを使用してXMLファイルを書き込む

C#を使用してノルウェー語の文字をXMLファイルに書き込む際に問題が発生しました。ノルウェー語のテキスト(æøåなどの文字)を含む文字列変数があります。

XmlTextWriterを使用してXMLを記述し、次のようにコンテンツをMemoryStreamに書き込みます。

MemoryStream stream = new MemoryStream();
XmlTextWriter xmlTextWriter = new XmlTextWriter(stream, Encoding.GetEncoding("ISO-8859-1"));
xmlTextWriter.Formatting = Formatting.Indented;
xmlTextWriter.WriteStartDocument(); //Start doc

次に、ノルウェー語のテキストを次のように追加します。

xmlTextWriter.WriteCData(myNorwegianText);

次に、次のようにファイルをディスクに書き込みます。

FileStream myFile = new FileStream(myPath, FileMode.Create);
StreamWriter sw = new StreamWriter(myFile);

stream.Position = 0;
StreamReader sr = new StreamReader(stream);
string content = sr.ReadToEnd();

sw.Write(content);
sw.Flush();

myFile.Flush();
myFile.Close();

問題は、これに関するファイルでは、すべてのノルウェー語の文字がおかしいように見えることです。

私はおそらく上記を愚かな方法でやっています。それを修正する方法について何か提案はありますか?

17
henningst

XMLを最初にMemoryStreamに書き込み、次にそれを実際のファイルストリームに書き込むのはなぜですか?それはかなり非効率的です。 FileStreamに直接書き込む場合は、機能するはずです。

それでも二重書き込みを実行したい場合は、何らかの理由で、次の2つのいずれかを実行します。どちらか

  1. 使用するStreamReaderオブジェクトとStreamWriterオブジェクトallsameを使用していることを確認してくださいXmlWriterで使用したものとしてエンコードする(他の誰かが提案したように、StreamWriterだけでなく)、または

  2. StreamReader/StreamWriterを使用しないでください。代わりに、単純なbyte []とStream.Read/ Writeを使用して、バイトレベルでストリームをコピーするだけです。とにかく、これははるかに効率的になるでしょう。

13
tomasr

文字列を書き込んだり、バイナリデータを文字列として読み取るたびに、エンコーディングを設定する必要があります。

    Encoding encoding = Encoding.GetEncoding("ISO-8859-1");

    FileStream myFile = new FileStream(myPath, FileMode.Create);
    StreamWriter sw = new StreamWriter(myFile, encoding);

    stream.Position = 0;
    StreamReader sr = new StreamReader(stream, encoding);
    string content = sr.ReadToEnd();

    sw.Write(content);
    sw.Flush();

    myFile.Flush();
    myFile.Close();
8
Thomas Danecker

上記の回答で述べたように、ここでの最大の問題はEncodingです。これは、指定されていないためにデフォルトになっています。

この種の変換にEncodingを指定しない場合、デフォルトのUTF-8が使用されます。これは、シナリオに一致する場合と一致しない場合があります。また、データをMemoryStreamにプッシュしてから、FileStreamにプッシュすることにより、データを不必要に変換しています。

元のデータがUTF-8でない場合、ここで発生するのは、MemoryStreamへの最初の遷移がUTF-8のデフォルトのEncodingを使用してデコードを試みて破損することです。結果としてあなたのデータ。次に、デフォルトでエンコードとしてUTF-8も使用しているFileStreamに書き出すと、その破損をファイルに保持するだけです。

この問題を修正するには、EncodingオブジェクトにStreamを指定する必要があります。

実際には、MemoryStreamプロセスを完全にスキップすることもできます。これにより、より高速で効率的になります。更新されたコードは次のようになります。

FileStream fs = new FileStream(myPath, FileMode.Create);

XmlTextWriter xmlTextWriter = 
    new XmlTextWriter(fs, Encoding.GetEncoding("ISO-8859-1"));

xmlTextWriter.Formatting = Formatting.Indented;
xmlTextWriter.WriteStartDocument(); //Start doc

xmlTextWriter.WriteCData(myNorwegianText);

StreamWriter sw = new StreamWriter(fs);

fs.Position = 0;
StreamReader sr = new StreamReader(fs);
string content = sr.ReadToEnd();

sw.Write(content);
sw.Flush();

fs.Flush();
fs.Close();
5
Troy Alford

結果ファイルを表示するためにどのエンコーディングを使用しますか? ISO-8859-1にない場合、正しく表示されません。

たとえばUTF8の代わりに、この特定のエンコーディングを使用する理由はありますか?

3
Treb

調査した後、これは私にとって最もうまくいったことです:

var doc = new XDocument(new XDeclaration("1.0", "ISO-8859-1", ""));
        using (XmlWriter writer = doc.CreateWriter()){
            writer.WriteStartDocument();
            writer.WriteStartElement("Root");
            writer.WriteElementString("Foo", "value");
            writer.WriteEndElement();
            writer.WriteEndDocument();
        }
        doc.Save("dte.xml");
0
mauro.Joestar