bom问题,编码问题



新公司的老项目,  说起来挺那啥的还
svn上是基于eclipse的工程,我习惯了idea,便导入idea,配置好启动参数后。
启动却报了一堆莫名其妙的error

第一行,第一列有错,这显然有问题。
而且很多文件几乎是全是错误,每隔一个字母就有一个类似的error。

查了查  编码问题是无疑了。eclipse是识别BOM的,确切的说是eclipse的编译器是识别bom的
所谓bom就是文件开头的4位16进制数。用于标识文件编码格式。不懂的看这里

而用editplus等工具打开查看就更明显了

再看那个几乎全是error的文件用editplus打开看的样子


首先,明确。这是两个问题
几乎全是error是因为编码使用了UTF-16(大端序)导致,我们应该首先把它转化为UTF-8编码。
如果就一两个,可以使用editplus,UE等工具直接另存为
如:

如果太多,就得用程序批量处理了。写了个工具类,java的

package cn.xiaozhi.tools;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;

public class ConvertEncode {
	public static void main(String[] args) {
		new ConvertEncode().start(args[0].toString());
	}
	
	public void start(String root){
		File dir = new File(root);
		process(dir);
	}
	
	//迭代找到所有子文件
	public void process(File file){
		if(file.isFile()){
			doRemove(file);
		}else{
			File[] files = file.listFiles();
			for(File child:files){
				process(child);
			}
		}
	}

	//实际处理文件的方法,临时用,业务集中在这里 
	private void doRemove(File file){
		//读取文件
		String fileName = file.getName();
		System.out.println("----Start process:"+fileName+"---->");
		//获取文件后缀,只改java
		if(fileName.lastIndexOf(".")>-1 && "java".equalsIgnoreCase(fileName.substring(fileName.lastIndexOf(".")+1,fileName.length()))){
			//判断文件编码格式
			String code="";
			try {
				code = codeString(file);
				System.out.println(fileName+":encoding:"+code);
			} catch (Exception e1) {
				// TODO Auto-generated catch block
				System.out.println("#can't read this code");
			}
			
			//只处理UTF-16BE的
			if("UTF-16BE".equalsIgnoreCase(code)){
				String fileContent = "";
				try {
					fileContent = getFileContentFromCharset(file, code);
				} catch (Exception e) {
					System.out.println("can't read file,do next--->");
					return;
				}
				try {
					saveFile2Charset(file, "UTF-8", fileContent);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					return;
				}
			}
			System.out.println("----end process"+fileName+"----");
		}else{
			System.out.println("----Not process:"+fileName+"----");
			return;
		}
		
	}
	
	 /**
     * 以指定编码方式读取文件,返回文件内容
     *
     * @param file
     *            要转换的文件
     * @param fromCharsetName
     *            源文件的编码
     * @return
     * @throws Exception
     */
    public static String getFileContentFromCharset(File file,
            String fromCharsetName) throws Exception {
        if (!Charset.isSupported(fromCharsetName)) {
            throw new UnsupportedCharsetException(fromCharsetName);
        }
        InputStream inputStream = new FileInputStream(file);
        InputStreamReader reader = new InputStreamReader(inputStream,
                fromCharsetName);
        char[] chs = new char[(int) file.length()];
        reader.read(chs);
        String str = new String(chs).trim();
        reader.close();
        return str;
    }
 
    /**
     * 以指定编码方式写文本文件,存在会覆盖
     * 
     * @param file
     *            要写入的文件
     * @param toCharsetName
     *            要转换的编码
     * @param content
     *            文件内容
     * @throws Exception
     */
    public static void saveFile2Charset(File file, String toCharsetName,
            String content) throws Exception {
        if (!Charset.isSupported(toCharsetName)) {
            throw new UnsupportedCharsetException(toCharsetName);
        }
        file.delete();
        OutputStream outputStream = new FileOutputStream(file);
        OutputStreamWriter outWrite = new OutputStreamWriter(outputStream,
                toCharsetName);
        outWrite.write(content);
        outWrite.close();
    }
    
	/**
	 * 判断文件的编码格式
	 * @param fileName :file
	 * @return 文件编码格式
	 * @throws Exception
	 */
	public static String codeString(File fileName) throws Exception{
		BufferedInputStream bin = new BufferedInputStream(
		new FileInputStream(fileName));
		int p = (bin.read() << 8) + bin.read();
		String code = null;
		
		switch (p) {
			case 0xefbb:
				code = "UTF-8";
				break;
			case 0xfffe:
				code = "Unicode";
				break;
			case 0xfeff:
				code = "UTF-16BE";
				break;
			default:
				code = "GBK";
		}
		
		bin.close();
		return code;
	}
}


这样,先解决掉几乎全是error问题。

然后处理bom问题

贴出一个方法

 /**
     * 读取流中前面的字符,看是否有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格式文件");
        }
        return testin;

    }

就可以了

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值