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

本文探讨了使用Java在Windows和Linux环境下读取文件时遇到的乱码问题,并详细分析了FileReader及InputStreamReader类的工作原理,建议使用InputStreamReader指定字符集以避免乱码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近发现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"));

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值