2010-12-10 2 views
37

C#에서 내 asp.net mvc 2 응용 프로그램에서 UTF8 인코딩 문제가 있습니다. 나는 사용자가 문자열에서 간단한 텍스트 파일을 다운로드하도록하고있다. 나는 다음 행으로 바이트 배열을 얻기 위해 노력하고 있어요 :BOM을 사용하여 UTF8 인코딩을 사용하여 C#에서 GetBytes()를 만드는 방법은 무엇입니까?

var x = Encoding.UTF8.GetBytes(csvString);

하지만 다운로드를 반환 할 때 사용 : return File(x, ..., ...);

나는 그렇게 BOM없이 내가 돈있는 파일을 얻을 크로아티아 문자가 제대로 표시되지 않습니다. 왜냐하면 내 바이트 배열 인코딩 후 BOM을 포함하지 않기 때문입니다. 나는 그 바이트들을 수동으로 삽입하는 것을 우연히 만난다. 그리고 나서 그것은 올바르게 나타난다. 그러나 그것을하는 가장 좋은 방법은 아니다.

또한 UTF8Encoding 클래스 인스턴스를 생성하고 BOM을 포함하도록 생성자에 부울 값 (true)을 전달하려고 시도했지만 작동하지 않습니다.

누구나 해결책이 있습니까? 감사! 이 같은

답변

91

시도 :

public ActionResult Download() 
{ 
    var data = Encoding.UTF8.GetBytes("some data"); 
    var result = Encoding.UTF8.GetPreamble().Concat(data).ToArray(); 
    return File(result, "application/csv", "foo.csv"); 
} 

이유는 당신이 무엇을 기대 부울 매개 변수를 취하는 UTF8Encoding 생성자는하지 않는다는 것입니다 :

byte[] bytes = new UTF8Encoding(true).GetBytes("a"); 

결과 배열은 단일 포함됩니다 바이트 값은 97입니다. UTF8에는 BOM이 필요하지 않으므로 BOM이 없습니다.

+1

매력처럼 작동합니다. 감사합니다. :) –

+2

고마워요! Excel CSV에서 작동하지 않는 특수 문자로 인해 미쳐 버렸습니다. –

+1

명확성을 위해 'Encoding.UTF8'은'new UTF8Encoding (true)'과 동일합니다. 이 매개 변수는'GetPreamble()'이 BOM을 방출할지 여부를 제어합니다. – Stijn

2

UTF-8은 1 바이트 단어 시퀀스이므로 BOM이 필요하지 않습니다. UTF-8 = UTF-8BE = UTF-8LE.

대조적으로 UTF-16은 2 바이트 단어의 시퀀스이고 스트림의 나머지 부분이 UTF-16BE인지 UTF-16LE인지 식별하기 위해 스트림 시작 부분에 BOM이 필요합니다. BOM은 단어의 바이트가 BE인지 LE인지 식별합니다.

이 문제는 Encoding.UTF8 클래스와 관련이 없습니다. 문제는 파일을 보는 데 사용하는 프로그램에 달려 있습니다.

+1

UTF-8은 가변 폭 인코딩입니다. ASCII 문자를 인코딩하는 데 1 바이트 만 필요하지만 다른 코드 포인트는 여러 바이트를 사용합니다. –

+2

여러 바이트로 인코딩 된 코드 포인트는 미리 정의 된 순서를 갖습니다 ('U +'빅 엔디안 표현에 기반 함). 그러나 UTF8은 바이트 스트림으로 표현되기 때문에 엔디안 개념이 적용되지 않습니다. 엔디안은 바이트로 코드 포인트를 표현하는 것이 아니라 바이트로 16, 32, 64, 128 비트 정수를 표현하는 데 적용 할 수 있습니다. – yfeldblum

+0

죄송합니다. "시퀀스가 1 바이트 단어"라는 문구가 포함 된 코드 포인트 저장소를 말하는 것으로 알고 있습니다. 해명 해줘서 고마워. 당신의 대답과 코멘트 +1. –

-1

메모리에있는 동안 .NET 문자열은 모두 유니 코드이므로 디버거로 csvString을 올바르게 볼 수 있으면 파일을 쓰는 데 문제가 있다는 것을 기억하십시오.

내 생각에 파일과 동일한 인코딩으로 FileResult을 반환해야합니다.

public static class StreamExtensions 
{ 
    public static byte[] ToBytes(this string value, Encoding encoding) 
    { 
     using (var stream = new MemoryStream()) 
     using (var sw = new StreamWriter(stream, encoding)) 
     { 
      sw.Write(value); 
      sw.Flush(); 
      return stream.ToArray(); 
     } 
    } 
} 

사용법 :

가 파일 또는 스트림에 기입 할 때 반환 파일 인코딩을 설정해보십시오,
4

나는 바이트 배열의 그것의 표현에 대한 인코딩 문자열로 변환하는 간단한 확장을 생성
stringValue.ToBytes(Encoding.UTF8) 

이것은 BOM이 필요한 UTF-16과 같은 다른 인코딩에도 적용됩니다.

+0

이것은 실제로 매우 유용한 해결 방법입니다. 인코딩과 함께 'StreamWriter'를 사용하면 즉각적인 문제가 해결되고 Excel 2013에서 파일을 열 수있었습니다. –

관련 문제