在Windows Server 2012 StartsWith变化 [英] StartsWith change in Windows Server 2012

查看:136
本文介绍了在Windows Server 2012 StartsWith变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:我本来以为这是涉及到.NET Framework 4.5。原来,它适用于.NET框架4.0为好。



有在字符串是如何在Windows Server 2012中,我正在试图更好地理解处理的变化。好像StartsWith的行为发生了变化。这个问题同时使用.NET框架4.0和4.5是重复的。



通过在Windows 7上的.NET Framework 4.5,低于版画假,T的节目。在Windows 2012服务器,它打印真,T代替。

 内部类节目
{
私有静态无效的主要(字串[] args)
{
串byteOrderMark = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
Console.WriteLine(测试.StartsWith(byteOrderMark));
Console.WriteLine(测试[0]);
}
}

在换句话说,StartsWith(ByteOrderMark)不管返回真字符串的内容。如果您有尝试使用下面的方法来剥去字节顺序标记代码,这个代码将正常工作在Windows 7,但将打印EST在Windows 2012

 内部类节目
{
私有静态无效的主要(字串[] args)
{
串byteOrderMark = Encoding.UTF8.GetString (Encoding.UTF8.GetPreamble());
字符串someString =测试;

如果(someString.StartsWith(byteOrderMark))
someString = someString.Substring(1);

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

}



}



我知道你已经做错了什么,如果你有一个字符串字节顺序标记,但我们正在与有这个遗留代码整合。我知道我可以做类似下面解决这一具体问题,但我想更好地理解这个问题。

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



使用UTF8Encoding的构造,它可以让我来告诉它明确地发出UTF8标识汉斯Passsant建议。我想这一点,但它给了相同的结果。下面的代码输出不同的Windows 7和Windows Server 2012之间在Windows 7上,它打印结果:假。在Windows Server 2012中它打印结果:真。

 私有静态无效的主要(字串[] args)
{
变种编码=新的UTF8Encoding(encoderShouldEmitUT​​F8Identifier:真);
串byteOrderMark = encoding.GetString(encoding.GetPreamble());
Console.WriteLine(结果:+你好.StartsWith(byteOrderMark));
Console.ReadKey();
}



我也试过以下的变体,打印假,假,假在Windows 7,但真,真,假的Windows Server 2012中,这证实它涉及到StartsWith的Windows Server 2012中的执行情况。

 私有静态无效的主要(字串[] args)
{
变种编码=新的UTF8Encoding(encoderShouldEmitUT​​F8Identifier:真);
串byteOrderMark = encoding.GetString(encoding.GetPreamble());
Console.WriteLine(你好.StartsWith(byteOrderMark));
Console.WriteLine(你好.StartsWith('\\\'.ToString()));
Console.WriteLine(你好[0] =='\\\');

Console.ReadKey();
}


解决方案

原来我的可以的摄制此,运行在Windows 8.1测试程序。它是在相同的家庭作为Server 2012的



该问题的最可能的来源是,培养敏感比较规则已经改变。它们可以是,呃,的片状的,并且对这类人物的奇怪结果。 BOM表是一个零宽度的空间。推理这一点同样需要一种精神体操作为理解为什么ABC.StartsWith()返回true:)



您需要使用StringComparison解决你的问题.Ordinal。这样就产生假,假,假:

 私有静态无效的主要(字串[] args){
变种编码=新的UTF8Encoding(encoderShouldEmitUT​​F8Identifier:真);
串byteOrderMark = encoding.GetString(encoding.GetPreamble());
Console.WriteLine(你好.StartsWith(byteOrderMark,StringComparison.Ordinal));
Console.WriteLine(你好.StartsWith(\\\,StringComparison.Ordinal));
Console.WriteLine(你好[0] =='\\\');
Console.ReadKey();
}


Edit: I originally thought this was related to .NET Framework 4.5. Turned out it applies to .NET Framework 4.0 as well.

There's a change in how strings are handled in Windows Server 2012 which I'm trying to understand better. It seems like the behavior of StartsWith has changed. The issue is reproducible using both .NET Framework 4.0 and 4.5.

With .NET Framework 4.5 on Windows 7, the program below prints "False, t". On Windows 2012 Server, it prints "True, t" instead.

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]);
   }
}

In other words, StartsWith(ByteOrderMark) returns true regardless of string content. If you have code which attempts to strip away the byte order mark using the following method, this code will work fine with on Windows 7 but will print "est" on Windows 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 realize that you have already done something wrong if you have byte order markers in a string, but we're integrating with legacy code which has this. I know I can solve this specific issue by doing something like below, but I want to understand the problem better.

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

Hans Passsant suggested using the constructor of UTF8Encoding which lets me tell it explicitly to emit UTF8 identifier. I tried this, but it gives the same result. The below code differs in output between Windows 7 and Windows Server 2012. On Windows 7, it prints "Result: False". On Windows Server 2012 it prints "Result: 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();
  }

I've also tried the following variant, which prints False, False, False on Windows 7 but True, True, False on Windows Server 2012, which confirms it's related to the implementation of StartsWith on Windows Server 2012.

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

解决方案

Turns out I could repro this, running the test program on Windows 8.1. It is in the same "family" as Server 2012.

The most likely source of the problem is that the culture sensitive comparison rules have changed. They can be, erm, flaky and can have odd outcomes on these kind of characters. The BOM is a zero-width space. Reasoning this out requires the same kind of mental gymnastics as understanding why "abc".StartsWith("") returns true :)

You need to solve your problem by using StringComparison.Ordinal. This produced False, False, False:

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

这篇关于在Windows Server 2012 StartsWith变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆