当前位置:课程学习>>第七章 输入输出流>>文本学习>>知识点二


知识点二  字符流




对于像汉字这样的双字节字符处理,仅有字节流是不方便的,这是因为基本的处理单位不是1字节,而是2字节。由于Java语言中字符是用Unicode双字节表示的,因而在java.io包中提供了专门用于字符流处理的类。以Reader为根类的所有类用于字符的输入,以Writer为根类的所有类用于字符的输出。

Reader类和Writer

Reader和Writer是面向字符输入的,它们以字符(16位)为单位读写,因此效率较InputStream和OutputStream类高。Java建议在可能的情况下,尽量用Reader和Writer。下列表中列出了Reader类和Writer类的常用方法。

表7.5 Reader类的常用方法

方法

描述

Public int read() throws IOException

返回字符输入流中读取一个Unicode字符。若读到流结束,则返回-1。若流中暂时无字符可读,则该方法进入阻塞状态

Public int read(char cbuf[]) throws IOException

将cbuf.length字符读入到数组cbuf中,返回实际读入的字符数。若读到流结束,则返回-1。若流中暂时无字符可读,则该方法进入阻塞状态

Public abstract int read(char cbuf[],int off,int len) throws IOException

将len字符读入到数组cbuf[]中,返回实际读入的字符数。若读到流结束,则返回-1。若流中暂时无字符可读,则该方法进入阻塞状态

Public Boolean marksupported()

若流支持mark()操作则返回true,否则返回false

Public void mark(int readAheadLimit) throws IOException

给当前流作为标记,最多支持readAheadLimit字符的回溯

Public void reset() throws IOException

将当前流重置到标记处。注:不是所有的字符流都支持mark()和reset()

Public abstract void close() throws IOException

关闭流,进一步的读取将会产生IOException异常

表7.6 Writer类的常用方法

方法

描述

Public void write(int c) throws IOException

将c的低16位写入输出流中,高16位丢弃

Public void write(char[] cbuf) throws IOEception

将字符数组cbuf[]中的所有字符全写到输出流中

Public abstract void write(char cbuf[],int off,int len) throws IOException

将字符数组cbuf[]中从索引off位置处开始的len字符写入到输出流中

Public void write(String s) throws IOException

将字符串s中的所有字符写入到输出流中

Public void write(String str,int off,int len) throws IOException

将字符串str中从索引off开始处的len字符写入到输出流中

Public abstract void flush() throws IOException

刷空输出流,将所有被缓存的字符全写到输出流中

Public abstract void close() throws IOException

先将所有被缓存的字符全写到输出流中,然后关闭流。

二、InputStreamReaderOutputStreamWriter

字符流是建立在字节流基础之上的,Java语言内部可将一个字节流按照某种

编码规范转换成字符流,这方面的转换是由字节流与字符流转换的桥类InputStreamReader和OutputStreamWriter来完成的。

(1) InputstreamReader类的构造方法:

      Public InputStreamReader(InputStream in)

使用当前平台默认的编码规范,将字节输入流in转换成一个字符输入流。

(2) OutputStreamWriter类的构造方法:

      Public OutputStreamWriter(OutputStream out)

使用当前平台默认的编码规范,将字节输出流out转换成一个字符输出流。

以下这两个方法,这两个类都支持。

      Public String getEncoding() //返回当前字符流所使用的编码规范

      Public void close() throws IOException //关闭流

【例7.12】获取当前平台默认的编码规范

1 //InStreamReaderExample.java

2 import java.io.*;

3 public class InStreamReaderExample {

4    public static void main(String[] args) {

5       InputStreamReader reader = new InputStreamReader(System.in);

6       System.out.println("默认编码规范:" + reader.getEncoding());

7    }

8 }

【例7.13】从键盘上读入汉字,打印出汉字及其Unicode代码。

1 //OutStreamWriterExample.java

2 import java.io.*;

3 public class OutStreamWriterExample {

4    public static void main(String[] args) {

5       Reader rd = new InputStreamReader(System.in);

6       int c;

7       try

8       {

9          while((c=rd.read())!=-1)

10             System.out.println("汉字是:"+(char)c+"Unicode: "+c);

11       }catch(IOException e)

12       {

13          System.out.println(e);

14       }

15   

16    }

17 }

该程序的运行结果为:

我们

汉字是:我Unicode: 25105

汉字是:们Unicode: 20204

三、FileReader类和FileWriter

对字符文件如文本文件的处理是以Unicode字符为基本单位的,尽管在理论上,任何文件都是字节文件,但以字节为单位处理字符文件有时不方便。FileReader类用于字符文件的读,每次读取一个字符或一个字符数组。FileWriter类用于字符文件的写,每次写入一个字符、一个数组或一个字符串。通常将FileReader类的对象视为一个以字符为基本单位的无格式的字符输入流,将FileWriter的对象视为一个以字符为基本单位的无格式的字符输出流。

【例7.14】文本文件的复制:将t1.txt复制到t2.tx中。

1 //FileReaderExample.java

2 import java.io.*;

3 public class FileReaderExample {

4    public static void main(String[] args) throws Exception{

5       try{

6          FileReader fr = new FileReader("E:\\teacher\\course\\java\\javabook\\t1.txt");

7          FileWriter fw = new FileWriter("E:\\teacher\\course\\java\\javabook\\t2.txt");

8          int c;

9          while((c=fr.read())!=-1)

10             fw.write(c);

11             fw.flush();

12             fr.close();

13             fw.close();

14       }catch(FileNotFoundException e)

15       {

16          System.out.println(e);

17       }

18    }

19 }

四、BufferedReader类和BufferedWriter

文本行是以回车、换行结束的字符序列,以文本行为基本单位进行文本读取与处理有时更方便。BufferedReader类和BufferedWriter类是带缓冲的字符流,可用于以文本行为为基本单位进行处理的场合,比如要求从键盘读入一个整数值123,可将键盘变成一个带缓冲的字符输入流,一下子读入串“123”,然后利用Integer.ParseInt(“123”)转换成整数123。

【例7.15】从键盘上读入一个整数值n,打印出1+2+…+n之和。

1 //BufferedReaderExample.java

2 import java.io.*;

3 public class BufferedReaderExample {

4    public static void main(String[] args) throws Exception{

5       BufferedReader kr = new BufferedReader(new    

InputStreamReader(System.in));

6       //键盘转换成一个能读取文本行的字符输入流

7       String s;

8       int n=0;

9       int sum=0,k=0;

10       System.out.println("请输入一个整数值:");

11       s=kr.readLine(); //从键盘读取一行

12       n = Integer.parseInt(s);

13       for(k=1;k<=n;k++)

14          sum=sum+k;

15       System.out.println("1+2+...+n="+sum);

16    }

17 }

五、PrintWriter

文本文件的输出流有FileWriter类,该类通常是以字符为单位写文本文件。有时需要以Java语言中的基本数据类型为单位进行文本文件的写入,如将实数值12.6以文本方式写入文本文件中。尽管使用FileWriter也能写入,但处理起来不是很方便,Java语言中引入的PrintWriter类可以很方便地进行此类文本文件的输出。PrintWriter流是文本流中使用频率很高的流。

【例7.16】将100以内的所有素数都打印到文本文件中,每行5个数,数之间用逗号分割。

1 //PrintWriterExample.java

2 import java.io.*;

3 public class PrintWriterExample {

4    public static void main(String[] args) throws Exception{

5    PrintWriter pw = new PrintWriter(new FileWriter("tp.txt"),true);

6    int k,j,cc=0;

7    again:for(k=2;k<100;k++)

8    {

9       for(j=2;j<=k/2;j++)

10       if(k%j==0) continue again; //若k不是素数则继续下一个

11          pw.print(k);

12       cc++;

13       if(cc==5) //每5个换1行

14       {

15          cc=0;

16          pw.println();

17       }

18 else

19 pw.print(","); //向文件中输出逗号

20 }

21 pw.close();

22 }

23 }

该程序的输出结果为:

2,3,5,7,11

13,17,19,23,29

31,37,41,43,47

53,59,61,67,71

73,79,83,89,97

六、File类及其应用

前面介绍的类基本上是对文件的内容进行处理,例如在文件中读取或存储数据。当需要读取数据的文件不存在时往往不能直接做出判断,而必须通过异常才能得到这种信息。类java.io.File很好地解决了这个问题。

File类是java.io程序包中的一个类,它是对文件系统中文件和文件夹的抽象,一般不涉及文件内部的具体内容,而是从整体上对文件进行处理,如获取各种各样的文件信息或删除文件。类File不仅可以对文件进行操作,还可以对路径进行操作。下面介绍File类的构造方法及常用方法。

表7.7 File类的构造方法及常用方法

方法

描述

Public File(String name)

指定与File对象关联的文件或目录的名称。Name可以包含路径信息及文件或目录名。

Pulbic File(String pathToName,String name)

使用pathToName来定位参数name所指定的文件或目录

Public File (File directory, String name)

使用现有的File对象directory(绝对路径或相对路径)来定位参数name所指定的文件或目录

Public File(URI uri)

使用给定的URI对象来定位文件

isFile()

判断指定的File实例是否是文件

isDirectory()

判断指定的File实例是否是路径

canRead()

判断当前文件是否可读

canWrite()

判断当前文件是否可写

compareTo()

按词典顺序比较两个抽象路径名或者对象

delete()

删除文件或者目录

deleteOnExit()

当虚拟机结束时删除实例所表示的文件或者文件夹

exists()

检测与文件对象实例对应的文件是否存在

getAbsoluteFile()

返回文件的绝对路径

length()

返回文件长度

list()

以数组的形式返回目录中的文件名

getName()

返回文件对象的名称

getParent()

返回字符串类型的文件对象的上级目录,如果没有则为空

getParentPath()

返回文件类型的文件对象的上级目录

getPath()

得到抽象路径名对应的路径字符串

hashCode()

为文件对象计算hash值

isAbsolute()

检测抽象路径名是否是绝对的

listFiles()

以文件数组的形式返回目录中的文件

listRoots()

返回可用的系统根目录

mkdir()

创建目录

toString()

返回文件实例的路径名

【例7.18】File类的应用示例。

1 //FileExample.java

2 import java.io.*;

3 public class FileExample {

4    public static void main(String[] args) {

5    for(int i=0;i<args.length;i++)

6    {

7       File f = new File(args[i]);

8       if(f.exists())

9       {

10          System.out.println("getName:" + f.getName());

11          System.out.println("getPath:" + f.getPath());

12          System.out.println("getAbsolutePath:" + f.getAbsolutePath());

13          System.out.println("getParent:" + f.getParent());

14          if(f.canWrite())

15             System.out.println(f.getName() + "is writable.");

16          if(f.canRead())

17             System.out.println(f.getName() + "is readable.");

18          if(f.isFile())

19             System.out.println(f.getName() + "is a file.");

20          else if(f.isDirectory())

21             System.out.println(f.getName() + "is a directory.");

22          else

23             System.out.println("What is this?");

24          if(f.isAbsolute())

25             System.out.println(f.getAbsolutePath() + "is an absolute path.");

26          else

27             System.out.println(f.getName() + "is not an absolute path.");

28          System.out.println("Last Modified:" + f.lastModified());

29          System.out.println(f.getName() + "is" + f.length() + "bytes.");

30          }

31          else

32          System.out.println("Can't find the file" + args[i]);

33       }

34    }

35 }

 

进入知识归纳学习