目录
尽管Java中字节流的功能十分强大,几乎可以直接或简介地处理任何类型的输入/输出操作,但利用它却不能直接操作16位的Unicode字符。这就要用到字符流。
字符输入流
Reader类是所有字符流输入类的父类,该类定义了许多方法,这些方法对所有子类都是有效的。
Reader类的常用子类如下:
CharArrayReader
类: 将字符数组转换为字符输入流,从中读取字符
StringReader
类: 将字符串转换为字符输入流,从中读取字符
BufferedReader
类: 为其他字符输入流提供读缓冲区
PipedReader
类: 连接到一个PipedWriter
InputStringReader
类: 将字节输入流转换为字符输入流,可以指定字符编码
与InputStream
类相同,在Reader类中也包含close()、mark()、skip()和reset()等方法,这些方法可以参考InputStream
类的方法
Reader类中的read()方法
方法名及返回值类型 | 说明 |
---|---|
int read() | 从输入流中读取一个字符,并把它转换为0-65535的整数。如果返回-1则表示已经到了输入流的末尾 |
int read(char[] cbuf) | 从输入流中读取若干个字符,并把它们保存到参数cbuf指定的字符数组中。该方法返回读取的字符数,如果返回-1,则表示已经到了输入流的末尾 |
int read(char[] cbuf, int off, int len) | 从输入流中读取若干个字符,并把它们保存到参数cbuf指定的字符数组中。其中,off指定在字符数组中开始保存数据的起始下标,len指定读取的字符数。该方法返回实际读取的字符数,如果返回-1,则表示已经到了输入流的末尾 |
字符输出流
与Reader类相反,Writer类是所有字符输出流的父类,该类中有许多方法,这些方法对继承该类的所有子类都是有效的。
Writer类的常用子类如下:
CharArrayWriter
类: 向内存缓冲区的字符串数组写数据
StringWriter
类: 向内存缓冲区的字符串(StringBuffer
)写数据
BufferedWriter
类: 为其他字符输出流提供写缓冲区
PipedWriter
类: 连接到一个PipedReader
OutputStreamReader
类: 将字节输出流转换为字符输出流,可以指定字符编码
与OutputStream
类相同,Writer类也包含close()、flush()等方法,这些方法可以参考OutputStream
类的方法。
方法名及返回值类型 | 说明 |
---|---|
void write(int c) | 向输出流中写入一个字符 |
void write(char[] cbuf) | 把参数cbuf指定的字符数组中的所有字符写到输出流中 |
void write(char[] cbuf, int off, int len) | 把参数cbuf指定的字符数组中的若干字符写到输出流中。其中,off指定字符数组中的起始下标,len表示元素个数 |
void write(String str) | 向输出流中写入一个字符串 |
void write(String str, int off, int len) | 向输出流中写入一个字符串中的部分字符。其中,off指定字符串的起始偏移量,len表示字符个数 |
append(char c) | 将参数c指定的字符添加到输出流中 |
append(charSequence esq) | 将参数esq指定的字符序列添加到输出流中 |
append(charSequence esq, int start, int end) | 将参数esq指定的字符序列的子序列添加到输出流中。其中,start指定子序列的第一个字符的索引,end指定子序列中最后一个字符后面的字符的索引,也就是说子序列的内容包含start索引处的字符,但不包含end索引处的字符 |
注意: Writer类所有的方法在出错的情况下都会引发IOException
异常。关闭一个流后,再对其进行任何操作都会产生错误。
字符文件输入流
为了读取方便,Java提供了用来读取字符文件的便捷类——FileReader
。该类的构造方法有如下两种重载形式
FileReader(File file)
: 在给定要读取数据的文件的情况下创建一个新的FileReader
对象。其中,file表示要从中读取数据的文件
FileReader(String fileName)
: 在给定从中读取数据的文件名的情况下创建一个新FileReader
对象。其中,fileName
表示要从中读取数据的文件的名称,表示的是一个文件的完整路径。
在用该类的构造方法创建FileReader
读取对象时,默认的字符编码及字节缓冲区大小都是有系统设定的。要自己指定这些值,可以在FileInputStream
上构造一个InputStreamReader
注意: 在创建FileReader
对象时可能会引发一个FileNotFoundException
异常,因此需要使用try-catch语句捕获该异常
字符流和字节流的操作步骤相同,都是首先创建输入流或者输出流对象,即建立连接管道,建立完成后进行读或写操作,最后关闭输入/输出流通道。
public class Test5 {
public static void main(String[] args) {
FileReader f1 = null;
try {
f1 = new FileReader("D:\\JAVA study\\A2.java");
//创建FileReader对象
int i =0;
System.out.println("D:\\JAVA study\\
A2.java文件内容如下:");
while((i=f1.read())!=-1) {
//循环读取
System.out.print((char)i);
//将读取的内容强制转换为char类型
}
} catch (Exception e) {
System.out.print(e);
}finally {
try {
f1.close();
//关闭对象
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// 输出为:
D:\JAVA study\A2.java文件内容如下:
public class A2{
public static void main(String[] args){
int num =3;
int num1=34;
System.out.println(num>>2);//除法
System.out.println(num<<2);//乘法
System.out.println(num&3);
System.out.println(num&1);//获取二进制最低位数字 判断奇数偶数
System.out.println("是奇数吗?"+((num&1)==1));
System.out.println((num1<50)&(num<37));
System.out.println((num1>50)&(num1++>37));
System.out.println(num1);
System.out.println(num|5);
}
如上述代码,首先创建了FileReader
字符输入流对象f1,该对象指向D:\JAVA study\A2.java文件,然后定义变量 i 来接收调用read()方法的返回值,即读取的字符。在while循环中,每次读取一个字符赋给整型变量 i ,直到读取到文件末尾时推出循环(当输入流读取到文件末尾时,会返回值-1)
字符文件输出流
Java提供了写入字符文件的便捷类——FileWriter
,该类的构造方法有如下4中重载形式。
FileWriter(File file)
: 在指定对象的情况下构造一个FileWriter
对象。其中,file表示要写入数据的File对象
FileWriter(File file, boolean append)
: 在指定File对象的情况下构造一个FileWriter
对象,如果append为true,则将字符写入文件末尾,而不是写入文件开始处。
FileWriter(String fileName)
: 在指定文件名的情况下构造一个FileWriter
对象。其中,fileName
表示要写入字符的文件名,表示的是完整路径。
FileWriter(String fileName, boolean append)
: 在指定文件名以及要写入文件的位置的情况下构早FileWriter
对象。其中,append是一个boolean值,如果为true,则将数据写入文件末尾,而不是文件开始处。
在创建FileWriter
对象时,默认字符编码和默认字节缓冲区区大小都是由系统设定的。要自己指定这些值,可以在FileOutputStream
上构造一个OutputStreamWriter
对象。
FileWriter
类的创建不依赖于文件存在与否,如果关联文件不存在,则会自动生成一个新的文件。在创建这个文件之前,FileWriter
将在创建对象时打开它作为输出。如果试图打开一个只读文件,将引发一个IOException
异常
编写一个程序,将用户输入的4个字符串保存到D:\JAVA study\A4.java文件中。在这里使用FileWriter()
类中的 write()方法循环向指定文件中写入数据
public class Test6 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
FileWriter f1 = null;
try {
f1 = new FileWriter("D:\\JAVA study\\A4.java");
//创建FileWriter对象
for(int i=0;i<4;i++) {
System.out.println("请输入第"+(i+1)+
"个字符串");
String name = input.next();
f1.write(name+"\r\n");
}
System.out.println("录入完成!");
} catch (IOException e) {
System.out.println(e.getMessage());
}finally {
try {
f1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// 请输入第1个字符串
我是断勃闻
请输入第2个字符串
我是笋温姐
请输入第3个字符串
我是豆锅清
请输入第4个字符串
我是芹卿清
录入完成!
//文件D:\\JAVA study\\A4.java中内容为
我是断勃闻
我是笋温姐
我是豆锅清
我是芹卿清
字符缓冲区输入流
BufferedReader
类主要用于辅助其他字符输入流,它带有缓冲区,可以先将一批数据读到内存缓冲区。接下来的读操作就可以直接从缓冲区中获取数据,而不需要每次都从数据源读取数据并进行字符编码转换,这样就可以提高数据的读取效率。
BufferedReader
类的构造方法有如下两种重载形式
BufferedReader(Reader in)
: 创建一个BufferedReader
来修饰参数in指定的字符输入流
BufferedReader(Reader in, int size)
: 创建一个BufferedReader
来修饰参数in指定的字符输入流,参数size则用于指定缓冲区的大小,单位为字符。
除了可以为字符输入流提供缓冲区以外,BufferedReader
还提供了readLine()
方法,该方法返回包含该行内容的字符串,但该字符串中不包含任何终止符,如果已达到流末尾,则返回null。readLine()
方法表示每次读取一行文本内容,当遇到换行(\n)、回车(\r)或回车后直接跟着换行标记符即可认为某行已终止。
使用BufferedReader
类中的readLine()
方法逐行读取D:\JAVA study\A4.java文件中的内容,并将读取的内容在控制台中打印输出
public class Test7 {
public static void main(String[] args) {
FileReader f1 = null;
BufferedReader f2 = null;
try {
f1 = new FileReader("D:\\JAVA study\\A4.java");
//创建FileReader对象
f2 = new BufferedReader(f1);
//创建BufferedReader对象
System.out.println("D:\\JAVA study\\A4.java文件内容如下:");
String strLine = "";
while((strLine = f2.readLine())!=null) {
//循环读取每行数据
System.out.println(strLine);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
f1.close();
//关闭FileReader对象
f2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//输出为:
D:\JAVA study\A4.java文件内容如下:
我是断勃闻
我是笋温姐
我是豆锅清
我是芹卿清
如上述代码,首先分别创建了名称为f1的FileReader
对象和名称为f2的BufferedReader
对象,然后调用BufferedReader
对象的readLine()
方法逐行读取文件中的内容。如果读取的文件内容为Null,即表明已经读取到文件尾部,此时退出循环不在进行读取操作。最后将文件输入流和带缓冲的字符输入流关闭。
字符缓冲区输出流
BufferedWriter
类主要用于辅助其他字符输出流,它同样带有缓冲区,可以先将一批数据写入缓冲区,当缓冲满了以后,再将缓冲区的数据一次性写到字符输出流,其目的是提高数据的写效率。
BufferedWriter
类的构造的方法有如下两种重载形式
BufferedWriter(Writer out)
: 创建一个 BufferedWriter
来修饰参数指定的字符输出流
BufferedWriter(Writer out, int size)
: 创建一个BufferedWirter
来修饰参数out指定的字符输出流,参数size则用于指定缓冲区的大小,单位为字符
该类除了可以给字符输出流提供缓冲区之外,还提供了一个新方法newLine()
,该方法用于写入一个行分隔符。行分隔符字符串由系统属性 line.separator
定义,并且不一定时单个新行(\n)符。