1 package com.test.file; 2 3 import java.io.BufferedInputStream; 4 import java.io.BufferedReader; 5 import java.io.DataInputStream; 6 import java.io.FileInputStream; 7 import java.io.FileOutputStream; 8 import java.io.IOException; 9 import java.io.InputStreamReader; 10 import java.io.OutputStreamWriter; 11 import java.io.Writer; 12 13 public class FileRW { 14 public static void main(String[] args) { 15 String file_utf = "D:/eclipse/workspace/javaFileTest/test-utf.txt"; 16 codeString(file_utf,true); 17 getFileContent(file_utf,false); 18 19 String file_gbk = "D:/eclipse/workspace/javaFileTest/test-gbk.txt"; 20 String file_gbk_utf_8 = "D:/eclipse/workspace/javaFileTest/test-gbk-utf-8-error.txt"; 21 String file_gbk_utf_16 = "D:/eclipse/workspace/javaFileTest/test-gbk-utf-16-ok.txt"; 22 23 transferFile(file_gbk,file_gbk_utf_8,"utf-8"); 24 transferFile(file_gbk,file_gbk_utf_16,"utf-16"); 25 26 codeString(file_gbk,true); 27 getFileContent(file_gbk,false); 28 29 codeString(file_gbk_utf_8,true); 30 getFileContent(file_gbk_utf_8,false); 31 32 codeString(file_gbk_utf_16,true); 33 getFileContent(file_gbk_utf_16,false); 34 } 35 36 private static void getFileContent(String filePath,boolean forceCode) 37 { 38 try{ 39 String line_separator = System.getProperty("line.separator"); 40 FileInputStream fis = new FileInputStream(filePath); 41 StringBuffer content = new StringBuffer(); 42 DataInputStream in = new DataInputStream(fis); 43 String code = codeString(filePath,false); 44 BufferedReader d = null; 45 if (forceCode) { 46 d = new BufferedReader(new InputStreamReader(in, "UTF-8")); 47 } else { 48 d = new BufferedReader(new InputStreamReader(in, code)); 49 } 50 String line = null; 51 while ((line = d.readLine()) != null) 52 content.append(line + line_separator); 53 d.close(); 54 in.close(); 55 fis.close(); 56 System.out.println(content); 62 }catch(IOException e){ 63 System.out.println("获取文件内容异常"); 64 } 65 } 66 67 private static void transferFile(String srcFileName, String destFileName,String codeOuput) { 68 try { 69 String line_separator = System.getProperty("line.separator"); 70 FileInputStream fis = new FileInputStream(srcFileName); 71 StringBuffer content = new StringBuffer(); 72 DataInputStream in = new DataInputStream(fis); 73 String codeInput = codeString(srcFileName,false); 74 BufferedReader d = new BufferedReader(new InputStreamReader(in, codeInput));// , "UTF-8" 75 String line = null; 76 while ((line = d.readLine()) != null) 77 content.append(line + line_separator); 78 d.close(); 79 in.close(); 80 fis.close(); 81 Writer ow = new OutputStreamWriter(new FileOutputStream(destFileName), codeOuput); 82 ow.write(content.toString()); 83 ow.close(); 84 System.out.println("写入完成!"); 85 } catch (Exception e) { 86 System.out.println("文件编码转换异常"); 87 } 88 } 89 90 /** 91 * 判断文件的编码格式 92 * 93 * @param fileName 94 * :file 95 * @return 文件编码格式 96 * @throws Exception 97 */ 98 public static String codeString(String fileName,boolean print) { 99 String return_value = ""; 100 try { 101 BufferedInputStream bin = new BufferedInputStream( 102 new FileInputStream(fileName)); 103 104 int p = (bin.read() << 8) + bin.read(); 105 106 String code = null; 107 108 switch (p) { 109 case 0xefbb: 110 code = "UTF-8"; 111 break; 112 case 0xfffe: 113 code = "Unicode"; 114 break; 115 case 0xfeff: 116 code = "UTF-16BE"; 117 break; 118 case 0x5c75: 119 code = "ANSI|ASCII"; 120 break; 121 default: 122 code = "GBK"; 123 } 124 125 return_value = code; 126 } catch (Exception e) { 127 System.out.println("获取文件编码类型失败"); 128 } 129 if (print) 130 System.out.println(fileName + " code:" + return_value); 131 return return_value; 132 } 133 134 }
异常描述:
当用utf-16写入文件时,可以判断该文件的编码格式为utf-16,并且可以用utf-16的编码正确读出此文件。
当用utf-8写入文件时,判断该文件的编码格式却是gbk。但是如果用gbk编码去读文件内容,出现乱码。用utf-8编码读取时正常。
综上,我的疑问就是----------为什么用utf-8编码写入文件后,该文件的编码格式却是gbk。
求大牛。。。。。。。
有些utf-8的文件是没有BOM(Byte Order Mark,就是字节序标记)的,所以你判断的时候使用BOM来判断,自然就判断错了
只需判断txt文件。
可以实测,txt文件另存为utf-8,再用此程序跑一下。你就会发现结果的。
@扛着西瓜刀的老鼠: 你用transferFile(file_gbk,file_gbk_utf_8,"utf-8");保存文件的时候,应该是不带BOM的,所以才判断不了
你说的实测,是指在系统自带的notepad打开,并另存为utf-8吗?如果是,那么当然可以判断,因为notepad另存为utf-8的时候会带BOM
@诶碧司: 恩,是这样的。
现在的功能是需要将txt转为pdf文档。但是发现gbk编码的txt无法转换。
而utf-8编码的(带bom)才可以转换。
怎么写入utf-8时带上bom呢。
-------废话-----》结帖时过早了。发现加上bom头还是不对,文件后面还有一个特殊尾巴不好处理。
那么怎么写入时加上bom尾呢。求赐教
@诶碧司:
加上bom的byte就可以了,之前加错编码了。
多谢你。
编码使用错了,读出的内容肯定会乱码
你在windows下可以使用UltraEdit获取其他工具查看文件的二进制内容
至于文件开头的FEFF这个标识是针对文本文件加的编码识别标识
UTF-8下汉字一般3个字节,GBK汉字2个字节,这些交错使用肯定就乱码了
编码怎么错了。
转码的思路我是这样理解的:
gbk<------可逆过程------->unicode(java String)<------可逆过程------->utf-8。
哪有问题,求赐教。
将文本内容以utf-8编码写入txt文本时,只是写入文本本身的utf-8编码内容。
通过导出txt文本的二进制数据,发现txt二进制数据前24表示此txt的编码方式。
那么将gbk编码的txt文档转换到utf-8编码的txt文档就有了方法。
--------->
二级制数据读写流:写入“111011111011101110111111”加上原文件内容的二进制流
你写入的“111011111011101110111111”,就是utf-8的BOM,三个字节的值”ef bb bf“