勿以恶小而为之,勿以善小而不为--------------------------刘备
劝诸君,多行善事积福报,莫作恶
上一章简单介绍了字节流InputStream和OutputStream(二),如果没有看过,请观看上一章
一. Writer
输出字符流,主要用于操作字符, 往文件里面写入字符。常常用其子类 FileWriter
一.一 Writer 接口方法
方法 | 作用 |
abstract void close() | 关闭流 |
abstract void flush() | 刷新流 |
跟原先一样的 write: | |
void write(int c) | 一个一个写,写入字符 |
void write(char[] cbuf) | 将要写入的字符先封装到字符数组里面,写入封装好的字符数组 |
abstract void write(char[] cbuf, int off, int len) | 写入字符数组的一部分,从off到off+len |
直接操作字符串的 | |
void write(String str) | 直接写入一个字符串 |
void write(String str, int off, int len) | 写入字符串的一部分 |
新增加的 append方法,可链式编程: | |
Writer append(char c) | 追加单个字符 |
Writer append(CharSequence csq) | 追加整个字符串 |
Writer append(CharSequence csq, int start, int end) | 追加字符串的一部分 |
String 类实现了 CharSequence 接口。
一.二 FileWriter 子类
一.二.一 构造方法
一.二.一.一 方法
方法 | 作用 |
FileWriter(File file) | 传入一个文件,重写文件里面的内容 |
FileWriter(File file, boolean append) | 传入一个文件,append为true时,追加, 为false时重写 |
FileWriter(String fileName) | 传入文件的路径,重写文件里面的内容 |
FileWriter(String fileName, boolean append) | 传入文件的路径,append为true时,追加,为false时重写 |
也是有 传入文件 和传入文件路径两种形式。 通常采用传入 文件的形式。 如果文件不存在,也同样会创建的。
一.二.一.二 演示
@Test
public void conTest() throws Exception{
File file=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"wz.txt");
//传入文件
Writer writer1=new FileWriter(file);
String path="E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"wz.txt";
//传入文件路径
Writer writer2=new FileWriter(path);
}
一.二.二 写入和关闭等方法
重写父类的方法, 主要是 write(),append() 方法。
一.三 FileWriter 写入文件
一.三.一 write() 写入
老蝴蝶综合简化一下, 包括以前的写入单个,写入数组,换行,写入中文。
@Test
public void write1Test() throws Exception{
File file=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"wz.txt");
Writer writer=new FileWriter(file,true);
//写入单个,会转换成字符,并不是数字。
writer.write(65);
//写入字符数组
char[] chars="Hello,My Name is TwoButterfly".toCharArray();
writer.write(chars);
//写入字符数组的部分形式
// writer.write(chars,0,3)
//直接写入字符串
writer.write("\r\n");
writer.write("Hello,My Name is TwoButterfly");
//写入字符串的部分形式
//writer.write("Hello ",0,5);
//换行
writer.write("换行\r\n");
//写入中文
writer.write("新的一行");
writer.close();
}
运行程序,打开文件系统:
一.三.二 append() 链式写入
@Test
public void appendTest() throws Exception{
File file=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"wz.txt");
Writer writer=new FileWriter(file,true);
writer.append("\r\n");
String str="我是追加写入的字符串";
//链式写入
writer.append(str).append("\r\n").append(str,0,3);
writer.close();
}
运行程序,查看 wz.txt 文件内容
为了保持写入文件一致,通常采用 write()的形式。
二. Reader
Reader 用于读取文件,字符方式读取。 故一般只读取文本格式的文件,不用于读取图片,视频等格式文件。
二.一 Reader 接口方法
方法 | 作用 |
abstract void close() | 关闭流并释放与之相关联的任何系统资源 |
int read() | 依次读取一个字符,并返回读取的这个字符 |
int read(char[] cbuf) | 读取多个字符,并将其放置到字符数组里面, 返回读取的个数 |
abstract int read(char[] cbuf, int off, int len) | 一次读取多个内容,读的内容是从 off 到 off+len, 然后将内容放置到cbuf 字符数组里面,返回读取的长度 |
二.二 FileReader 类
二.二.一 构造方法
二.二.一.一 方法
方法 | 作用 |
FileReader(File file) | 传入文件对象 |
FileReader(String fileName) | 传入文件路径 |
建议传入文件。
二.二.一.二 演示
//构造
@Test
public void conTest() throws Exception{
File file=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"wz.txt");
//传入文件
Reader reader=new FileReader(file);
String path="E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"wz.txt";
//传入路径
Reader reader1=new FileReader(path);
}
二.二.二 读取和关闭方法
主要是实现 接口 Reader 里面的 read() 方法
二.三 Reader 读取文件内容
二.三.一 write() 读取单个字符和读取字符数组
@Test
public void readTest() throws Exception{
File file=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"wz.txt");
Reader reader=new FileReader(file);
int c=reader.read();
System.out.println("读取单个:"+(char)c);
char[] chars=new char[1024];
//读取多个到字符数组
int len= reader.read(chars);
System.out.println("输出内容:"+new String(chars,0,len));
reader.close();
}
控制台打印输出:
发现,是没有乱码的。
二.三.二 循环读取
@Test
public void read2Test() throws Exception{
File file=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"wz.txt");
Reader reader=new FileReader(file);
StringBuilder sb=new StringBuilder();
char[] chars=new char[1024];
int len=-1;
while((len= reader.read(chars))!=-1){
String temp= new String(chars,0,len);
sb.append(temp);
}
//读取多个到字符数组
System.out.println("输出内容:"+sb.toString());
reader.close();
}
运行程序,控制台打印输出:
字符方式读取,是不会存在中文乱码问题的。
三. Reader和Writer的应用: 文件复制
文件复制,实际上就是将 Reader ,Writer 结合起来使用, 两者共同使用同一个 字符数组, Reader将读出的内容批量写入到字符数组里面, Writer 将字符数组批量写入到文件里面
三.一 文件复制方法
/**
*
* @param src
* @param desc
* @return 复制文本的文件。
* 如果是复制图片的话, 不会报错,但不会写入数据,打开图片会报错。 大小仍然有。
*/
public static boolean copyStr(String src,String desc) throws Exception{
//定义两个文件
File srcFile=new File(src);
File descFile=new File(desc);
if(!srcFile.exists()||!srcFile.isFile()){
throw new RuntimeException("源文件不存在或者源文件是目录");
}
Reader reader=new FileReader(srcFile);
Writer writer=new FileWriter(descFile);
// 1M 1M 进行复制
char[] chars=new char[1024];
int len=-1;
while((len=reader.read(chars))!=-1){
writer.write(chars,0,len);
}
writer.flush();
writer.close();
reader.close();
return true;
}
三.二 文件复制测试
@Test
public void copyStrTest(){
//复制普通文件
String src="E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"rz.txt";
String desc="E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"rzNewcopy.txt";
try {
CopyUtils.copyStr(src,desc);
System.out.println("文件复制成功");
} catch (Exception e) {
e.printStackTrace();
}
}
运行程序,查看文件系统:
文件复制成功。
注意,此种方式不能复制二进制图片。 可以复制成功,但打开图片会报错,因为没有往图片里面写入数据。
四. InputStreamReader 和 OutputStreamWriter
给你一个文件或者是文件的路径, 我们可以构造出 字节流, FileInputStream和 FileOutputStream , 也可以构造出字符流 FileReader和FileWriter, 可以采用字节流,也可以采用字符流的方式操作文件的内容。 但是,字节方式操作可能会造成中文乱码, 字符方式不会产生中文乱码。 然而,除了文件,还有其他的输入源,或者输出源, 如内存,或者控制台,显示器。 是的,可以将控制台看成输入源,显示器看成输出源,内存既可以是输入源,也可以是输出源。 我们常用的 System.in, System.out 实际上就是 InputStream, OutputStream.
那么,在控制台输入时,因为采用的是字节读取,那么很可能造成乱码, 而字符方式不会造成乱码。 如果我们想解决键盘输入乱码的问题,只要将字节流转换成字符流就可以了。 那么,如何将字节流转换成字符流呢? 幸运地是, JDK 提供了这种转换。
InputStreamReader 将字节输入流转换成字符输入流, OutputStreamWriter 将字节输出流转换成字符输出流。
由于 InputStreamReader 继承了 Reader, 所以具有Reader 类的方法
public class InputStreamReader extends Reader {
}
由于 OutputStreamWriter 继承了 Writer, 所以具有Writer 类的方法
public class OutputStreamWriter extends Writer {
}
四.一 OutputStreamWriter
rz.txt 文件以前的内容是:
四.一.一 方法
四.一.一.一 构造方法
方法 | 作用 |
OutputStreamWriter(OutputStream out) | 传入 字节输出流 |
OutputStreamWriter(OutputStream out, String charsetName) | 传入字节输出流和编码方式 |
四.一.一.二 其他方法
参照其父类 Writer 中的方法。
四.一.二 演示
@Test
public void writeTest() throws Exception{
//有一个文件
File file=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"rz.txt");
OutputStream outputStream=new FileOutputStream(file,true);
//解决乱码问题和方便写入
//转换成了 writer
OutputStreamWriter outputStreamWriter=new OutputStreamWriter(outputStream);
//写入内容
outputStreamWriter.append("\r\n").append((char)65);
//写入内容
outputStreamWriter.write("\r\n你好啊,两个蝴蝶飞");
outputStreamWriter.close();
outputStream.close();
}
运行程序, rz.txt 文件的新内容是:
四.二 InputStreamReader
四.二.一 方法
四.二.一.一 构造方法
方法 | 作用 |
InputStreamReader(InputStream in) | 传入字节输入流 |
InputStreamReader(InputStream in, String charsetName) | 传入字节输入流和编码 |
四.二.一.二 其他方法
参照其父类 Reader 接口中的方法
四.二.二 演示
@Test
public void readTest() throws Exception{
File file=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"rz.txt");
InputStream inputStream=new FileInputStream(file);
//由字节流转换成字符流
InputStreamReader inputStreamReader=new InputStreamReader(inputStream);
char[] chars=new char[1024];
int len=-1;
StringBuilder sb=new StringBuilder();
while((len=inputStreamReader.read(chars))!=-1){
String temp=new String(chars,0,len);
sb.append(temp);
}
System.out.println("读出内容:"+sb.toString());
inputStreamReader.close();
inputStream.close();
}
运行程序,控制台打印输出:
谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!