java读取文件多平台下乱码问题

最近发现java读取文件在window下正常.但有时在linux就乱码.于是花了点时间找了一下.

 

以下面的代码为例

FileReader fileReader = null;
BufferedReader bufferedReader = null;
fileReader = new FileReader("");
bufferedReader = new BufferedReader(fileReader);

 

FileReader类看了一下源码.其它就是继承InputStreamReader类.而且不能设置字符编码,在多平台很容易出现乱码问题.

所以个人不推荐使用.

 

接着看InputStreamReader类,默认不传编译的构造方法.FileReader也是使用这个方法.

    public InputStreamReader(InputStream in) {
	super(in);
        try {
	    sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
        } catch (UnsupportedEncodingException e) {
	    // The default encoding should always be available
	    throw new Error(e);
	}
    }

 

 

这里又扯到StreamDecoder类.再跟进去看看

 

  public static StreamDecoder forInputStreamReader(InputStream paramInputStream, Object paramObject, String paramString)
    throws UnsupportedEncodingException
  {
    String str = paramString;
    if (str == null)
      str = Charset.defaultCharset().name();
    try {
      if (Charset.isSupported(str))
        return new StreamDecoder(paramInputStream, paramObject, Charset.forName(str)); 
    } catch (IllegalCharsetNameException localIllegalCharsetNameException) {
    }
    throw new UnsupportedEncodingException(str);
  }

 

接下来关键为如果不传字符编码用Charset.defaultCharset().name();来取的字符编译来做为默认编码.

跟进Charset类的defaultCharset方法.

  public static Charset defaultCharset()
  {
    if (defaultCharset == null) {
      synchronized (Charset.class) {
        GetPropertyAction localGetPropertyAction = new GetPropertyAction("file.encoding");

        String str = (String)AccessController.doPrivileged(localGetPropertyAction);
        Charset localCharset = lookup(str);
        if (localCharset != null)
          defaultCharset = localCharset;
        else
          defaultCharset = forName("UTF-8");
      }
    }
    return defaultCharset;
  }

 

public class GetPropertyAction
  implements PrivilegedAction<String>
{
  private String theProp;
  private String defaultVal;

  public GetPropertyAction(String paramString)
  {
    this.theProp = paramString;
  }

  public GetPropertyAction(String paramString1, String paramString2)
  {
    this.theProp = paramString1;
    this.defaultVal = paramString2;
  }

  public String run()
  {
    String str = System.getProperty(this.theProp);
    return str == null ? this.defaultVal : str;
  }
}

 

跟了这么多,关键就是默认字符编码为 System.getProperty("file.encoding");

 

window中文版一般取出的值的GBK,而linux则要看设置去.

所以当你使用FileReader类去读取一个GBK文件时,你会发现在window上是正常的.但在linux下不一定正常.

而且FileReader无法设置字符编码.很蛋疼的一个类.很容易出现乱码的类.个人强烈推荐不再使用这个类.

 推荐直接使用InputStreamReader类.并指定字符编码.

bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "GBK"));

  

你可能感兴趣的:(java读取文件)