自动判断文本文件编码来读取文本文件内容(.net版本和java版本)
.net版本
using System;
using System.IO;
using System.Text; namespace G2.Common
{
/// <summary>
/// 用于取得一个文本文件的编码方式(Encoding)。
/// </summary>
public static class TextEncodingHelper
{
/// <summary>
/// 取得一个文本文件的编码方式。如果无法在文件头部找到有效的前导符,Encoding.Default将被返回。
/// 文件的字符集在Windows下有两种,一种是ANSI,一种Unicode。
/// 对于Unicode,Windows支持了它的三种编码方式,一种是小尾编码(Unicode),一种是大尾编码(BigEndianUnicode),一种是UTF-8编码。
/// 我们可以从文件的头部来区分一个文件是属于哪种编码。当头部开始的两个字节为 FF FE时,是Unicode的小尾编码;当头部的两个字节为FE FF时,是Unicode的大尾编码;当头部两个字节为EF BB时,是Unicode的UTF-8编码;当它不为这些时,则是ANSI编码。
/// 按照如上所说,我们可以通过读取文件头的两个字节来判断文件的编码格式
/// </summary>
/// <param name="filename">文件名。</param>
/// <returns></returns>
public static System.Text.Encoding GetFileEncoding(this string filename)
{
if (!File.Exists(filename))
{
throw new Exception("文件"" + filename + ""不存在!");
} using (var fs = new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read))
using (var br = new System.IO.BinaryReader(fs))
{
var buffer = br.ReadBytes();
if (buffer[] >= 0xEF)
{
if (buffer[] == 0xEF && buffer[] == 0xBB)
{
return System.Text.Encoding.UTF8;
} if (buffer[] == 0xFE && buffer[] == 0xFF)
{
return System.Text.Encoding.BigEndianUnicode;
} if (buffer[] == 0xFF && buffer[] == 0xFE)
{
return System.Text.Encoding.Unicode;
}
} return GetEncodingWithBomUtf8(fs, System.Text.Encoding.Default);
}
} /// <summary>
/// 通过给定的文件流,判断文件的编码类型 (解决了不带BOM的 UTF8 编码问题 )
/// </summary>
/// <param name="fs">文件流</param>
/// <param name="defaultEncoding">默认编码</param>
/// <returns>文件的编码类型</returns>
private static System.Text.Encoding GetEncodingWithBomUtf8(Stream fs, Encoding defaultEncoding)
{
byte[] unicode = new byte[] { 0xFF, 0xFE, 0x41 };
byte[] unicodeBig = new byte[] { 0xFE, 0xFF, 0x00 }; //带BOM
byte[] utf8 = new byte[] { 0xEF, 0xBB, 0xBF };
var reVal = defaultEncoding; using (var r = new System.IO.BinaryReader(fs))
{
byte[] ss = r.ReadBytes();
if (ss[] == 0xFE && ss[] == 0xFF && ss[] == 0x00)
{
reVal = Encoding.BigEndianUnicode;
}
else if (ss[] == 0xFF && ss[] == 0xFE && ss[] == 0x41)
{
reVal = Encoding.Unicode;
}
else
{
if (ss[] == 0xEF && ss[] == 0xBB && ss[] == 0xBF)
{
reVal = Encoding.UTF8;
}
else
{
int i;
int.TryParse(fs.Length.ToString(), out i);
ss = r.ReadBytes(i); if (IsUtf8Bytes(ss))
{
reVal = Encoding.UTF8;
}
}
} return reVal;
}
} /// <summary>
/// 判断是否是不带 BOM 的 UTF8 格式
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
private static bool IsUtf8Bytes(byte[] data)
{
int charByteCounter = ; //计算当前正分析的字符应还有的字节数
for (int i = ; i < data.Length; i++)
{
var curByte = data[i]; //当前分析的字节.
if (charByteCounter == )
{
if (curByte >= 0x80)
{
//判断当前
while (((curByte <<= ) & 0x80) != )
{
charByteCounter++;
}
//标记位首位若为非0 则至少以2个1开始 如:110XXXXX...........1111110X
if (charByteCounter == || charByteCounter > )
{
return false;
}
}
}
else
{
//若是UTF-8 此时第一位必须为1
if ((curByte & 0xC0) != 0x80)
{
return false;
}
charByteCounter--;
}
}
if (charByteCounter > )
{
throw new Exception("非预期的byte格式!");
}
return true;
}
}
}
java版本
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.util.BitSet; public class EncodeUtils {
private static final Logger logger = LoggerFactory.getLogger(EncodeUtils.class);
private static final int BYTE_SIZE = 8;
private static final String CODE_UTF8 = "UTF-8";
private static final String CODE_UTF16 = "UTF-16";//Unicode
private static final String CODE_UTF16LE = "UTF-16LE";//Unicode big endian
private static final String CODE_GBK = "GBK"; //ABSU /**
* 通过文件全名称获取编码集名称
*/
public static String getEncode(String fullFileName) throws Exception {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fullFileName));
return getEncode(bis, CODE_GBK);
} /**
* 通过文件全名称获取编码集名称
*/
public static String getEncode(String fullFileName, String defaultEncoding) throws Exception {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fullFileName));
return getEncode(bis, defaultEncoding);
} /**
* 通过文件缓存流获取编码集名称,文件流必须为未曾
*
* @param bis 文件流
*/
public static String getEncode(BufferedInputStream bis, String defaultEncoding) throws Exception {
bis.mark(0);
String encodeType;
byte[] head = new byte[3];
bis.read(head);
if (head[0] == -1 && head[1] == -2 && head[2] == (byte) 0x41) {
encodeType = CODE_UTF16;
} else if (head[0] == -2 && head[1] == -1 && head[2] == 0) {
//encodeType = "Unicode";
encodeType = CODE_UTF16LE;
} else if (head[0] == -17 && head[1] == -69 && head[2] == -65) {
//带BOM的UTF8 (CODE_UTF8_BOM)
encodeType = CODE_UTF8;
} else {
if (isUTF8(bis)) {
encodeType = CODE_UTF8;
} else {
encodeType = defaultEncoding;
}
} return encodeType;
} /**
* 是否是无BOM的UTF8格式,不判断常规场景,只区分无BOM UTF8和GBK
*/
private static boolean isUTF8(BufferedInputStream bis) throws Exception {
bis.reset(); //读取第一个字节
int code = bis.read();
do {
BitSet bitSet = convert2BitSet(code);
//判断是否为单字节
if (bitSet.get(0)) {//多字节时,再读取N个字节
if (!checkMultiByte(bis, bitSet)) {//未检测通过,直接返回
return false;
}
}
code = bis.read();
} while (code != -1);
return true;
} /**
* 检测多字节,判断是否为utf8,已经读取了一个字节
*/
private static boolean checkMultiByte(BufferedInputStream bis, BitSet bitSet) throws Exception {
int count = getCountOfSequential(bitSet);
byte[] bytes = new byte[count - 1];//已经读取了一个字节,不能再读取
bis.read(bytes);
for (byte b : bytes) {
if (!checkUtf8Byte(b)) {
return false;
}
}
return true;
} /**
* 检测bitSet中从开始有多少个连续的1
*/
private static int getCountOfSequential(BitSet bitSet) {
int count = 0;
for (int i = 0; i < BYTE_SIZE; i++) {
if (bitSet.get(i)) {
count++;
} else {
break;
}
}
return count;
} /**
* 检测单字节,判断是否为utf8
*/
private static boolean checkUtf8Byte(byte b) throws Exception {
BitSet bitSet = convert2BitSet(b);
return bitSet.get(0) && !bitSet.get(1);
} /**
* 将整形转为BitSet
*/
private static BitSet convert2BitSet(int code) {
BitSet bitSet = new BitSet(BYTE_SIZE); for (int i = 0; i < BYTE_SIZE; i++) {
int tmp3 = code >> (BYTE_SIZE - i - 1);
int tmp2 = 0x1 & tmp3;
if (tmp2 == 1) {
bitSet.set(i);
}
}
return bitSet;
} public static void main(String[] args) {
String filePath = "C:\\110025.txt";
try {
String encoding = getEncode(filePath);
System.out.println(encoding);
} catch (Exception ex) {
logger.warn("文件检测编码出错!", ex);
}
}
}
自动判断文本文件编码来读取文本文件内容(.net版本和java版本)的更多相关文章
- [转发]读取txt防止读到乱码--自动根据文件编码进行读取
以下是摘抄 /// <summary> /// 获取文件的编码格式 /// </summary> public class EncodingType { /// <sum ...
- web前端读取文本文件内容
html5+js实现,参照xxyy888的CSDN博客文章<使用HTML+javascrpt读取txt文本文件>失败,将作者文章中的代码重新整理了下依然不行,文章代码存在的问题是括号错误, ...
- java读取文本文件内容2
版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/183 很久之前写了一篇Java读取文本文件内容,链接地址是 ...
- java读取文本文件内容
版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/128 java读取文本文件内容 今天写代码写着要调试一个很 ...
- php -- 读取文本文件内容
php读取文件内容的三种方法: //**************第一种读取方式***************************** 代码如下: header("content- ...
- MATLAB对于文本文件(txt)数据读取的技巧总结(经典中的经典)
振动论坛原版主eight的经典贴http://www.chinavib.com/thread-45622-1-1.html MATLAB对于文本文件(txt)进行数据读取的技巧总结(经典中的经典)由于 ...
- python读取文本文件
1. 读取文本文件 代码: f = open('test.txt', 'r') print f.read() f.seek(0) print f.read(14) f.seek(0) print f. ...
- 获取文本文件的第N行内容
在PowerShell中,可以通过Get-Content这个cmdlet来获取文本文件的内容.Get-Content将一个文本文件读取到一个数组中,每一个数组元素就是文件的一行内容.比如一个文本文件内 ...
- (转) Java读取文本文件中文乱码问题
http://blog.csdn.net/greenqingqingws/article/details/7395213 最近遇到一个问题,Java读取文本文件(例如csv文件.txt文件等),遇到中 ...
随机推荐
- blockchain notes
1. IBM blockchain platform https://www.ibm.com/blockchain/platform/ 2. 开源项目hyperledger https://hyper ...
- 453D Little Pony and Elements of Harmony
传送门 分析 我们可以将所有的b[i^j]直接对应到b[f(i^j)]上 于是显然可以fwt 我们对b进行t次fwt之后直接将答案与e0卷起来即可 注意由于模数不确定,我们可以将模数扩大$2^m$然后 ...
- threading学习
多线程类似于同时执行多个不同程序,多线程运行有如下优点: 使用线程可以把占据长时间的程序中的任务放到后台去处理. 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进 ...
- 二度Xml<2>
一下介绍xml的基本操作,添加xml新节点: 其他方法在前一篇日记中有详细讲解,请详见:http://www.cnblogs.com/fjsnail/archive/2012/10/20/273212 ...
- Alpha项目复审
队名 优点 缺点 排名 拉登是我罩的 1.最底层.从无到有实现的软硬件结合的俄罗斯方块游戏. 2.从画电路原理图.PCB电路板设计.接线.操作系统(没用到操作系统).驱动程序.应用程序开发,串口通信. ...
- 使用Recyclerview实现图片水平自动循环滚动
简介: 本篇博客主要介绍的是如何使用RecyclerView实现图片水平方向自动循环(跑马灯效果) 效果图: 思路: 1.准备m张图片 1.使用Recyclerview实现,返回无数个(实际Inter ...
- FileUtils 文件下载 文件导出
public class FileUtils { /// <summary> /// 文件下载 /// </summary> /// <param name=" ...
- 《Andorid开源》greenDao 数据库orm框架
一 前言:以前没用框架写Andorid的Sqlite的时候就是用SQLiteDatabase ,SQLiteOpenHelper ,SQL语句等一些东西,特别在写SQL语句来进行 数据库操作的时 ...
- C#NPOI.RabbitMQ.EF.Attribute.HttpRuntime.Cache.AD域.List<T>根据指定字段去重.前端JQuery.Cache.I18N(多语言).data-xx(自定义属性)
使用NPOI 操作Excel 个人使用的电脑基本默认安装Excel 操作起来 调用Excel的组件便可.如果是一台服务器.没有安装Excel,也就无法调用Excel组件. 在此推荐第三方插件.NPOI ...
- angular 辅助路由