XmlTextWriterとISO-8859-1エンコーディングを使用したXMLファイルの書き込み
-
02-07-2019 - |
質問
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();
問題は、このファイルでは、ノルウェー語の文字がすべておかしいように見えることです。
おそらく、上記のことを何らかの愚かな方法で行っています。修正方法に関する提案はありますか?
解決
XMLを最初にMemoryStreamに書き込み、次に実際のファイルストリームに書き込むのはなぜですか?それはかなり非効率的です。 FileStreamに直接書き込む場合、動作するはずです。
まだ何らかの理由で二重書き込みを行いたい場合は、次のいずれかを実行します。どちらか
-
使用するStreamReaderおよびStreamWriterオブジェクトが、 all エンコードを、XmlWriterで使用したもの(StreamWriterだけでなく、他の誰かが提案した)、または
-
StreamReader / StreamWriterを使用しないでください。代わりに、単純なbyte []とStream.Read/Writeを使用して、バイトレベルでストリームをコピーするだけです。とにかく、これはとにかくずっと効率的になります。
他のヒント
エンコーディングを指定していないため、StreamWriterとStreamReaderはどちらもUTF-8を使用しています。それが物事が壊れる理由です。
tomasrが言ったように、FileStreamを使用して開始する方が簡単ですが、MemoryStreamには便利な「WriteTo」もあります。 FileStreamに簡単にコピーできるメソッドです。
実際のコードにusingステートメントがあることを願っています。書き込み中に何か問題が発生した場合、ファイルハンドルを開いたままにしないでください。
ジョン
文字列を書き込むか、バイナリデータを文字列として読み取るたびに、エンコーディングを設定する必要があります。
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();
上記の回答で述べたように、ここでの最大の問題は Encoding
です。これは指定されていないためにデフォルトになっています。
この種の変換に Encoding
を指定しない場合、デフォルトの UTF-8
が使用されます。これはシナリオに一致する場合と一致しない場合があります。また、データを MemoryStream
にプッシュしてから FileStream
に出力することにより、データを不必要に変換しています。
元のデータが UTF-8
でない場合、ここで何が起こるかは、 MemoryStream
への最初の遷移がデフォルトの Encoding
of UTF-8
-結果としてデータが破損します。その後、デフォルトで UTF-8
をエンコードとして使用している FileStream
に書き込むと、その破損がファイルに残るだけです。
問題を解決するには、 Stream
オブジェクトに Encoding
を指定する必要があります。
実際には 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();
結果ファイルの表示にはどのエンコードを使用しますか? ISO-8859-1にない場合、正しく表示されません。
たとえばUTF8ではなく、この特定のエンコードを使用する理由はありますか?
調査後、これは私にとって最も効果的でした:
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");