最近用Java处理文件的时候,同样遇到了中文问题,觉得还是有必要总结一下,也使该系列的文章更加完整。
熟悉Java 的人都知道,在Java中,IO是分成两大部分的,分别对应字节和字符的操作,也就是Stream和Character,它们之间可以相互转换,桥梁就是StreamInputReader/StreamOutputWriter。为了更加清楚的了解它们之间的关系,我们可以看看它们所在的类结构。
java.lang.Object
- java.io.InputStream (implements java.io.Closeable)
- java.io.OutputStream (implements java.io.Closeable, java.io.Flushable)
- java.io.RandomAccessFile (implements java.io.Closeable, java.io.DataInput, java.io.DataOutput)
- java.io.Reader (implements java.io.Closeable, java.lang.Readable)
- java.io.BufferedReader
- java.io.InputStreamReader
- java.io.Writer (implements java.lang.Appendable, java.io.Closeable, java.io.Flushable)
- java.io.BufferedWriter
- java.io.OutputStreamWriter
上面列出来的并不是Java.io中全部的类,但是对于文件读写来说已经足够了。通常,我们使用以下代码来进行文件的读写:
java 代码
- public void naiveWrite() throws IOException{
- FileWriter fw = new FileWriter("test.txt");
- fw.write("中文你好");
- fw.close();
- }
-
- public String naiveRead() throws IOException{
- FileReader fr = new FileReader("test.txt");
- BufferedReader br = new BufferedReader(fr);
- String str = br.readLine();
- br.close();
- fr.close();
- return str;
- }
如果我们的是中文平台,上面代码是可以正常运行的。但是如果我们把这些代码放到一个ISO8859-1的系统上,中文问题就出来了(当然,前提你在javac的时指定了编码方式,如javac -encoding gb2312 ***.java,参看该系列前面的文章)。为什么呢?这是因为FileWriter和FileReader是辅助类,为了方便大家使用 OutputSteamWriterer 和 InputStreamReader 而屏蔽了字符集的设定操作,而采用系统默认的编码方式,而这在很多情况下也能满足用户的需求。在中文系统中,系统的默认编码方式一般是GBK,因此文件中中文的读写是没有问题的。但是,当程序运行在ISO8859-1的系统中时,JVM使用ISO8859-1对中文进行编码,当然就认不到了,于是那一个个的问号就来了。
那怎么办呢?既然捷径走不通,我们就只好使用OutputSteamWriter 和 InputStreamReader了。
java 代码
- public void write() throws IOException{
- OutputStreamWriter osw = new OutputStreamWriter(
- new FileOutputStream("test.txt"), "utf-8");
- osw.write("中国万岁");
- osw.close();
- }
- public String read() throws IOException{
- InputStreamReader isr = new InputStreamReader(
- new FileInputStream("test.txt"),"utf-8");
- BufferedReader br = new BufferedReader(isr);
- String str = br.readLine();
- br.close();
- isr.close();
- return str;
- }
在这里,我们指定文件读写的编码方式为utf-8,当然对于中文来说GBK和GB2312也是可以的,但是推荐使用UTF-8,这样对于软件的国际化很有好处。其实,这里指定编码方式进行文件的写入跟我们使用记事本等编辑器的另存为,并且指定格式为“UTF-8”在本质上是一样的。通过上述处理后,程序就可以跨平台运行了。
在处理文件的过程中,我们还会用到RandomAccessFile这个类来随机访问文件。这里,如果我们写入字符串的时候调用writeChars,那么,如果写入的是中文,中文问题就又会出现了。因为此时RandomAccessFile并没有使用系统的默认编码来写入文件,而是直接将内存中的二进制数据直接写到文件中去。如何解决这个问题呢?只要读写对称就行了。
java 代码
- public void randWrite() throws IOException{
- RandomAccessFile raf = new RandomAccessFile("test1.txt","rw");
- raf.writeChars("中国你好");
- raf.close();
- }
- public String randRead() throws IOException{
- RandomAccessFile raf = new RandomAccessFile("test1.txt","r");
- StringBuffer sb = new StringBuffer();
- while( raf.getFilePointer() < raf.length()){
- sb.append( raf.readChar() );
- }
- raf.close();
- return sb.toString();
- }
但是这样处理起来不是很方便,我们可以这样写:
java 代码
- public void randWrite() throws IOException{
- RandomAccessFile raf = new RandomAccessFile("test1.txt","rw");
- raf.writeUTF("中国你好");
- raf.close();
- }
- public String randRead() throws Exception{
- RandomAccessFile raf = new RandomAccessFile("test1.txt","r");
- String str = raf.readUTF();
- raf.close();
- return str;
- }
好了,文件读写的中文问题就解决了。
分享到:
相关推荐
《深入浅出Java》这本书以其独特的讲解方式,旨在让学习者轻松掌握复杂的Java编程语言。"深入浅出"这一理念,意味着作者通过直观、生动的示例和丰富的图解,帮助读者逐步理解Java的核心概念和技术。 Java是一种广泛...
《深入浅出Java语言程序设计》这本书旨在帮助初学者和有一定经验的程序员深入理解Java语言的核心概念和技术,从而能够熟练地进行Java程序开发。 本书首先会从Java的基础知识入手,包括Java的安装与配置环境,解释...
《深入浅出JAVA》这本书是为那些希望深入了解Java编程语言的初学者和有一定经验的开发者量身打造的。书中的内容全面且深入,旨在帮助读者巩固基础,理解Java的核心概念,提升编程技能。 首先,书中的第一章通常会...
在深入浅出的讲解中,本书涵盖了Java编程的基础知识,包括: 1. **Java简介**:首先介绍Java的历史背景、特点以及为什么选择Java作为学习的编程语言。书中可能以生动的故事或比喻解释,帮助读者理解Java在软件开发...
《深入浅出Java语言程序设计》是一本专为初学者和有一定基础的程序员设计的教程,旨在通过由浅入深的方式,系统性地讲解Java编程的核心概念和技术。这本书的特色在于其详细的解释和通俗易懂的语言,使得学习者能够...
《深入浅出Java2面向对象程序设计》是一本旨在帮助读者深入理解Java编程语言和面向对象编程概念的书籍。随书附带的光盘包含了源代码、习题解答以及实验工具,为学习者提供了丰富的实践资源,使得理论与实践相结合,...
《深入浅出Java2源代码》是一本专为Java初学者和进阶者设计的教材,旨在通过深入解析Java2的源代码,帮助读者更好地理解并掌握这门强大的编程语言。光盘中包含的源代码是书中实例和讲解的重要组成部分,它们提供了...
【标题】"Java深入浅出哥哥复合管"可能是指一个关于Java编程的教程或课程,其中"哥哥复合管"可能是作者或讲师的别称,或者是某种特定编程概念的比喻。这个标题暗示了内容将深入讲解Java语言,并可能涵盖一些高级或...
《Spring-Boot深入浅出》是一本专注于Spring Boot框架的深度解析书籍,旨在帮助开发者全面理解和熟练运用这一现代Java开发的利器。Spring Boot以其“起步依赖”、“内嵌服务器”和“自动配置”等特性,极大地简化了...
7. **I/O流**:学习输入/输出流的概念,包括文件读写、对象序列化和网络数据传输。 8. **多线程**:理解并发编程,如何创建和管理线程,以及同步和互斥的概念。 9. **接口与抽象类**:区分接口和抽象类的区别,...
《深入浅出Java语言程序设计》是一本专为学习和理解Java编程语言而编写的教材。这本书的内容丰富,涵盖了从基础语法到高级特性的全面解析,旨在帮助读者深入理解Java编程的核心概念和技术。 首先,Java作为一门面向...
《深入浅出Java语言程序设计》是一本专为学习和理解Java编程语言而设计的教材。这本书涵盖了从基础到高级的Java编程概念,旨在帮助读者深入理解Java的各个方面,从而能够熟练地进行软件开发。 首先,Java语言是面向...
《深入浅出MappedByteBuffer》这篇文章主要探讨了Java NIO中MappedByteBuffer这一高效处理大文件的机制,以及与其相关的计算机内存管理概念。首先,我们来详细理解一下这些知识点。 内存管理是计算机系统的重要组成...
《深入浅出NIO》 在Java编程领域,NIO(New Input/Output)是一种用于替代标准IO模型的机制,其核心在于非阻塞的I/O操作和通道(Channel)及缓冲区(Buffer)的使用。传统的IO模型,如描述中的“阻塞I/O”,在读写...
这份"Java基础知识精讲"的资料深入浅出地介绍了Java的核心概念,是初学者理想的入门指南。以下将详细介绍其中可能涵盖的知识点。 1. **Java简介**:讲解Java的发展历史,其跨平台的特性(Write Once, Run Anywhere...
【云计算分布式大数据Hadoop深入浅出案例驱动实战】是一门以实战为导向的课程,由资深IT专家王家林老师主讲。课程的核心是通过案例教学,帮助学员掌握Hadoop这一强大的分布式大数据处理框架,适用于互联网企业、金融...
本精讲将深入浅出地探讨Java的基础知识,旨在为初学者提供一个全面且易理解的学习路径。 1. **Java简介**:Java是由Sun Microsystems(现为Oracle Corporation)于1995年发布的,它的设计目标是“一次编写,到处...