字符输入流Reader
java.io.FileReader
类是读取字符文件的便利类。可以读取字符信息到内存中。它定义了字符输入 流的基本共性功能方法。public void close()
:关闭此流并释放与此流相关联的任何系统资源。public int read()
: 从输入流读取一个字符。public int read(char[] cbuf)
: 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中 。
FileReader类
- java.io.FileReader 类是读取字符文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。
字符编码:字节与字符的对应规则。
Windows系统的中文编码默认是GBK编码表。
idea中UTF-8
构造方法
FileReader(File file)
: 创建一个新的 FileReader ,给定要读取的File对象。FileReader(String fileName)
: 创建一个新的 FileReader ,给定要读取的文件的名称。
使用
public class FileReaderTest {
public static void main(String[] args) throws IOException {
//创建FileReader对象,传入读取路径
FileReader fr=new FileReader("abc.txt");//文件内容为:"你好abc"
//使用Read方法读取文件
//int read();//一次读取一个字节
/*int len=0;
while ((len=fr.read())!=-1){
System.out.println(len);
}*/
//int read(char[] buf):一次读取多个字符,将字符读入数组
char[] buf=new char[1024];
int len=0;
while ((len=fr.read(buf))!=-1){
//String的构造方法,
// new String(char[] value)
//new String(char value,int offset,int count)
System.out.println(new String(buf,0,len));
}
fr.close();
}
}
字符输出流
java.io.Writer
抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地。它定义了字节 输出流的基本共性功能方法。void write(int c)
写入单个字符。void write(char[] cbuf)
写入字符数组。abstract void write(char[] cbuf, int off, int len)
写入字符数组的某一部分,off数组的开始索引,len 写的字符个数。void write(String str)
写入字符串。void write(String str, int off, int len)
写入字符串的某一部分,off字符串的开始索引,len写的字符个 数.void flush()
刷新该流的缓冲。void close()
关闭此流,但要先刷新它。
FileWriter类
java.io.FileWriter
类是写出字符到文件的便利类。
构造方法
FileWriter(File file)
: 创建一个新的 FileWriter,给定要读取的File对象。FileWriter(String fileName)
: 创建一个新的 FileWriter,给定要读取的文件的名称。
使用
- 使用步骤:
- 创建FileWriter对象,构造方法中绑定要写入数据的目的地
- 使用write方法,把数据写入到内存缓冲区中(字符转换为字节的过程)
- 使用flush方法,把内存缓冲区中的数据,刷新到文件中;
- 释放资源(会把内存缓冲区中的数据刷新到文件中)
写单个字符
public class FWWrite {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileWriter fw = new FileWriter("fw.txt");
// 写出数据
fw.write(97); // 写出第1个字符
fw.write('b'); // 写出第2个字符
fw.write('C'); // 写出第3个字符
fw.write(30000); // 写出第4个字符,中文编码表中30000对应一个汉字。
/*
【注意】关闭资源时,与FileOutputStream不同。
如果不关闭,数据只是保存到缓冲区,并未保存到文件。
*/
// fw.close();
}
} 输出结果: abC田
虽然参数为int类型四个字节,但是只会保留一个字符的信息写出。
未调用close方法,数据只是保存到了缓冲区,并未写出到文件中。
写出其他数据
write(char[] cbuf)
和write(char[] cbuf, int off, int len)
,每次可以写出字符数组中的数据
public class FWWrite {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileWriter fw = new FileWriter("fw.txt");
// 字符串转换为字节数组
char[] chars = "黑马程序员".toCharArray();
// 写出字符数组
fw.write(chars); // 黑马程序员
// 写出从索引2开始,2个字节。索引2是'程',两个字节,也就是'程序'。
fw.write(b,2,2); // 程序
// 关闭资源
fos.close();
}
}
flush和close的区别
- flush :刷新缓冲区,流对象可以继续使用。
- close :先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。
字符流的续写和换行
- 操作类似于FileOutputStream。
FileWriter(File file,boolean append)
FileWriter(String fileName,boolean append)
- 换行:windows :
\r\n
- 注意:字符流,只能操作文本文件,不能操作图片,视频等非文本文件。
IO异常的处理
JDK7之前处理
- 使用try…catch…finally处理异常
public class HandleException1 {
public static void main(String[] args) {
// 提升变量fw的作用域,让finally可以使用
//变量在定义的时候可以没有值,但是使用的时候必须有值
FileWriter fw = null;
try {
//创建流对象
fw = new FileWriter("fw.txt");
// 写出数据
fw.write("abc");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fw != null) {//不判断直接关闭会抛出空指针异常
fw.close();
}
} catch (IOException e)
{
e.printStackTrace();
}
}
}
}
JDK7新特性(try-with-resource
)
- 在try的后边可以增加一个(),在括号中可以定义流对象,那么这个流对象的作用域就在try中有效
- try中的代码执行完毕,会自动把流对象释放掉,不用在写finally了
- 格式:
try (创建流对象语句,如果多个,使用';'隔开) {
// 读写数据
} catch (IOException e) {
e.printStackTrace();
}
- 使用举例
public class HandleException2 {
public static void main(String[] args) {
// 创建流对象
try ( FileWriter fw = new FileWriter("fw.txt"); ) {
// 写出数据
fw.write("abc"); //abc
} catch (IOException e) {
e.printStackTrace();
}
}
}
JDK9新特性(try-with-resource
)
- 在try的前边可以定义流对象
- 在try的后边()中可以直接引入流对象的名称(变量名)
- 在 try中的代码执行完毕,会自动把流对象释放掉,不用在写finally了
- 格式:
Resource resource1 = new Resource("resource1");
Resource resource2 = new Resource("resource2");
// 引入方式:直接引入
try (resource1; resource2) {
// 使用对象
}catch (IOException e) {
e.printStackTrace();
}
Properties属性集
java.util.Properties
集合 extendsHashtable<k,v>
implementsMap<k,v>
- Properties类表示了一个持久的属性集。Properties可保存在流中或从流中加载,属性列表中每个键及其对应值都是一个字符串;
- Properties集合是唯一一个和IO流相结合的集合:
1)可以使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储
2)可以使用Properties集合中的方法load,把硬盘中保存的文件(键值对),读取到集合中使用
构造方法
public Properties()
:创建一个空的属性列表。
基本的存储方法
public Object setProperty(String key, String value)
: 保存一对属性。public String getProperty(String key)
:使用此属性列表中指定的键搜索属性值。public Set<String> stringPropertyNames()
:所有键的名称的集合。
与流相关的方法
- 使用store方法,将集合中数据持久化到硬盘中存储
void store(OutputStream out, String comments)
void store(Writer writer, String comments)
参数:
OutputStream out:字节输出流,不能写中文
Writer writer:字符输出流,可以写中文
String comments:用来说明保存的文件是做什么用的,不能使用中文,会产生乱码,默认是Unicode编码,而系统是GBK编码,一般使用“空字符串”
public class properties_test {
public static void main(String[] args) throws IOException {
//创建properties集合对象,添加数据
Properties properties=new Properties();
properties.setProperty("迪丽热巴","18");
// 创建字节输出流
FileOutputStream fos=new FileOutputStream("abc.txt");
//使用store方法
properties.store(fos,"store data");
//释放资源
fos.close();
}
}
- 使用load方法,把硬盘中保存的文件(键值对),读取到集合中使用
- public void load(InputStream inStream) : 从字节输入流中读取键值对
- public void load(Reader reader) : 从字节输入流中读取键值对
参数:
InputStream out:字节输入流,不能读取含有中文的键值对
Reader reader:字符输入流,可以读取含有中文的键值对
- 注意:
1)存储键值对的文件中,键与值默认的连接符可以使用=,空格(其他符号)
2)存储键值对的文件中,可以使用#进行注释,别注释的内容不会被读取
3)存储键值对的文件中,键与值默认都是字符串,不用在加引号
public class ProDemo2 {
public static void main(String[] args) throws FileNotFoundException {
// 创建属性集对象
Properties pro = new Properties();
// 加载文本中信息到属性集
pro.load(new FileInputStream("read.txt"));
// 遍历集合并打印
Set<String> strings = pro.stringPropertyNames();
for (String key : strings ) {
System.out.println(key+" ‐‐ "+pro.getProperty(key));
}
}
}