Java文件读取器编码问题
我试图使用java.io.FileReader读取一些文本文件并将其转换为字符串,但我发现结果编码错误,根本不可读 这是我的环境:Java文件读取器编码问题,java,file,unicode,encoding,Java,File,Unicode,Encoding,我试图使用java.io.FileReader读取一些文本文件并将其转换为字符串,但我发现结果编码错误,根本不可读 这是我的环境: Windows 2003,操作系统编码:CP1252 Java 5.0 我的文件是UTF-8编码或CP1252编码的,其中一些(UTF-8编码的文件)可能包含中文(非拉丁)字符 我使用以下代码来完成我的工作: private static String readFileAsString(String filePath) throws java.io
- Windows 2003,操作系统编码:CP1252
- Java 5.0
private static String readFileAsString(String filePath)
throws java.io.IOException{
StringBuffer fileData = new StringBuffer(1000);
FileReader reader = new FileReader(filePath);
//System.out.println(reader.getEncoding());
BufferedReader reader = new BufferedReader(reader);
char[] buf = new char[1024];
int numRead=0;
while((numRead=reader.read(buf)) != -1){
String readData = String.valueOf(buf, 0, numRead);
fileData.append(readData);
buf = new char[1024];
}
reader.close();
return fileData.toString();
}
上面的代码不起作用。我发现文件阅读器的编码是CP1252,即使文本是UTF-8编码的。但是java.io.FileReader的JavaDoc说:
此类的构造函数假定
这是默认的字符编码
默认字节缓冲区大小为
合适
这是否意味着如果我使用FileReader,我不需要自己设置字符编码?但我现在确实得到了错误编码的数据,正确的处理方法是什么?谢谢。是的,您需要指定要读取的文件的编码
是的,这意味着您必须知道要读取的文件的编码
不,没有通用的方法来猜测任何给定的“纯文本”文件的编码
始终使用平台默认编码,这通常不是一个好主意
因为Java11FileReader
还获得了接受编码的构造函数:and
在早期版本的java中,您需要使用
,)
FileReader
使用java的平台默认编码,这取决于运行该语言环境的计算机的系统设置,通常是该语言环境中用户最常用的编码
如果此“最佳猜测”不正确,则必须明确指定编码。不幸的是,
FileReader
不允许这样做(API中的主要疏忽)。相反,您必须使用新的InputStreamReader(新的FileInputStream(filePath),encoding)
并从有关文件的元数据中理想地获取编码。由于Java 11,您可以使用:
public FileReader(String fileName, Charset charset) throws IOException;
对于Java 7+,您可以使用以下方法:
BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8);
这是所有的字符集
例如,如果您的文件位于CP1252中,请使用
以下是IO和NIO的Java编码的其他规范名称
如果您不知道文件中的编码是否准确,您可以使用一些第三方LIB,如谷歌提供的这一工具,该工具非常简洁。对于另一种语言,例如西里尔语,您可以使用以下内容:
FileReader fr = new FileReader("src/text.txt", StandardCharsets.UTF_8);
并确保您的
.txt
文件以UTF-8
(但不是默认的ANSI
)格式保存。干杯 带有InputStreamReader的FileInputStream比直接使用FileReader要好,因为后者不允许您指定编码字符集
下面是一个同时使用BufferedReader、FileInputStream和InputStreamReader的示例,这样您就可以从文件中读取行
List<String> words = new ArrayList<>();
List<String> meanings = new ArrayList<>();
public void readAll( ) throws IOException{
String fileName = "College_Grade4.txt";
String charset = "UTF-8";
BufferedReader reader = new BufferedReader(
new InputStreamReader(
new FileInputStream(fileName), charset));
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
if( line.length() == 0 ) continue;
int idx = line.indexOf("\t");
words.add( line.substring(0, idx ));
meanings.add( line.substring(idx+1));
}
reader.close();
}
List words=new ArrayList();
列表含义=新的ArrayList();
public void readAll()引发IOException{
字符串fileName=“College_grade 4.txt”;
字符串charset=“UTF-8”;
BufferedReader reader=新的BufferedReader(
新的InputStreamReader(
新文件输入流(文件名,字符集));
弦线;
而((line=reader.readLine())!=null){
line=line.trim();
如果(line.length()==0)继续;
int idx=line.indexOf(“\t”);
添加(行子字符串(0,idx));
添加(行子字符串(idx+1));
}
reader.close();
}
您还应该在循环中释放字符串.valueOf(),并直接使用StringBuffer.append(char[],int,int)。这节省了大量的char[]复制。还可以使用StringBuilder替换StringBuffer。不过,这些都不是关于你的问题,我不想这么说,但是你在粘贴部分之后读过JavaDoc吗?你知道,那部分说“要自己指定这些值,在FileInputStream上构造InputStreamReader。”?谢谢你的评论,实际上我读了JavaDoc,但我不确定的是我是否应该自己指定这些值,然后切换到“在FileInputStream上构造InputStreamReader”。是的,如果您知道该文件使用的不是平台默认编码,那么您必须告诉InputStreamReader使用哪种编码。“API中的主要疏忽”-感谢您的解释-我想知道为什么找不到我要找的构造函数!干杯John@BhanuSharma:这是另一个级别的编码问题,请检查文件名的来源,如果是硬编码,则检查编译器使用的编码。@BhanuSharma:文件名编码问题与此问题无关。请参阅许多现有的“为什么Unicode文件名不能在Java中工作”问题之一。扰流板:像FileReader这样的java.io API使用C标准库文件系统调用,这在Windows上不支持Unicode;考虑使用JavaNIO。“<代码>文件名> /CODE >使用java的平台默认编码,这取决于它运行的计算机的系统设置,并且通常是该区域中用户中最流行的编码。“我不会这么说。至少有两扇窗户。出于一些奇怪的技术/历史原因,JVM忽略了一个事实,即Unicode是Windows上“所有新应用程序”的编码,而总是将配置为旧应用程序后备的旧编码视为“平台默认值”。我甚至会说,如果Java应用程序在每次读取或写入时都没有显式指定编码文件/流/资源,它已损坏,因为它无法可靠地工作。InputStream is=new FileInputStream(filename);在这里,我得到了错误文件not found error,俄文文件名为+1,建议使用InputStreamReader,但是在代码块中使用链接会使复制和粘贴代码变得困难,如果可以更改,ThxB会吗
List<String> words = new ArrayList<>();
List<String> meanings = new ArrayList<>();
public void readAll( ) throws IOException{
String fileName = "College_Grade4.txt";
String charset = "UTF-8";
BufferedReader reader = new BufferedReader(
new InputStreamReader(
new FileInputStream(fileName), charset));
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
if( line.length() == 0 ) continue;
int idx = line.indexOf("\t");
words.add( line.substring(0, idx ));
meanings.add( line.substring(idx+1));
}
reader.close();
}