上篇博客中主要说了GDAL库C#版本中存在的问题,其表现形式主要是:“文件名中的汉字个数是偶数,完全没有影响,读取和创建都正常,如果文件名中的汉字个数是奇数,读取和创建都会报错。

针对这个问题,今天仔细研究(查看+折腾)了下C#程序中string类型的默认编码方式。首先通过下面的代码进行检测C#程序中string类型的默认编码方式是什么。

static void Main(string[] args)
{string s = "我";// 首先获取默认编码的字节及其长度,并输出byte[] bDefault =Encoding.Default.GetBytes(s);Console.WriteLine(bDefault.Length);foreach (byte b inbDefault){Console.WriteLine(b);}// 接下来获取Unicode编码的字节及其长度,并输出byte[] bUnicode =Encoding.Unicode.GetBytes(s);Console.WriteLine(bUnicode.Length);foreach (byte b inbUnicode){Console.WriteLine(b);}// 接下来获取UTF8编码的字节及其长度,并输出byte[] bUTF8 =Encoding.UTF8.GetBytes(s);Console.WriteLine(bUTF8.Length);foreach (byte b inbUTF8){Console.WriteLine(b);}// 最后获取936编码(即GB2312)的字节及其长度,并输出byte[] b936 =Encoding.GetEncoding(936).GetBytes(s);Console.WriteLine(b936.Length);foreach (byte b in b936){Console.WriteLine(b);}
}

在XP64位中文操作系统与Win764位英文操作系统上运行过上面的代码片段,我们通过查看四个byte数组中的值,分别如下图所示。截图上面是十进制显示,下半部分为十六进制显示。

从上图可以清楚的看出,C#中对于汉字的默认编码应该使用的是GB2312(936)编码。这个默认的编码与操作系统也没有关系。

知道了系统默认的汉字编码方式,那么下面就来看看昨天的问题,使用代码System.Text.Encoding.Default.GetString(System.Text.Encoding.UTF8.GetBytes(utf8_path))转换后的编码到底变成了什么编码。使用下面的代码片段进行测试:

static void Main(string[] args)
{string s = "我";string strTEmp = System.Text.Encoding.Default.GetString(System.Text.Encoding.UTF8.GetBytes(s));byte[] bDefault =Encoding.Default.GetBytes(strTEmp);Console.WriteLine(bDefault.Length);foreach (byte b inbDefault){Console.WriteLine(b);}Console.WriteLine(strTEmp);
}

通过监视查看发现通过上面的代码转换之后的字节与UTF8前两个一致,但是第三个已经变成了ASCII码中的63即问号“?”,但是系统当前认为字符串依旧是GB2312的编码,所以字符串出现了乱码。如下图所示。

接下来我们再看看这个字符串通过swig封装之后,传入GDAL库之后的C++语言对应的字节编码是什么,使用前两篇博客中的跨语言调试方式,直接将上面的字符串“我”用Ogr.Open函数打开,然后在C++库中的文件gdal-1.10.0\port\cpl_vsil_win32.cpp中的函数VSIVirtualHandle*VSIWin32FilesystemHandler::Open( const char *pszFilename,   const char *pszAccess )处添加断点来查看传入的字符串,如下图所示:

转换前后的字符串及其字节码如下:

通过对比这个图与上面C#的字节码,发现了一个问题。C#中的bDefault字节码是(230、136、63)转换为16进制为(0xe6、0x88、0x3f)与C++库中传入的字节码一致(pszFilename)。这也就是说,通过swig封装并传入C++库后,编码保持不变,依旧是那个错误的编码。也就是说通过代码System.Text.Encoding.Default.GetString(System.Text.Encoding.UTF8.GetBytes(utf8_path))进行转换造成了编码错误,那么只需要修改这里,不让他进行转码或者在将Default改成UTF8应该就行了。

按照这个思路,将swig\csharp目录下的所有的System.Text.Encoding.Default.GetString(System.Text.Encoding.UTF8.GetBytes(utf8_path))都改成System.Text.Encoding. UTF8.GetString(System.Text.Encoding.UTF8.GetBytes(utf8_path))进行测试。

共需改动的文件不多,共有四个文件,如下图所示:

修改时,使用批量替换即可。修改完重新编译GDAL的C#库,然后将编译好的八个dll重新加入工程中,按照上面的步骤再次进行调试。进入C++的代码中,监视编码转换前后的值的变化。如下图所示。

从上图可以看出,这里传入的字符串pszFilename的编码已经变成了(0xce、0xd2),这个编码就是C#里面的默认编码或者GB2312编码,也就不是UTF8编码了。那么我们就可以通过设置GDAL_FILENAME_IS_UTF8=NO来进行读取了。

接下来,我们使用一个原来不能打开的路径,然后将GDAL_FILENAME_IS_UTF8设置为NO,进行测试。调试代码如下图所示,从图中可以看出,原来不能打开的shp已经正常打开。

控制台输出的信息为:

经过测试,这样修改可以支持所有的中文及其英文路径了。测试环境为Xp64位中文操作系统与Win764位英文操作系统。

我已经将修改后的C#版本的8个dll打包上传至CSDN资源和qq群共享,直接替换之前GDAL110版本里面的原来的dll即可。CSDN下载地址为:http://download.csdn.net/detail/liminlu0314/5809463

浅析GDAL库C#版本支持中文路径问题(续)相关推荐

  1. 浅析GDAL库C#版本支持中文路径问题

    GDAL库对于C#的支持问题还是蛮多的,对于中文路径的支持就是其中之一(另一个就是通过OGR库获取图形的坐标信息). 关于C#支持中文路径,看过我之前博客的应该都不陌生,如果使用的是我修改过的GDAL ...

  2. GDAL支持中文路径-属性表支持中文配置

    // 为了支持中文路径 OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // ...

  3. 使用SQLite3支持中文路径

    最近编写控制点库的几何精校正中使用SQLite来管理控制点,在使用过程中发现SQLite发现不支持中文路径,打开中文路径的数据库在查询的时候提示"no such table: ***&quo ...

  4. 解决Mygui不支持中文路径

    昨日不可追, 今日尤可为.勤奋,炽诚,不忘初心 外国人写的Mygui库,不支持中文路径,情有可原,中文编码嘛,中国的标准,对吧. 但是! 中国那么多用Mygui的大虾呢?网上居然找不到一篇博客是解决M ...

  5. opencv中的imread不支持中文路径的解决办法

    其实严格来说,不是imread不支持中文路径,而是不支持non-ascii.所以不论路径如何转换编码格式,应该都不能解决问题. 解决的思路就是先用其他支持中文的API,把图片数据导入到内存中,然后通过 ...

  6. svn不支持中文路径问题的解决

    作者:朱金灿 来源:http://blog.csdn.net/clever101 svn的授权文件authz默认是不支持中文路径的,因此在精确控制中文文件夹的授权时往往会出错.要解决这个问题,需要用U ...

  7. java压缩解压缩_利用Java实现压缩与解压缩(zip、gzip)支持中文路径

    zip扮演着归档和压缩两个角色:gzip并不将文件归档,仅只是对单个文件进行压缩,所以,在UNIX平台上,命令tar通常用来创建一个档案文件,然后命令gzip来将档案文件压缩. Java I/O类库还 ...

  8. nginx文件服务器中文路径,nginx配置文件支持中文路径.htm

    nginx配置文件支持中文路径 nginx配置文件支持中文路径 例子: server { color=#ff0000>charset utf-8; listen 8088;         se ...

  9. 使GDAL库支持中文路径或中文文件名的处理方法

    之前生成的gdal 2.1.1动态库,在通过命令行执行时,遇到有中文路径或中文图像名时,GDALOpen函数不能正确的被调用,如下图: 解决方法: 1.      在所有使用GDALAllRegist ...

最新文章

  1. 基本概念学习(8003)---CPU中央处理器
  2. 11.24杭州沙龙预告:数据化经营,智能化决策
  3. mysql免安装版配置方法
  4. Linux系统下如何挂载FAT32的U盘
  5. vb冒泡排序法流程图_VB算法-冒泡排序教案
  6. 生产环境频繁内存溢出,原来就是因为这个“String类”
  7. 开始研究WEKA,一个开源java的数据挖掘工具
  8. Android UDP
  9. HTML5 data-* 自定义属性 ---转载 原文地址:https://www.cnblogs.com/dolphinX/p/3348458.html...
  10. 维、哈、柯文字符代码及键盘标准
  11. 【DockerCE】Docker-CE 20.10.17正式版发布
  12. Codeforces Is your horseshoe on the other hoof?
  13. 50.新拟物卡片悬停特效
  14. html中以菱形为边框,深入浅析css3 border-image边框图像详解
  15. DELLEMC S4048
  16. 全面认识SaaS的优缺点
  17. PHP苹果支付以及事件通知-周期订阅实现
  18. 80篇+网络安全面试经验帖
  19. appium 环境搭建配置清单带版本号
  20. 各种管理系统术语,OMS、WMS、CRM...

热门文章

  1. 弹出页面,弹出框,$(‘‘).modal({});模态框
  2. mac 图形化安装mysql,mac安装mysql图形化工具?
  3. 力扣——在排序数组中查找元素的第一个和最后一个位置
  4. Java中的Bean是什么?
  5. mpvue解析富文本mpvue-wxParse
  6. C#文件夹的创建和定期删除
  7. Halcon Blob分析(二值化图像分割)
  8. ap.net core 教程(三)
  9. SQL语句的一些重要操作
  10. 关于如何提高代码可测试性的一些看法