java 清除 bom
参考工具 http://akini.mbnet.fi/java/unicodereader/
Utf8BomRemover 清除bom的方法
package cn.com.do1.component.common.util;import java.io.*;import java.nio.charset.Charset;public class Utf8BomRemover {/*** 读取流中前面的字符,看是否有bom,如果有bom,将bom头先读掉丢弃** @param in* @return* @throws java.io.IOException*/public static InputStream getInputStream(InputStream in) throws IOException {PushbackInputStream testin = new PushbackInputStream(in);int ch = testin.read();if (ch != 0xEF) {testin.unread(ch);} else if ((ch = testin.read()) != 0xBB) {testin.unread(ch);testin.unread(0xef);} else if ((ch = testin.read()) != 0xBF) {throw new IOException("错误的UTF-8格式文件");} else {// 不需要做,这里是bom头被读完了// // System.out.println("still exist bom");}return testin;}/*** 根据一个文件名,读取完文件,干掉bom头。** @param fileName* @throws java.io.IOException*/public static void trimBom(String fileName) throws IOException {FileInputStream fin = new FileInputStream(fileName);// 开始写临时文件InputStream in = getInputStream(fin);ByteArrayOutputStream bos = new ByteArrayOutputStream();byte b[] = new byte[4096];int len = 0;while (in.available() > 0) {len = in.read(b, 0, 4096);// out.write(b, 0, len);bos.write(b, 0, len);}in.close();fin.close();bos.close();// 临时文件写完,开始将临时文件写回本文件。System.out.println("[" + fileName + "]");FileOutputStream out = new FileOutputStream(fileName);out.write(bos.toByteArray());out.close();System.out.println("处理文件" + fileName);}public static void main(String[] args) throws IOException {//刪除指定文件夾下(含子文件夾)所有java文件的BOM,若構造器中參數為null則刪除所有文件頭部BOMnew Utf8BomRemover( "java" ).start( "\"F:\\\\flwork\\\\gmmsDGYH\\\\src\\\\com");}/*** 根据一个文件名,读取完文件,干掉bom头2 这里使用了第三方类UnicodeReader** @throws java.io.IOException*/public void saveFile(String file) throws IOException {InputStream in= new FileInputStream( file);BufferedReader bre = null;OutputStreamWriter pw = null;//定义一个流CharArrayWriter writer = new CharArrayWriter();//这一句会读取BOM头//bre = new BufferedReader(new InputStreamReader(in, "UTF-8"));//这一句会干掉BOM头bre = new BufferedReader(new UnicodeReader(in, Charset.defaultCharset().name()));//String line = bre.readLine();while(line != null){writer.write(line);/*加上这段代码可以查看更详细的16进制byte[] allbytes = line.getBytes("UTF-8");for (int i=0; i < allbytes.length; i++){int tmp = allbytes[i];String hexString = Integer.toHexString(tmp);// 1个byte变成16进制的,只需要2位就可以表示了,取后面两位,去掉前面的符号填充hexString = hexString.substring(hexString.length() -2);System.out.print(hexString.toUpperCase());System.out.print(" ");}*/line = bre.readLine();}writer.flush();bre.close();FileWriter f2 = new FileWriter(file);writer.writeTo(f2);f2.close();writer.close();}private String extension = null ;public Utf8BomRemover(String extension) {super ();this .extension = extension;}/** 啟動對某個文件夾的篩選 */@SuppressWarnings ( "unchecked" )public void start(String rootDir) throws IOException {traverseFolder2(rootDir);}public void traverseFolder2(String path) throws IOException {File file = new File(path);if (file.exists()) {File[] files = file.listFiles();if (files.length == 0) {System.out.println("文件夹是空的!");return;} else {for (File file2 : files) {if (file2.isDirectory()) {System.out.println("文件夹:" + file2.getAbsolutePath());traverseFolder2(file2.getAbsolutePath());} else {remove(file2.getAbsolutePath());}}}} else {System.out.println("文件不存在!");}}/** 移除UTF-8的BOM */private void remove(String path) throws IOException {saveFile(path);trimBom(path);}}
第二种方法的UnicodeReader 类
package cn.com.do1.component.common.util;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PushbackInputStream;import java.io.Reader;/**version: 1.1 / 2007-01-25- changed BOM recognition ordering (longer boms first)网络地址:http://koti.mbnet.fi/akini/java/unicodereader/UnicodeReader.java.txtOriginal pseudocode : Thomas WeidenfellerImplementation tweaked: Aki Nieminenhttp://www.unicode.org/unicode/faq/utf_bom.htmlBOMs:00 00 FE FF = UTF-32, big-endianFF FE 00 00 = UTF-32, little-endianEF BB BF = UTF-8,FE FF = UTF-16, big-endianFF FE = UTF-16, little-endianWin2k Notepad:Unicode format = UTF-16LE***//*** Generic unicode textreader, which will use BOM mark* to identify the encoding to be used. If BOM is not found* then use a given default or system encoding.*/public class UnicodeReader extends Reader {PushbackInputStream internalIn;InputStreamReader internalIn2 = null;String defaultEnc;private static final int BOM_SIZE = 4;/**** @param in inputstream to be read* @param defaultEnc default encoding if stream does not have* BOM marker. Give NULL to use system-level default.*/UnicodeReader(InputStream in, String defaultEnc) {internalIn = new PushbackInputStream(in, BOM_SIZE);this.defaultEnc = defaultEnc;}public String getDefaultEncoding() {return defaultEnc;}/*** Get stream encoding or NULL if stream is uninitialized.* Call init() or read() method to initialize it.*/public String getEncoding() {if (internalIn2 == null) return null;return internalIn2.getEncoding();}/*** Read-ahead four bytes and check for BOM marks. Extra bytes are* unread back to the stream, only BOM bytes are skipped.*/protected void init() throws IOException {if (internalIn2 != null) return;String encoding;byte bom[] = new byte[BOM_SIZE];int n, unread;n = internalIn.read(bom, 0, bom.length);if ( (bom[0] == (byte)0x00) && (bom[1] == (byte)0x00) &&(bom[2] == (byte)0xFE) && (bom[3] == (byte)0xFF) ) {encoding = "UTF-32BE";unread = n - 4;} else if ( (bom[0] == (byte)0xFF) && (bom[1] == (byte)0xFE) &&(bom[2] == (byte)0x00) && (bom[3] == (byte)0x00) ) {encoding = "UTF-32LE";unread = n - 4;} else if ( (bom[0] == (byte)0xEF) && (bom[1] == (byte)0xBB) &&(bom[2] == (byte)0xBF) ) {encoding = "UTF-8";unread = n - 3;} else if ( (bom[0] == (byte)0xFE) && (bom[1] == (byte)0xFF) ) {encoding = "UTF-16BE";unread = n - 2;} else if ( (bom[0] == (byte)0xFF) && (bom[1] == (byte)0xFE) ) {encoding = "UTF-16LE";unread = n - 2;} else {// Unicode BOM mark not found, unread all bytesencoding = defaultEnc;unread = n;}//System.out.println("read=" + n + ", unread=" + unread);if (unread > 0) internalIn.unread(bom, (n - unread), unread);// Use given encodingif (encoding == null) {internalIn2 = new InputStreamReader(internalIn);} else {internalIn2 = new InputStreamReader(internalIn, encoding);}}public void close() throws IOException {init();internalIn2.close();}public int read(char[] cbuf, int off, int len) throws IOException {init();return internalIn2.read(cbuf, off, len);}}
浙公网安备 33010602011771号