标签:
出处:http://blog.darkthread.net/post-2015-08-07-big5-utf8-source-code-batch-converter.aspx
改用VS2015后没多久就发现它处理BIG5(ANSI)编码程式码的原则不同於以往(推测与编译器改用Roslyn有关),导致部分使用BIG5编码存档的古老程式档,会因许功盖造成编译错误。
PO文隔两天同事跟我说,他们换VS2015后也射了好一阵子茶包,最后爬文又爬回我的文章。XD 后来聊到可以写程式把所有BIG5编码程式档转成UTF8一劳永逸,同事说档案没几个,手动另存就搞定了,还不需要养乳牛。
这两天,收到网友留言询问VS2015是否会修正这个问题;也有网友提到手上专案有成千上万个cs,改了一个BIG5,还有千千万万个BIG5,只好跟VS2015说Goodbye。
首先,虽然不确定VS2015会不会针对此一Issue进行修正,但依我之见,BIG5编码已经过时多年,除了在VS2015產生不相容,遇到中文难字及其他语系文字都得额外处理(在Visual Studio.NET 2003时代就有处理过)。因此,不管VS2015会不会修正,将程式码统一改存UTF8编码是正确的方向。
问题来了,如网友所说,若专案有上万支cs,一一手动转存UTF8的浩大工程确实令人心寒。我最爱打造这种可以省时省力的潜盾机,就写支批次转档程式搞定吧!
这裡我假设专案的.cs档案分成两类,一部分已经是UTF8或Unicode编码,其餘则為BIG5编码(假设全部都是BIG5,排除掺杂简体中文、日文等其他ANSI编码的情况)。因此,可以用Directory.GetFiles()搜寻找出特定目录(含子目录)下的指定档案型别(例如:cs及js),检查档案註记略过UTF8或Unicode编码档案,找到BIG5档案后先用BIG5 Encoding读取,再以UTF8 Encoding写入就完成转档,而原来的档案则加上.big5.bak副档名备份保留。
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace B2UBatchConverter { class Program { public class AnalyzeResult { public string Content; public Encoding Encoding; } //REF:http://goo.gl/jAJgIr by Rick Strahl public static AnalyzeResult AnalyzeFile(string srcFile) { //預設為Big5 Encoding enc = Encoding.GetEncoding(950); //由前五碼識別出UTF8、Unicode、UTF32等編碼,其餘則視為 byte[] buffer = new byte[5]; using (FileStream file = new FileStream(srcFile, FileMode.Open)) { file.Read(buffer, 0, 5); file.Close(); if (buffer[0] == 0xef && buffer[1] == 0xbb && buffer[2] == 0xbf) enc = Encoding.UTF8; else if (buffer[0] == 0xfe && buffer[1] == 0xff) enc = Encoding.Unicode; else if (buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 0xfe && buffer[3] == 0xff) enc = Encoding.UTF32; else if (buffer[0] == 0x2b && buffer[1] == 0x2f && buffer[2] == 0x76) enc = Encoding.UTF7; } //使用指定的Encoding讀取內容 return new AnalyzeResult() { Content = File.ReadAllText(srcFile, enc), Encoding = enc }; } static void Main(string[] args) { //args = new string[] { "D:\\Lab\\L805\\ConApp" }; string path = args[0]; //列舉要搜尋轉碼的副檔名 var scanFileTypes = "cs,js".Split(‘,‘); //略過不處理的資料夾名稱 var skipFolders = "bin,obj".Split(‘,‘); foreach (var file in //列舉所有子目錄下的檔案 Directory.GetFiles(path, "*.*", SearchOption.AllDirectories)) { //取得副檔名 var ext = Path.GetExtension(file).TrimStart(‘.‘).ToLower(); //若非預先指定的副檔名就略過不處理 if (!scanFileTypes.Contains(ext)) continue; //處於\bin\* \obj\*目錄下的檔案也一律略過 if (skipFolders.Any(o => file.Contains( Path.DirectorySeparatorChar + o + Path.DirectorySeparatorChar))) continue; //讀取檔案內容並識別編碼 var analysis = AnalyzeFile(file); if (analysis.Encoding.CodePage == 950) //BIG5編號檔案才要處理 { Console.Write("Process File {0}...", file); //將原檔更名為*.big5.bak var bakFile = file + ".big5.bak"; if (File.Exists(bakFile)) File.Delete(bakFile); File.Move(file, bakFile); //重新以UTF8寫入 File.WriteAllText(file, analysis.Content, Encoding.UTF8); Console.WriteLine(" done!"); } else { Console.WriteLine("Skip File {0} / {1}", file, analysis.Encoding.EncodingName); } } } } }
专案编译成Console Application,执行时提供路径名称作為参数,转换程式就会扫瞄该目录下所有的.cs及.js,一口气将BIG5编码程式码转存成UTF8。
【提醒】批次转换前请务必先备份,以避免转换出错造成资料遗失。
【2015-08-07 更新】 感谢网友黄文生、Norton Lin在FB专页留这补充两款现成软体工具:ConvertZ以及UTFCast也可以做到批次编码转换。 另外,ChrisTorng 也分享可与TFS整合的批次转档,并提到靠 StreamReader 建构式之 detectEncodingFromByteOrderMarks 参数侦测Encoding的小技巧。
谢谢大家的回馈。
【2015-08-12 更新】VS2015程式档BIG5相容问题快速解法-修改csproj/vbproj
vs2015 编译报错 CS1003 Syntax error
标签:
原文地址:http://www.cnblogs.com/jtaosj/p/VS2015.html