读书笔记—CLR via C#字符串及文本
前言
这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可以加深自己理解的深度,当然同时也和技术社区的朋友们共享
字符(System.Char)
- 字符在.NET 中表示成16位Unicode代码值
 - System.Char.MinValue = '\0' MaxValue = '\uffff'
 - 实例方法GetUnicodeCategory,返回System.Globalization.UnicodeCategory枚举(包含控制字符、货币符号、小写字母、大些字母、标点符号、数学符号或者其他由Unicode定义的字符)
 - 简化接口为IsDigit, IsLetter, IsUpper, IsLower, IsPunctuation, IsLetterOrDigit, IsControl, IsNumber, IsSeparator, IsSurrogate等
 - 以上Is简化接口内部都调用GetUnicodeCategory,并简单返回true或false
 - ToLowerInvariant或ToUpperInvariant忽略语言文化 ToLower和ToUpper则使用调用线程关联的语言文化信息
 - CompareTo忽略语言文化结果,GetNumericValue返回字符的数值形式
 - 与数值进行转型
 - 转型(强制类型转换)效率最高,直接使用编译器IL指令。不必调用额外的方法。可指定checked或unchecked
 - Convert,强制使用checked方式。如果发现数据丢失,就会抛出OverflowException
 - 使用IConvertible 接口,数值类型都实现了此接口,效率最差,因为使用接口会进行装箱。对于无法转换会InvalidCastException
 
字符串(System.String)
- String代表不可变的顺序字符集,String代表不可变的顺序字符集
 - CLR用特殊的方式构造文本常量String对象,构造函数允许使用字符指针作为参数构造
 - 对于非文本常量字符串使用+操作符,连接则会在运行时进行,对于连接多个字符串,避免使用+操作符,它会在堆上创建多个字符串对象,增加GC的负载影响性能
 - 字符串不可变,所以操作或访问字符串时不会发生线程同步问题
 - CLR通过“字符串留用”机制让多个相同的string共享同一个string对象。节省性能
 - 字符串显式留用
 - Intern,获取一个String,获得它的哈希吗,并在内部哈希表中检查是否有相匹配的。如果存在一个完全相同的,返回对这个已经存在的String对象的一个引用。如果不存在,创建副本,将副本添加道内部哈希表,返回对副本的引用
 - IsInterned,也获取一个String,并在内部哈希表中查找它。如果找到,返回留用对象的引用。然而如果没有,则会返回null,它不会将字符串添加到哈希表中
 - 程序集加载时,CLR默认会留用程序集的元数据中描述的所有文本常量字符串
 - 程序集标记 assembly attribute/flag System.Runtime.CompilerServices.CompilationRelaxationsAttribute(CompilationRelaxations.NoStringInterning) 特性,指定程序集默认不进行字符串留用,一般CLR会忽略该属性
 - 编译器只在模块的元数据中将文本常量字符串写入一次,引用该字符串的所有代码都会被修改,以引用元数据中的同一个字符串。这样可以减少模块和程序集的大小。其实C/C++编译器多年来也一直采用这个技术,称为字符串池。字符串池时提升字符串性能的一种有效方式
 - 代理项字符串,使用System.Globalization.StringInfo类型处理。提供功能将字符串拆分为文本元素并循环访问这些文本元素
 - string对象的一些接口,比如Copy和CopyTo,会创建新的字符串对象,确保引用(指针)不同,即使字符串包含相同字符内容,还有Insert,Remove,PadLeft,Replace,Split等等,都是返回一个新的字符串对象
 - string.ToString() 返回对同一个对象(this)的引用
 
字符串构造器(System.Text.StringBuilder)
- 字符串构造器,动态构造字符串。包含由Char结构组成的数组字段,高效率缩短字符串或更改字符串中的字符,如果字符串太大,SB自动分配一个新的更大的数组,复制字符,并开始使用新数组。前一个数组会被垃圾回收。建议在可预见的情况下指定StringBuilder的容量
 - 内部方法EnsureCapacity,其实List<T>等集合也有这么一个方法。负责维护容量和自动扩容
 - StringBuilder的很多方法都是返回同一个引用,所以方便链式调用 sb.Append().Replace().Remove()...
 
字符串显示与文化
- 在ToString方法的实现中,为了使调用者能选择格式和语言文化,类型应该实现System.IFormattable接口。基元数值基本都实现了这个接口
 - 格式化一个数字时,ToString会检查为formatProvider参数传递的值,如果传递的是null,ToString会通过读取Thread.CurrentThread.CurrentCulture属性判断与调用线程关联的语言文化。如果一个类型实现了该接口,就认为类型的一个实例能提供符合语言文化的格式信息,与调用线程关联的语言文化应被忽略。一般使用的实现为 CultureInfo,注意属性对象为NumberFormatInfo和DateTimeFormatInfo。针对数字和时间进行格式化。(format默认为常规格式,formatProvider默认为调用线程的语言文化信息。)
 - 如果不针对具体语言文化格式化,应该调用CultureInfo.InvariantCulture, 语言中立
 - FCL的IFormatProvider接口实现,1 CultureInfo 2 NumberFormatInfo 3 DateTimeFormatInfo
 - 当使用自定义ICustomFormatter时,最好使用string.Format的方式构造字符串,不要用ToString,因为像字符串或日期都对Format做了限制
 - 一般数值或日期的ToString中的Provider,使用CultureInfo来代替就OK,或者自己提供DateTimeFormatInfo或NumberFormatInfo,实际上前者包含了后面两者的属性定义,在GetFormat中判断调用对象的类型返回后面两者中的一个
 - 自定义格式需要实现IFormatProvider和ICustomFormatter,然后把参数传递给执行自定义格式的设置操作方法,比如String.Format
 
字符串解析和转换
- Convert,Convert基本上是一个封装,在内部调用ToString或者Parse等方法。内部主要接口就是Number.Parse(NumberStyles)和DateTime.Parse(DateTimeStyles)等
 - Parse和TryParse方法
 
字符编码
- UTF-16时将每个16位字符编码为2个字节,不对字符产生影响,也不会压缩,性能出色
 - UTF-8将部分字符编码为1个字节,部分编码为2个字节。部分编码为3甚至4个字节,对应区间段: 0x0080/0x0080~0x07FF/0x0800/surrogate pairs
 - UTF-32使用4字节来编码,每个字符都是4个字节,不需要考虑代理项的问题,通常在内部使用
 - UTF-7编码,用于旧式系统。使用7位值表示,此编码方案已被Unicode协会淘汰
 - ASCII编码方案将16位字符编码成ASCII字符;值小于0x0080的16位字符被转换成单字节。超过0x007F的任何字符都不能被转换,否则字符的值会丢失。由于字符串完全由ASCII范围(0x00~0x7F)内的字符构成,ASCII编码方案就能将数据压缩到原来的一般,而且速度非常快(高位字节会被直接截掉。)不过如果字符在ASCII范围之外,编码就不适合,因为字符的值会丢失
 - 编码接口,System.Text.Encoding 例如:Byte[] encodedBytes = encodingUTF8.GetBytes(s); BitConverter.ToString(encodedBytes)
 - Encoding.Default属性返回一个对象,它使用用户当前的代码页进行编码/解码。当前用户页编码在控制面板的“区域和语言选项”对话框中,通过“非Unicode程序中所使用的当前语言”的选项来指定,通常不鼓励开发人员使用Default属性,否则程序的行为随着机器的设置而变
 - 分配字节时可以利用方法Encoding派生类的GetByteCount方法,它能统计对一组字符进行编码所产生的字节数,同时不实际进行编码
 - GetCharCount()返回解码得到的字符数,同时也不实际进行编码。可以节省内存和重用数组
 - 以上两个方法性能不佳,如果要性能更加,使用GetMaxByteCount和GetMaxCharCount方法,返回最坏情况下的值
 - 针对文件流或者网络流,如果需要跨块处理的字节流,则需要使用Encoder(通过GetEncoder获得)和Decoder(通过GetDecoder获得),它们会维护连续调用间的状态信息,它会尽可能多的解码字节数组,如果字节数组包含的字节不足以完成一个字符,剩余的字节会保存到Decoder对象内部。下次调用时,它们会利用之前剩余的字节再加上新的字节。
 - 中文的全角和半角问题,因为所有的字符在CLR中都是以Unicode-16编码的,这个问题就比较好处理了,全角和半角的值它们相差65248,除了空格相差12256。所以全角的字符若是想转换成半角除空格减12256外,其他相减65248便是相应的半角。全角空格为12288,半角空格为32。其他字符半角(33-126)与全角(65281-65374)的对应关系是:均相差65248
 - BOM,BOM全称是Byte Order Mark,即字节顺序标记,是一段二进制,用于标识一个文本是用什么编码的,比如当用Notepad打开一个文本时,如果文本里包括这一段BOM,那么它就能判断是采用哪一种编码方式,并用相应的解码方式,就会正确打开文本不会有乱码。如果没有这一段BOM,Notepad会默认以ANSI打开,这种会有乱码的可能性。可以通过Encoding的方法GetPreamble()来判断这编码有没有BOM,目前CLR中只有下面5个Encoding有BOM
 - Encoding.Convert可以对字节数组执行编码转换
 - 如果给定一个文本,我们不知道它的编码格式,解码时我们如何选择Encoding呢?答案是根据BOM来判断到底是哪种Unicode。UnicodeEncodings[i].GetPreamble()
 - 关于编码解码的一些文章参考:http://www.cnblogs.com/criedshy/
 - 字符集及编码:http://www.cnblogs.com/skynet/archive/2011/05/03/2035105.html
 
Base64字符串编码和解码
- Base-64字符串编码解码,也是一种流行的编码方案,使用System.Convert类的静态方法。
 - 具体方法包括 FromBase64String, FromBase64CharArray, ToBase64String, ToBase64CharArray
 
安全字符串
- 字符串对象可能包含敏感数据,如果和不安全的非托管代码交互,可能造成机密数据的泄露。
 - System.Security.SecureString,构造时,在内部分配一个非托管内存块,其中包含一个字符数组,之所以要使用非托管内存块,是为了避开垃圾回收的“罗网”,这些字符串是经过加密的,能防范任何恶意的非安全非托管代码获取机密信息。提供AppendChar, InsertAt, RemoveAt, SetAt等方法。内部会解密字符串然后重新加密字符串。对性能会有影响。通过IDisposable接口可以进行销毁。其中一个字段引用SafeBuffer继承与CriticalFinalizerObject,所以字符串在垃圾回收时,字符内容会保证清零,缓冲区可以释放。而且和string不同,回收之后,加密字符串的内容将不再存在于内存中
 - 解密过程,(char*)Marshal.SecureStringToTaskMemUnicode(ss),指针释放Marshal.ZeroFreeCoTaskMemUnicode(char*)
 - Marshal类提供了一系列的方法永远操纵安全字符串,包含将字符串解密到缓冲区,以及清零并释放缓冲区
 - 关于安全这块,还可以关注以下几块的东西
 - System.Security.Cryptography.ProtectedData
 - 使用System.Security.Cryptography.ProtectedMemory类
 - Configuration cfg.AppSettings.SectionInformation.ProtectSection
 - 未完待续。。。可以在探讨.NET安全时继续探讨
 
读书笔记—CLR via C#字符串及文本的更多相关文章
- CLR via C#字符串和文本处理
		
一.字符 在.NET Framewole中,字符总是表示成16位Unicode代码值,这简化了国际化应用程序的开发. 每个字符都表示成System.Char结构(一个值类型) 的一个实例.Sy ...
 - 读书笔记—CLR via C#异常和状态管理
		
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
 - 读书笔记—CLR via C#反射
		
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
 - 读书笔记—CLR via C#章节3
		
这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可以加深 ...
 - 读书笔记—CLR via C#同步构造28-29章节
		
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
 - python3-cookbook笔记:第二章 字符串和文本
		
python3-cookbook中每个小节以问题.解决方案和讨论三个部分探讨了Python3在某类问题中的最优解决方式,或者说是探讨Python3本身的数据结构.函数.类等特性在某类问题上如何更好地使 ...
 - 读书笔记—CLR via C#委托和attribute
		
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
 - 读书笔记—CLR via C#章节11-13
		
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
 - 读书笔记—CLR via C#章节8-10
		
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
 
随机推荐
- Android使用HttpClient方法和易错问题
			
HttpClient为Android开发人员提供了跟简洁的操作Http网络连接的方法,在连接过程中也有两种方式,get和post,先看一下怎样实现的 默认是get方式 //先将參数放入List,再对參 ...
 - oracle 11g 基于磁盘的备份rman duplicate
			
基于磁盘的备份rman duplicate 命令创建standby database 前提条件: 确保原始库数据库的备份.存档standby 结束是完全可见, 这里,如果原始文库和靶 - 侧数据文件, ...
 - Vim 命令 【转】
			
高级一些的编辑器,都会包含宏功能,vim当然不能缺少了,在vim中使用宏是非常方便的: :qx 开始记录宏,并将结果存入寄存器xq 退出记录模式@x 播放记录在x寄存器中的宏命 ...
 - Axis2  转让Webservice 介面
			
1,先学习部署环境.建立Axis2周围环境. http://blog.csdn.net/lanqibaoer/article/details/22731291 如今调用一个现有的公共webservic ...
 - 补间动画实现(tween)
			
1.补间动画的概念: 补间动画:仅仅须要开发人员设置好动画的開始与结束的关键帧 中间帧有喜用计算机补齐. 2.种类:分为4种: ①alpha 透明度 ②alpha 透明度 ③translate 位置移 ...
 - android模拟器与PC的端口映射(转)
			
阅读目录 一.概述 二.实现步骤 回到顶部 一.概述 Android系统为实现通信将PC电脑IP设置为10.0.2.2,自身设置为127.0.0.1,而PC并没有为Android模拟器系统指定IP,所 ...
 - 面向对象三大特征之多态——Java笔记(七)
			
多态: 同一个实体同时具有多种形式 编译时的类型有声明该变量时使用的类型决定,运行时的类型有实际赋值给变量的对象决定 如果编译时类型和运行时类型不同,就出现多态 例: clas ...
 - linux 3.4.103 内核移植到 S3C6410 开发板 移植失败 (问题总结,日本再战!)
			
linux 3.4.103 内核移植到 S3C6410 开发板 这个星期差点儿就搭在这里面了,一開始感觉非常不值得,移植这样的浪费时间的事情.想立刻搞定,然后安安静静看书 & coding. ...
 - 严重:IOException while loading persisted sessions:java.io.EOFException.
			
1.错误叙述性说明 严重:IOException while loading persisted sessions:java.io.EOFException. java.io.EOFException ...
 - 概率图形模型(PGM)学习笔记(一)动机和概述
			
在本文中,基于Daphne Koller完成课程. PDM(ProbabilisticGraphiccal Models) 称为概率图模型. 以下分别说明3个词相应的意义. 概率 -给出了不确定性的明 ...