Pergunta

Estou tendo problemas para escrever caracteres noruegueses em um arquivo XML usando C#. Eu tenho uma variável de string contendo algum texto norueguês (com letras como æøå).

Estou escrevendo o XML usando um XMLTextWriter, escrevendo o conteúdo em um Memorystream como este:

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

Então eu adiciono meu texto norueguês como este:

xmlTextWriter.WriteCData(myNorwegianText);

Então escrevo o arquivo para disco assim:

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();

Agora, o problema é que, no arquivo, todos os personagens noruegueses parecem engraçados.

Provavelmente estou fazendo da maneira mais estúpida. Alguma sugestão em como consertar?

Foi útil?

Solução

Por que você está escrevendo o XML primeiro em um MemoryStream e depois escrevendo isso no fluxo de arquivos real? Isso é bastante ineficiente. Se você escrever diretamente para o Filestream, ele deve funcionar.

Se você ainda quiser escrever duplo, por qualquer motivo, faça uma de duas coisas. Qualquer

  1. Certifique -se de que os objetos StreamReader e Streamwriter que você usa tudo use o mesmo codificação como o que você usou com o XMLWriter (não apenas o streamwriter, como alguém sugeriu), ou

  2. Não use StreamReader/StreamWriter. Em vez disso, basta copiar o fluxo no nível de bytes usando um byte simples [] e stream.read/write. De qualquer maneira, isso vai ser, btw, muito mais eficiente.

Outras dicas

O seu streamwriter e o streamreader estão usando o UTF-8, porque você não está especificando a codificação. É por isso que as coisas estão ficando corrompidas.

Como Tomasr disse, o uso de um FileStream para começar seria mais simples - mas também a MemoryStream possui o método útil "WritEto", que permite copiá -lo para um Filestream com muita facilidade.

Espero que você tenha uma declaração de uso em seu código real, a propósito - você não deseja deixar o identificador de arquivo aberto se algo der errado enquanto estiver escrevendo para ele.

Jon

Você precisa definir a codificação sempre que escrever uma string ou ler dados binários como uma string.

    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();

Como mencionado nas respostas acima, o maior problema aqui é o Encoding, que está sendo padronizado devido a não ser especificado.

Quando você não especifica um Encoding Para esse tipo de conversão, o padrão de UTF-8 é usado - que pode ou não corresponder ao seu cenário. Você também está convertendo os dados desnecessariamente empurrando -os para um MemoryStream e depois para um FileStream.

Se seus dados originais não forem UTF-8, o que acontecerá aqui é que a primeira transição para o MemoryStream tentará decodificar usando o padrão Encoding do UTF-8 - e corrompe seus dados como resultado. Quando você então escreve para o FileStream, que também está usando UTF-8 Como codificação por padrão, você simplesmente persiste essa corrupção no arquivo.

Para corrigir o problema, você provavelmente precisa especificar Encoding dentro de voce Stream objetos.

Você pode realmente pular o MemoryStream Processo inteiramente, também - que será mais rápido e mais eficiente. Seu código atualizado pode parecer algo mais como:

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();

Qual codificação você usa para exibir o arquivo de resultado? Se não estiver no ISO-8859-1, não será exibido corretamente.

Existe uma razão para usar essa codificação específica, em vez de, por exemplo, UTF8?

Depois de investigar, isso funcionou melhor para mim:

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");
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top