2013-10-21 2 views
11

편집 : 원래이 .NET Framework 4.5 관련된 생각했습니다. 그것은 .NET Framework 4.0에도 적용됩니다.시작 Windows Server 2012에서 변경

Windows Server 2012에서 문자열을 처리하는 방법이 변경되어 더 잘 이해하려고합니다. StartsWith의 동작이 변경된 것 같습니다. 이 문제는 .NET Framework 4.0 및 4.5를 사용하여 재현 할 수 있습니다.

Windows 7의 .NET Framework 4.5에서는 아래 프로그램이 "False, t"를 인쇄합니다. Windows 2012 Server에서는 대신 "True, t"를 인쇄합니다.

internal class Program 
{ 
    private static void Main(string[] args) 
    { 
     string byteOrderMark = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble()); 
     Console.WriteLine("test".StartsWith(byteOrderMark)); 
     Console.WriteLine("test"[0]); 
    } 
} 

즉, StartsWith (ByteOrderMark)는 문자열 내용에 관계없이 true를 반환합니다. 다음과 같은 방법을 사용하여 바이트 순서 표시를 벗겨을 시도 코드가있는 경우,이 코드는 윈도우 7과 잘 작동하지만 2012 년

internal class Program 
{ 
    private static void Main(string[] args) 
    { 
    string byteOrderMark = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble()); 
    string someString = "Test"; 

    if (someString.StartsWith(byteOrderMark)) 
     someString = someString.Substring(1); 

    Console.WriteLine("{0}", someString); 
    Console.ReadKey(); 

    } 

}

I Windows에서 "동부 표준시"를 인쇄합니다 문자열에 바이트 순서 마커가 있으면 이미 잘못 처리 한 것을 깨닫지 만,이를 가지고있는 레거시 코드와 통합하고 있습니다. 나는이 특정 문제를 다음과 같이함으로써 해결할 수 있다는 것을 알고 있지만 문제를 더 잘 이해하고 싶다.

someString = someString.Trim(byteOrderMark[0]); 

한스 Passsant 날 UTF8 식별자를 방출하는 명시 적으로 알려주는 기능 UTF8Encoding의 생성자를 사용하여 제안했다. 나는 이것을 시도했지만 동일한 결과를 준다. 아래 코드는 Windows 7과 Windows Server 2012 간의 출력이 다릅니다. Windows 7에서는 "결과 : False"가 인쇄됩니다. Windows Server 2012에서는 "결과 : True"를 인쇄합니다.

private static void Main(string[] args) 
    { 
    var encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: true); 
    string byteOrderMark = encoding.GetString(encoding.GetPreamble()); 
    Console.WriteLine("Result: " + "Hello".StartsWith(byteOrderMark)); 
    Console.ReadKey(); 
    } 

나는 또한이 윈도우 서버 2012 StartsWith의 이행과 관련이 확인 윈도우 서버 2012에 거짓 윈도우 7에 거짓하지만 사실, 참, 거짓 거짓 인쇄 다음과 같은 변형을,,, 해봤 .

private static void Main(string[] args) 
    { 
    var encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: true); 
    string byteOrderMark = encoding.GetString(encoding.GetPreamble()); 
    Console.WriteLine("Hello".StartsWith(byteOrderMark)); 
    Console.WriteLine("Hello".StartsWith('\ufeff'.ToString())); 
    Console.WriteLine("Hello"[0] == '\ufeff'); 

    Console.ReadKey(); 
    } 
+0

심지어'Trim'를 사용하지 것이다 - 당신이 * 첫 번째 문자에 대한 유일한 걱정하는 경우 * 그럼 그냥 확인 '여부를 텍스트 [0] =='\ ufeff '(빈 문자열을 적절히 처리하면) 충분할 것입니다. 그래도 이상하게 보입니다. –

+0

물론, 트림보다 효과적입니다. TrimStart가 잘 작동한다고 가정합니다. 아직도 나는 이것이 처음부터 왜 변했는지 이해하려고 노력하고있다. 이 사이트의 많은 응답은 StartsWith()를 먼저 확인하고 .NET Framework 4.5가 설치된 Windows Server 2012에서 실행될 때 코드가 무너질 것을 제안합니다. 예 : http://stackoverflow.com/questions/1317700/strip-byte-order-mark-from-string-in-c-sharp – Nitramk

답변

10

윈도우 8.1에서 테스트 프로그램을 실행,이 I 생식을 해제합니다. 서버 2012와 동일한 "패밀리"에 있습니다.

가장 큰 문제는 문화권 구분 비교 규칙이 변경된 것입니다. 그들은 flaky 일 수 있으며 이러한 종류의 문자에 이상한 결과가 발생할 수 있습니다. BOM은 너비가없는 공간입니다. 이것을 추측하는 것은 "abc"이유를 이해하는 것과 같은 종류의 정신적 체조가 필요합니다 .StartsWith ("")가 true를 반환합니다.

StringComparison.Ordinal을 사용하여 문제를 해결해야합니다. 이것은 거짓, 거짓, 거짓 제작 :

private static void Main(string[] args) { 
    var encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: true); 
    string byteOrderMark = encoding.GetString(encoding.GetPreamble()); 
    Console.WriteLine("Hello".StartsWith(byteOrderMark, StringComparison.Ordinal)); 
    Console.WriteLine("Hello".StartsWith("\ufeff", StringComparison.Ordinal)); 
    Console.WriteLine("Hello"[0] == '\ufeff'); 
    Console.ReadKey(); 
} 
+0

.NET Framework 4.0에서도 문제가 재현 될 수 있습니다.내 기본 게시물을 업데이트하여 제안 사항을 기반으로 새 스 니펫을 포함 시켰지만 Windows 7과 Windows Server 2012간에 다른 동작을 제공합니다. 또한 하드 코드를 추가하여 \ uffff 코드를 시작 부분에 추가하고 동작 Windows 7과 Windows 2012 Server 간에는 차이가 있습니다. 나는 이것이 이상하다는 데 동의하지만 그것은 내가보고있는 것이다. – Nitramk

+0

굉장해, 고마워! 별로 직관적이지는 않지만 이해가됩니다. – Nitramk

+0

너희들이 내 베이컨을 구해 줬어! BTW 나는 Windows Server 2012에서 간단히'문자열 byteOrderMarkUtf8 = Encoding.UTF8.GetPreamble());을 제거하고 중요한 StartsWith (byteOrderMarkUtf8, StringComparison.Ordinal)를 사용했습니다. – snark

관련 문제