• .Net Core 获取文件编码格式


    .由于业务需要,需要读取文本文件内容。所以参考了网上的一些写法,测试过程中还是踩了坑。故在此做一下记录。

    .Net Framework 中获取文件编码格式的方法:

    代码完全照搬来自文章:《C# 获取文件编码格式》(感谢哈!)

    主要代码如下:

    1. public class FileEncoding
    2. {
    3. ///
    4. /// 给定文件的路径,读取文件的二进制数据,判断文件的编码类型
    5. ///
    6. /// 文件路径
    7. /// 文件的编码类型
    8. public static System.Text.Encoding GetType(string FILE_NAME)
    9. {
    10. FileStream fs = new FileStream(FILE_NAME, FileMode.Open, FileAccess.Read);
    11. Encoding r = GetType(fs);
    12. fs.Close();
    13. return r;
    14. }
    15. ///
    16. /// 通过给定的文件流,判断文件的编码类型
    17. ///
    18. /// 文件流
    19. /// 文件的编码类型
    20. public static System.Text.Encoding GetType(FileStream fs)
    21. {
    22. Encoding reVal = Encoding.Default;
    23. BinaryReader r = new BinaryReader(fs, System.Text.Encoding.Default);
    24. int i;
    25. int.TryParse(fs.Length.ToString(), out i);
    26. byte[] ss = r.ReadBytes(i);
    27. if (IsUTF8Bytes(ss) || (ss[0] == 0xEF && ss[1] == 0xBB && ss[2] == 0xBF))
    28. {
    29. reVal = Encoding.UTF8;
    30. }
    31. else if (ss[0] == 0xFE && ss[1] == 0xFF && ss[2] == 0x00)
    32. {
    33. reVal = Encoding.BigEndianUnicode;
    34. }
    35. else if (ss[0] == 0xFF && ss[1] == 0xFE && ss[2] == 0x41)
    36. {
    37. reVal = Encoding.Unicode;
    38. }
    39. r.Close();
    40. return reVal;
    41. }
    42. ///
    43. /// 判断是否是不带 BOM 的 UTF8 格式
    44. ///
    45. ///
    46. ///
    47. private static bool IsUTF8Bytes(byte[] data)
    48. {
    49. int charByteCounter = 1; //计算当前正分析的字符应还有的字节数
    50. byte curByte; //当前分析的字节.
    51. for (int i = 0; i < data.Length; i++)
    52. {
    53. curByte = data[i];
    54. if (charByteCounter == 1)
    55. {
    56. if (curByte >= 0x80)
    57. {
    58. //判断当前
    59. while (((curByte <<= 1) & 0x80) != 0)
    60. {
    61. charByteCounter++;
    62. }
    63. //标记位首位若为非0 则至少以2个1开始 如:110XXXXX...........1111110X
    64. if (charByteCounter == 1 || charByteCounter > 6)
    65. {
    66. return false;
    67. }
    68. }
    69. }
    70. else
    71. {
    72. //若是UTF-8 此时第一位必须为1
    73. if ((curByte & 0xC0) != 0x80)
    74. {
    75. return false;
    76. }
    77. charByteCounter--;
    78. }
    79. }
    80. if (charByteCounter > 1)
    81. {
    82. throw new Exception("非预期的byte格式");
    83. }
    84. return true;
    85. }
    86. }

    .Net Core 中获取文件编码的方法

    然而,上面的代码在.Net Core + 默认ANSI编码的win操作系统(早于win10) 中运行会出现中文乱码的现象。主要原因在于Encoding.Default属性在.Net Core 中值发生了变化。

    微软官方文档中对 Encoding.Default 属性 做出了如下解释:

    也就是说:

    .NET Core 中,Encoding.Default 等于 Encoding.GetEncoding("gb2312")

    .NET Core 中, Encoding.Default 等于 UTF8Encoding

    所以.Net Core 中如果继续用上面参考文章中的代码,在读取ANSI文件时会发生乱码。而ANSI 在简体中文系统下就是 GB2312。

    所以适用于.net core 的获取文件编码的方法的代码如下:

    1. public class FileEncoding
    2. {
    3. ///
    4. /// 给定文件的路径,读取文件的二进制数据,判断文件的编码类型
    5. ///
    6. /// 文件路径
    7. /// 文件的编码类型
    8. public static System.Text.Encoding GetType(string FILE_NAME)
    9. {
    10. FileStream fs = new FileStream(FILE_NAME, FileMode.Open, FileAccess.Read);
    11. Encoding r = GetType(fs);
    12. fs.Close();
    13. return r;
    14. }
    15. ///
    16. /// 通过给定的文件流,判断文件的编码类型
    17. ///
    18. /// 文件流
    19. /// 文件的编码类型
    20. public static System.Text.Encoding GetType(FileStream fs)
    21. {
    22. Encoding reVal = Encoding.GetEncoding("gb2312");
    23. BinaryReader r = new BinaryReader(fs, System.Text.Encoding.Default);
    24. int i;
    25. int.TryParse(fs.Length.ToString(), out i);
    26. byte[] ss = r.ReadBytes(i);
    27. if (IsUTF8Bytes(ss) || (ss[0] == 0xEF && ss[1] == 0xBB && ss[2] == 0xBF))
    28. {
    29. reVal = Encoding.UTF8;
    30. }
    31. else if (ss[0] == 0xFE && ss[1] == 0xFF && ss[2] == 0x00)
    32. {
    33. reVal = Encoding.BigEndianUnicode;
    34. }
    35. else if (ss[0] == 0xFF && ss[1] == 0xFE && ss[2] == 0x41)
    36. {
    37. reVal = Encoding.Unicode;
    38. }
    39. r.Close();
    40. return reVal;
    41. }
    42. ///
    43. /// 判断是否是不带 BOM 的 UTF8 格式
    44. ///
    45. ///
    46. ///
    47. private static bool IsUTF8Bytes(byte[] data)
    48. {
    49. int charByteCounter = 1; //计算当前正分析的字符应还有的字节数
    50. byte curByte; //当前分析的字节.
    51. for (int i = 0; i < data.Length; i++)
    52. {
    53. curByte = data[i];
    54. if (charByteCounter == 1)
    55. {
    56. if (curByte >= 0x80)
    57. {
    58. //判断当前
    59. while (((curByte <<= 1) & 0x80) != 0)
    60. {
    61. charByteCounter++;
    62. }
    63. //标记位首位若为非0 则至少以2个1开始 如:110XXXXX...........1111110X
    64. if (charByteCounter == 1 || charByteCounter > 6)
    65. {
    66. return false;
    67. }
    68. }
    69. }
    70. else
    71. {
    72. //若是UTF-8 此时第一位必须为1
    73. if ((curByte & 0xC0) != 0x80)
    74. {
    75. return false;
    76. }
    77. charByteCounter--;
    78. }
    79. }
    80. if (charByteCounter > 1)
    81. {
    82. throw new Exception("非预期的byte格式");
    83. }
    84. return true;
    85. }
    86. }

    主要就是把:

    Encoding reVal = Encoding.Default;

    改成:

    Encoding reVal = Encoding.GetEncoding("gb2312");

  • 相关阅读:
    基于Struts2+Hibernate开发学生信息管理系统(选课)
    Web服务器-Tomcat详细原理与实现
    9.30 校招 实习 内推 面经
    Python的内存优化
    携职教育:来说说中级经济师的利与弊
    JSD-2204-Elasticsearch-SpringData-酷鲨商城概述-Day07
    Redis系列4:高可用之Sentinel(哨兵模式)
    开发中-唯一标识符最佳做法
    盘点Visual Studio 2022 17.4 给C++开发者带来的新东西
    递归应用判断是否循环引用
  • 原文地址:https://blog.csdn.net/guigenyi/article/details/126307665