字符
那么在Java中的字符用char来表示,char存储字符。Java使用Unicode来表示字符。Unicode可以表示在所有人类语言中找到的所有字符。Java char是16位类型
字符的范围是 0 ~
65536 ,
没有负字符。字符可以是文字、字母数字、符号等等。
字符流
尽管Java中字节流的功能十分强大,几乎可以直接或间接地处理任何类型的输入/输出操作,但利用它却不能直接操作 16 位的 Unicode 字符。这就要用到字符流。其实字节流和字符流的方法大致一样,区别在于使用字节流时,每个文字或者是字母看作是一个字节,但是在字节流中,文字占三个字节。
输入流——Reader
Reader 是Java的IO库提供的另一个输入流接口。 和 InputStream 的区别是, InputStream 是一个字节流,即以 byte 为单位读取,而 Reader 是一个字符流,即以 char 为单位读取
Reader结构图如下
FileReader
Reader使用时需要用其子类FileReader类来创建对象
File f1 = new File("D:/a.txt");
Reader in = new FileReader(f1);
这个时候就可以使用字符流的方法read方法来对文件进行读操作
那么既然是读操作,我们要先从内存找磁盘的某个文件是否存在才能进行读取
那么我们就事先在D盘创建一个a.txt文件,并且往里面添加点文字内容
那我们在Java中用read方法就可以读取里面的字符
//文件对象
File f1 = new File("D:/a.txt");
//创建Reader对象
Reader in = new FileReader(f1);
//读操作
int read = in.read();//读取第一个汉字的Unicode值
System.out.println((char)read);//将值强转为字符
如果要读取文件里的全部数据,就需要借助循环完成,代码如下
//文件对象
File f1 = new File("D:/a.txt");
//创建Reader对象
Reader in = new FileReader(f1);
//读操作
int n;
while ((n=in.read()) != -1){
System.out.print((char)n);//将值强转为字符
}
以上就可以完成文件的全字符获取,但是有个小问题,一个一个字符循环获取字符相对计较慢,我们还可以使用我们自定意缓冲区来进行性能的增强,代码如下
package IO;
import java.io.*;
public class Test01{
public static void main(String[] args) throws IOException {
//文件对象
File f1 = new File("D:/a.txt");
//创建Reader对象
Reader in = new FileReader(f1);
//读操作
//自定义每次最大读10个字符的缓冲区
char[] chars = new char[10];
//c初始化
int n;
//判断后值是否为-1,如果为-1则没有值
while ((n=in.read(chars)) != -1){//将chars数组传进read方法里,使每次读10个字符的存放入chars数组
//使用String类将chars数组中有效个字符转化成字符串,并打印
String s = new String(chars,0,n);
System.out.print(s);
}
}
}
当然了,Java中也就给我们定义好的缓冲区
package IO;
import java.io.*;
public class Test02 {
public static void main(String[] args) throws IOException {
//文件对象
File f1 = new File("D:/a.txt");
//创建Reader对象
Reader in = new FileReader(f1);
//读操作
//BufferedReader缓冲区,传入Reader对象
BufferedReader b = new BufferedReader(in);
//n初始化
int n;
//判断后值是否为-1,如果为-1则没有值
while ((n=b.read()) != -1){
System.out.print((char)n);
}
}
}
最后是一些Reader常用方法供参考
方法摘要 | |
---|---|
abstract void | close() 关闭该流并释放与之关联的所有资源。 |
void | mark(int readAheadLimit) 标记流中的当前位置。 |
boolean | markSupported() 判断此流是否支持 mark() 操作。 |
int | read() 读取单个字符。 |
int | read(char[] cbuf) 将字符读入数组。 |
abstract int | read(char[] cbuf, int off, int len) 将字符读入数组的某一部分。 |
int | read(CharBuffer target) 试图将字符读入指定的字符缓冲区。 |
boolean | ready() 判断是否准备读取此流。 |
void | reset() 重置该流。 |
long | skip(long n) 跳过字符。 |
输出流——Writer
Writer是Java的IO库提供的另一个输出流接口,和 OutputStream 的区别是, OutputStream 是一个字节流,即以 byte 为单位读取,而 Writer是一个字符流,即以 char 为单位读取结构图如下:
FileWriter的使用
FileWriter是Writer的子类,用来完成Writer对象的创建
//文件对象
File f1 = new File("D:/a.txt");
//创建Writer对象
Writer out = new FileWriter(f1);
下一步,我们可以用write方法来对文件进行插入数据
//文件对象
File f1 = new File("D:/a.txt");
//创建Writer对象
Writer out = new FileWriter(f1);
//写入数据
out.write("你好,我是蔡徐坤");
//刷新(如不刷新相当于没有保存)
out.flush();
其他的方法我放在下面,可以参考使用
方法摘要 | |
---|---|
Writer | append(char c) 将指定字符添加到此 writer。 |
Writer | append(CharSequence csq) 将指定字符序列添加到此 writer。 |
Writer | append(CharSequence csq, int start, int end) 将指定字符序列的子序列添加到此 writer.Appendable。 |
abstract void | close() 关闭此流,但要先刷新它。 |
abstract void | flush() 刷新该流的缓冲。 |
void | write(char[] cbuf) 写入字符数组。 |
abstract void | write(char[] cbuf, int off, int len) 写入字符数组的某一部分。 |
void | write(int c) 写入单个字符。 |
void | write(String str) 写入字符串。 |
void | write(String str, int off, int len) 写入字符串的某一部分。 |
综合案例
对含有汉字的文件完成复制操作
package IO;
import java.io.*;
public class Test03 {
public static void main(String[] args) throws IOException {
//创建复制和目标文件对象
File f1 = new File("D:/a.txt");
File f2 = new File("D:/b.txt");
//创建读对象
Reader in = new FileReader(f1);
//创建写对象
Writer out = new FileWriter(f2);
//缓冲区
char[] chars = new char[10];
//初始化
int n;
//读取数据
while ((n=in.read(chars)) !=-1){
//数据的写入
out.write(chars,0,n);
}
//资源释放
out.close();
in.close();
}
}
结果如下: