获取csv文件编码,解决csv读取中文乱码问题
咱们解析csv文件时最经常遇到的问题就是乱码,可能有朋友说了我在解析时直接设定编码类型为GBK,GB2312就可以解决中文乱码,如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | public static List<List<String>> readTxtOrCsvFile(InputStream input) { List<List<String>> data = Lists.newArrayList(); if (input == null ) { return data; } InputStreamReader read = null ; BufferedReader br = null ; try { read = new InputStreamReader(input, "GB2312" ); br = new BufferedReader(read); String line; while ((line = br.readLine()) != null ) { if (StringUtils.isNotBlank(line)) { List<String> dd = Arrays.asList(line.split( "," )); List<String> n = new ArrayList<>(); for ( int i = 0 ; i < dd.size(); i++) { String cellData = dd.get(i); n.add(buildText(cellData)); } data.add(n); } } } catch (Exception e) { e.printStackTrace(); } finally { try { if (br != null ) { br.close(); } if (read != null ) { read.close(); } if (input != null ) { input.close(); } } catch (Exception e) { e.printStackTrace(); } } return data; } |
这样可以解决部分用户的乱码,我想问下如果我的文件类型为UTF-8呢,这样解析出来的还是有乱码。如何做到完全解决呢。作者本人也遇到这种问题,想了许久,也在网上搜索很久,得到一个解决方案。
解决方案是:自己获取要解析文件编码,然后按照编码进行解析。如何才能获取编码,有如下步骤
1、从流中读取前三个字节到一个byte[3]数组中;
2、通过Integer.toHexString(byte[0] & 0xFF),将byte[3]数组中的三个byte分别转换成16进制的字符表示;
3、根据对三个byte进行转换后得到的字符串,与UTF-8格式头EFBBBF进行比较即可知道是否UTF-8格式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | /** * 读取txt,csv文件 * * @return */ public static List<List<String>> readTxtOrCsvFile(InputStream input) { List<List<String>> data = Lists.newArrayList(); if (input == null ) { return data; } InputStreamReader read = null ; BufferedReader br = null ; BufferedInputStream bb = null ; try { bb = new BufferedInputStream(input); read = new InputStreamReader(bb, getCharSet(bb)); br = new BufferedReader(read); String line; while ((line = br.readLine()) != null ) { if (StringUtils.isNotBlank(line)) { List<String> dd = Arrays.asList(line.split( "," )); List<String> n = new ArrayList<>(); for ( int i = 0 ; i < dd.size(); i++) { String cellData = dd.get(i); n.add(buildText(cellData)); } data.add(n); } } } catch (Exception e) { e.printStackTrace(); } finally { try { if (br != null ) { br.close(); } if (read != null ) { read.close(); } if (bb != null ) { bb.close(); } if (input != null ) { input.close(); } } catch (Exception e) { e.printStackTrace(); } } return data; } /** * 获取流对应的编码类型 * @param bb * @return * @throws Exception */ private static String getCharSet(BufferedInputStream bb) throws Exception { String charSet = null ; byte [] buffer = new byte [ 3 ]; //因流读取后再读取可能会缺少内容,此处需要先读,然后再还原 bb.mark(bb.available() + 1 ); bb.read(buffer); bb.reset(); String s = Integer.toHexString(buffer[ 0 ] & 0xFF ) + Integer.toHexString(buffer[ 1 ] & 0xFF ) + Integer.toHexString(buffer[ 2 ] & 0xFF ); switch (s) { //GBK,GB2312对应均为d5cbba,统一当成GB2312解析 case "d5cbba" : charSet = "GB2312" ; break ; case "efbbbf" : charSet = "UTF-8" ; break ; default : charSet = "GB2312" ; break ; } return charSet; } |
问题圆满解决
【推荐】博客园的心动:当一群程序员决定开源共建一个真诚相亲平台
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】Flutter适配HarmonyOS 5知识地图,实战解析+高频避坑指南
【推荐】开源 Linux 服务器运维管理面板 1Panel V2 版本正式发布
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· MySQL索引完全指南:让你的查询速度飞起来
· 一个字符串替换引发的性能血案:正则回溯与救赎之路
· 为什么说方法的参数最好不要超过4个?
· C#.Net 筑基-优雅 LINQ 的查询艺术
· 一个自认为理想主义者的程序员,写了5年公众号、博客的初衷
· 使用GcExcel .NET将Excel导出为PDF
· 【设计模式】外观模式
· 本地搭建一个对嘴AI工具
· MySQL索引完全指南:让你的查询速度飞起来
· Web前端入门第 72 问:JavaScript DOM 内容操作常用方法和 XSS 注入攻击