2012-09-06 15 views
6

Estoy escribiendo un texto en un TextWriter. Quiero que el UTF-16 Byte marca de orden (BOM) que aparece en la salida:¿Cómo se genera la orden de bytes al escribir en TextWriter?

public void ProcessRequest(HttpContext context) 
{ 
    context.Response.ContentEncoding = new UnicodeEncoding(true, true); 
    WriteStuffToTextWriter(context.Response.Output); 
} 

Excepto la salida no contiene una marca de orden de bytes:

HTTP/1.1 200 OK 
Server: ASP.NET Development Server/10.0.0.0 
Date: Thu, 06 Sep 2012 21:09:23 GMT 
X-AspNet-Version: 4.0.30319 
Content-Disposition: attachment; filename="Transactions_Calendar_20120906.csv" 
Cache-Control: private 
Content-Type: text/csv; filename="Transactions_Calendar_20120906.csv"; charset=utf-16BE 
Content-Length: 95022 
Connection: Close 

JobName,ShiftName,6////09////2012 12::::00::::00 АΜ,... 

¿Cómo le digo a un TextWriter para escribir el marcador de codificación?

Nota: El 2nd paramter in UnicodeEncoding:

context.Response.ContentEncoding = new UnicodeEncoding(true, true); 

byteOrderMark
Tipo: System.Boolean
cierto para especificar que se proporciona una marca de orden de bytes Unicode; de lo contrario, falso.

+0

¿qué es exactamente 'WriteStuffToTextWriter' es probable que tenga que especificar la codificación de allí en su' StreamWriter' –

+1

¿Qué te hace decir que no contiene una lista de materiales con el código que tienes? –

+0

Estoy con @JonHanna. Además, ¿ha intentado crear una aplicación de consola y escribir las mismas cosas directamente en un archivo y ver cómo se ve? Después de todo, un lof * stuff * ocurre entre su servidor web y su navegador. – aquinas

Respuesta

7

En algún momento me di cuenta de lo simple que es la solución.

i usé para pensar que el Unicode Byte-Order-Mark era una firma especial. Yo solía pensar que tenía que decidir cuidadosamente qué secuencia de bytes que quería de salida, con el fin de salida de la lista de materiales correcta:

  • 0xFE 0xFF
  • 0xFF 0xFE
  • 0xEF 0xBB 0xBF

Pero desde entonces me di cuenta de que Byte-Order-Mark byte es no alguna secuencia especial de bytes que debe anteponer a su archivo.

La lista de materiales es solo un carácter Unicode. Usted no genera ningún byte; solo muestra el carácter U+FEFF. El muy actúa de escribir ese personaje, el serializador lo convertirá a la codificación que esté usando para usted.

El carácter U+feff (ZERO WIDTH NO-BREAK SPACE) fue elegido por una buena razón. Es un espacio , por lo que no tiene ningún significado, y es ancho cero, por lo que ni siquiera debería verlo.

Eso significa que mi pregunta es fundamentalmente defectuosa. No existe tal como "escribir una marca de orden de bytes". Solo asegúrate de que el primer personaje que escribas sea U+FEFF.En mi caso estoy escribiendo a un TextWriter:

void WriteStuffToTextWriter(TextWriter writer) 
{ 
    String csvExport = GetExportAsCSV(); 

    writer.Write("\xfeff"); //Output unicode charcter U+FEFF as a byte order marker 
    writer.Write(csvExport); 
} 

El TextWriter se encargará de convertir el carácter Unicode U+feff en cualquier codificación de bytes que se ha configurado para utilizar.

Nota: Cualquier código se lanza al dominio público. No se requiere atribución.

0

Escriba context.Response.ContentEncoding.GetPreamble(). Eche un vistazo a Write text files without Byte Order Mark (BOM)?

+0

Sin embargo, cuidado. No estoy seguro de que en realidad ya no estén sacando una lista de materiales. Un segundo U + FEFF se interpretaría como un espacio sin pausa de ancho cero al comienzo del texto real, después de la BOM. –

0

Intenté su solución pero no funciona. En realidad, escribe la cadena \xfeff en el archivo de salida.

código

Mi Powershell es la siguiente:

System.Text.StringBuilder] $stringBuilder = New-Object System.Text.StringBuilder; 
$utf16 = new-object System.Text.UnicodeEncoding; 
[System.IO.StreamWriter] $writer = New-Object System.IO.StreamWriter("C:\dev\BPM_To_BV\BOM_Test.xml",$utf16); 
    $stringBuilder.AppendLine("\uFEFF"); 
    $stringBuilder.AppendLine("<Root>"); 
    $stringBuilder.AppendLine("</Root>"); 
    $xml = $stringBuilder.ToString(); 
    $writer.Write($xml); 
    $writer.Flush(); 
    $writer.Close(); 
+0

Esto parece ser un comentario a otra publicación. Además, su código es para PowerShell, mientras que la pregunta es sobre C#. –

+0

Tendrás que averiguar cómo escribir caracteres Unicode en PowerShell. Si es mayor que U + 0064 ('d'), U + 2020 (' † '), U + 277C (' ❼'), o U + FEFF (''). En algunos lenguajes de programación, indica una secuencia de caracteres unicode en bruto como '" \ x277c "'. En mi idioma favorito es '# $ 277C'. Tendrás que descubrir PowerShell por ti mismo. –

Cuestiones relacionadas