赞
踩
字符流(Java IO的Reader和Writer)功能与InputStream和OutputStream非常类似,InputStream和OutputStream基于字节处理,而字符流(Reader和Writer)是基于字符处理。主要用于读写文本。
Reader类是Java IO中所有Reader的基类。子类包括FileReader,BufferedReader,InputStreamReader,StringReader和其他Reader。
FileReader类从InputStreamReader类继承而来(间接继承了Reader)。该类按字符读取流中数据。
FileReader(File file);通过打开一个到实际文件的连接来创建一个FileReader
,该文件通过文件系统中的 File
对象 file
指定。
FileReader(String fileName) ; 通过打开一个到实际文件的连接来创建一个FileReader
,该文件通过文件系统中的路径名 name
指定。
(了解)FileReader(FileDescriptor fd) ; 在给定从中读取数据的FileDescriptor
的情况下创建一个新 FileReader。
提示:FileDescriptor 是“文件描述符”。
其中有三个属性:
- in 标准输入(键盘)的描述符(从键盘输入读取流)
- out 标准输出(屏幕)的描述符(讲流输出到控制台上)
- err 标准错误输出(屏幕)的描述符(将流以红色的字体输出到控制台上)
代码示例:
try { FileWriter fw = new FileWriter(FileDescriptor.out); fw.write("我是爱你的。"); fw.flush(); fw.close(); }...
- 1
- 2
- 3
- 4
- 5
- 6
控制台输出:
test.txt 文件内容(字符长度为17)
read();读取字符输入流。读取字符输入流的下一个字符,返回一个字符。
try {
File file = new File("test.txt");
FileReader fileReader = new FileReader(file);
int read = fileReader.read();//默认第一次读取第一个字符
System.out.println((char)read);
}...
结果:
read(char cbuf[]);读取字符输入流。读取多个字符,存入字符数组cbuf,返回实际读入的字符数。
try {
File file = new File("test.txt");
FileReader fileReader = new FileReader(file);
char c [] = new char[20];
int len = fileReader.read(c);//
System.out.println("读取的字符长度为:"+len);
for (char d : c) {
System.out.print(d);
}
}...
结果:
read(char cbuf[], int off, int len);读取字符输入流。每次读取len个字符,存入字符数组cbuf,从off下标开始存储。
try {
File file = new File("test.txt");
FileReader fileReader = new FileReader(file);
char c [] = new char[20];
int len = fileReader.read(c,2,8);//读取8个字符存入c数组,从下标2开始存储
System.out.println("读取的字符长度为:"+len);
for (char d : c) {
System.out.print(d);
}
}
结果:
close();关闭当前流,释放与该流相关的资源,防止资源泄露。在带资源的try语句中将被自动调用。关闭流之后还试图读取字符,会出现IOException异常。
try {
File file = new File("test.txt");
FileReader fileReader = new FileReader(file);
int read = fileReader.read();//
System.out.println((char)read);
fileReader.close();//通过close()来关闭流,以释放系统资源。
}...
//或者在这里关闭
...finally {
if(fileReader!=null)
fileReader.close();
}
注意:
- 通常不使用close会导致内存泄露,垃圾回收机制会回收,但是最好自己显式关闭
- OutputStream的作用是如FileOutStream,当不调用close的时候,不会将缓存刷入文件中。
所以:一般使用完IO流之后都要通过close()来关闭,以释放系统资源
off
开始的 len
个字符写入此输出流。 FileWriter类从OutputStreamWriter类继承而来(间接继承Writer类)。该类按字符向流中写入数据。
FileWriter
,该文件通过文件系统中的 File
对象 file
指定。 FileWriter
,该文件通过文件系统中的 File
对象 file
指定。 如果第二个参数为true,则将字符写入文件末尾处,而不是写入文件开始处。FileWriter
,该文件通过文件系统中的路径名 name
指定。FileWriter
,该文件通过文件系统中的路径名 name
指定。如果第二个参数为true,则将字符写入文件末尾处,而不是写入文件开始处。FileDescriptor
的情况下创建一个新 FileReader。(可以向控制台输出文本流)。write (String str); 将指定的字符串写入此输出流。
try {
File file = new File("test.txt");
Writer fileWriter = new FileWriter(file);
fileWriter.write("十年之前,我不认识你。");
fileWriter.flush();
fileWriter.close();
}...
结果:
write(int c );将指定的字符写入此输出流。
try {
File file = new File("test.txt");
Writer fileWriter = new FileWriter(file);
fileWriter.write('育');
fileWriter.flush();
fileWriter.close();
}...
结果:
write(char[] cbuf);将 cbuf 字符数组写入此输出流。
try {
File file = new File("test.txt");
Writer fileWriter = new FileWriter(file);
char[] charArray = "字符串转字符数组".toCharArray();
fileWriter.write(charArray);
fileWriter.flush();
fileWriter.close();
}
结果:
write(char[] cbuf, int off, int len);将 cbuf 字符数组,按偏移量 off
开始的 len
个字符写入此输出流。
try {
File file = new File("test.txt");
Writer fileWriter = new FileWriter(file);
char[] charArray = "字符串转字符数组".toCharArray();
fileWriter.write(charArray, 1, 5);//从偏移量 1 开始,写入5个字符。
fileWriter.flush();
fileWriter.close();
}
结果:
write(String str, int off, int len);
try {
File file = new File("test.txt");
Writer fileWriter = new FileWriter(file);
String str ="字符串也可以制定写的内容";
fileWriter.write(str, 3, 5);
fileWriter.flush();
fileWriter.close();
}
结果:
(BufferedReader/BufferedWriter) 是带缓冲区的字符流,默认缓冲区大小是8Kb,能够减少访问磁盘的次数,提高文件读取性能;并且可以一次性读取一行字符。(类似管道套管道一样,不带缓冲的流只能一滴一滴流,套了管道后,可以让一滴一滴留到外面的管道后一次性流出。)
BufferedReader.readLine();在字符缓冲输入流读取字符的时候,可以一次性读取一行,并将游标指向下一行。
try {
File file = new File("test.txt");
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
String str;
while ((str = br.readLine())!=null) {
System.out.println(str);
}
}
BufferedWriter.newLine();在字符串缓冲输出流写入字符的时候,默认是在一行写入,当需要换行的时候,调用 newLine() 实现文本换行。
try {
File file = new File("test.txt");
FileWriter fw = new FileWriter(file);
BufferedWriter bw = new BufferedWriter(fw);
bw.write("写入一行的文本");
bw.newLine();//换行
bw.write("写入第二行的文本");
bw.flush();//刷新缓冲区,强制写入文件中
bw.close();
}...
字节流和字符流使用是非常相似的,那么除了操作代码的不同之外,还有哪些不同呢?
字节流在操作的时候本身是不会用到缓冲区(内存)的,是与文件本身直接操作的,而字符流在操作的时候是使用到缓冲区的
字节流在操作文件时,即使不关闭资源(close方法),文件也能输出,但是如果字符流不使用close方法的话,则不会输出任何内容,说明字符流用的是缓冲区,并且可以使用flush方法强制进行刷新缓冲区,这时才能在不close的情况下输出内容
那开发中究竟用字节流好还是用字符流好呢?
在所有的硬盘上保存文件或进行传输的时候都是以字节的方法进行的,包括图片也是按字节完成,而字符是只有在内存中才会形成的,所以使用字节的操作是最多的。
如果要java程序实现一个拷贝功能,应该选用字节流进行操作(可能拷贝的是图片),并且采用边读边写的方式(节省内存)。
最好在流前面加上缓冲流,为了提高性能和读取速度
public static void smallTOBig(File aFile, File bFile) {
if (aFile.exists()) {
try (FileReader fReader = new FileReader(aFile); FileWriter fWriter = new FileWriter(bFile);) {
char[] cbuf = new char[1024];
int read = -1;
while ((read = fReader.read(cbuf)) != -1) {
String string = new String(cbuf, 0, read);
String upperCase = string.toUpperCase();
fWriter.write(upperCase);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
File aFile = new File("test.txt");
File bFile = new File("a.txt");
smallTOBig(aFile, bFile);
}
(使用字符流实现)编写程序来实现如下功能
public static void main(String[] args) {
System.out.println("1 查看请假条 2 撰写请假条");
Scanner sc = new Scanner(System.in);
int nextInt = sc.nextInt();
switch (nextInt) {
case 1:
readMessage();
break;
case 2:
writeMessage();
break;
default:
break;
}
}
public static void readMessage() {
try (FileReader frReader = new FileReader(new File("Letter/b.txt"));) {
int read = -1;
char[] cbuf = new char[1024];
while ((read = frReader.read(cbuf)) != -1) {
String string = new String(cbuf, 0, read);
System.out.println(string);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void writeMessage() {
Scanner sc = new Scanner(System.in);
System.out.println("请假人:");
String n1 = sc.next();
System.out.println("请假日期:");
String n2 = sc.next();
System.out.println("请假原因:");
String n3 = sc.next();
try (FileWriter fWriter = new FileWriter(new File("Letter/b.txt"));) {
StringBuffer stringBuffer = new StringBuffer();
fWriter.write("请假人:" + stringBuffer.append(n1));
fWriter.write("\r\n");
fWriter.write("请假日期:" + stringBuffer.append(n2));
fWriter.write("\r\n");
fWriter.write("请假原因:" + stringBuffer.append(n3));
fWriter.write("\r\n");
} catch (IOException e) {
e.printStackTrace();
}
}
写一个程序,记录程序在运行时出现过的错误,保存成错误日志!。如:追加写入:true
在输入Int类型的时候输错,把这个记录写入到文件中。
在String 类型 转换 int类型的时候如果出错,把错误的记录写入到文件中。
格式如下:
err:2017年3月30日 15:26:33 字符串转换Int失败 不能把 abc 转成 int 类型。
err:2017年3月30日 15:27:12 Scanner输入类型错误,要求输入int,却输入了”xyz”。
提示:捕获程序有可能出现错误的地方,在catch语句中 将错误的信息 用自己的语言组织,写入到File中。
public static void collectErr(File file) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你要输入的整数值");
try {
int nextInt = scanner.nextInt();
} catch (Exception e) {
try (FileWriter fWriter = new FileWriter(file, true);) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
Date date = new Date();
String format = simpleDateFormat.format(date);
fWriter.write(format + "符串转换Int失败 不能把输入的转成 int 类型" + "\r\n");
} catch (IOException e1) {
e1.printStackTrace();
}
System.out.println("找到一次错误");
}
}
public static void collect2Err(File file) {
Scanner scanner = new Scanner(System.in);
try {
System.out.println("请输入你要输入的字符型值");
String next = scanner.next();
int parseInt = Integer.parseInt(next);
} catch (NumberFormatException e) {
try (FileWriter fWriter = new FileWriter(file, true);) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
Date date = new Date();
String format = simpleDateFormat.format(date);
fWriter.write(format + "Scanner输入类型错误,要求输入int,却输入了xyz" + "\r\n");
} catch (IOException e1) {
e1.printStackTrace();
}
System.out.println("又找到一次错误");
}
}
public static void main(String[] args) {
File file = new File("d.txt");
collectErr(file);
collect2Err(file);
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。