一.介绍
Java中对文件的操作是以流的方式进行的。流是Java内存中的一组有序数据序列。Java将数据从源(文件、内存、键盘、网络)读入到内存中,形成了流,然后将这些流还可以写到另外的目的地(文件、内存、控制台、网络),之所以称为流,是因为这个数据序列在不同时刻所操作的是源的不同部分。
那么操作文件的流,我们称之为文件件流,文件流不是若干个文件组成的流而是以文件流输入输出若要对文件进行输入输出,若要对文件进行输入输出。就必须通过文件流来实现。
二.知识点介绍
1、字节流
2、字符流
三.上课视频对应说明文档
回想之前写过的程序,数据都是在内存中,一旦程序运行结束,这些数据都没有了,等下次再想使用这些数据,可是已经没有了。那怎么办呢?能不能把运算完的数据都保存下来,下次程序启动的时候,再把这些数据读出来继续使用呢? 其实要把数据持久化存储,就需要把内存中的数据存储到内存以外的其他持久化设备(硬盘、光盘、U盘等)上。
当需要把内存中的数据存储到持久化设备上这个动作称为输出(写)Output操作。
当把持久设备上的数据读取到内存中的这个动作称为输入(读)Input操作。
因此我们把这种输入和输出动作称为IO操作。
1、字节流
1.1、一切均为字节
在数据传输过程中,一切数据(文本、图像、声音等)最终存储的均为一个个字节,即二进制数字。所以数据传输过程中使用二进制数据可以完成任意数据的传递。
我们向一个文件中存储一定数据(一些数字),如果使用文本方式打开,则会以文本的方式解释数据。如果以视频的方式打开,则会以视频的方式解释数据。音频、可行执行文件等亦是如此。所以,在文件传输过程中,我们要时刻明确,传输的始终为数据。
1.2、字节输出流
输出流:OutputStream(抽象类):FileOutputStream(基本输出流)
构造方法:需要绑定IO资源
public FileOutputStream(String name) 创建覆盖写出对象
public FileOutputStream(String name,boolean append) 创建指定是否追加写出对象
其他方法: 写出时,如果没有该文件对象,会自动创建文件对象
write(int n):输出一个字节;(使用int替代了byte)
write(byte[] b):输出一个字节数组;
write(byte[] b, int off , int len):输出字节数组的一部分;
flush():刷新此输出流并强制写出所有缓冲的输出字节;
close(): 由于每个IO流都需要绑定一个IO资源,在使用时,需要回收资源
1.3、FileOutputStream类
OutputStream有很多子类,其中子类FileOutputStream可用来写入数据到文件。
FileOutputStream类,即文件输出流,是用于将数据写入 File的输出流。
构造方法
(1)FileOutputStream(File file):创建一个向指定File对象表示的文件中写入数据的文件输出流。
(2)FileOutputStream(String name):创建一个向具有指定名称的文件中写入数据的输出文件流。
1.3.1、写出一个字节
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 字节输出流
* FileOutputStream(File file) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
* FileOutputStream(String name) 创建一个向具有指定名称的文件中写入数据的输出文件流。
*
*/
public class Demo2 {
public static void main(String[] args) throws IOException {
//创建 字节输出流 对象.
FileOutputStream fos = new FileOutputStream("aaa.txt");
// 写出数据
fos.write(97);
// 关闭资源 , 必须做.
fos.close();
}
}
1.3.2、FileOutputStream类写入数据到文件中
代码示例:
public class FileOutputStreamDemo {
public static void main(String[] args) throws IOException {
//需求:将数据写入到文件中。
//创建存储数据的文件。
File file = new File("c:\\file.txt");
//创建一个用于操作文件的字节输出流对象。一创建就必须明确数据存储目的地。
//输出流目的是文件,会自动创建。如果文件存在,则覆盖。
FileOutputStream fos = new FileOutputStream(file);
//调用父类中的write方法。
byte[] data = "abcde".getBytes();
fos.write(data);
//关闭流资源。
fos.close();
}
}
1.4、给文件中续写和换行
我们直接new FileOutputStream(file)这样创建对象,写入数据,会覆盖原有的文件,那么我们想在原有的文件中续写内容怎么办呢?
继续查阅FileOutputStream的API。发现在FileOutputStream的构造函数中,可以接受一个boolean类型的值,如果值true,就会在文件末位继续添加。
构造方法:
(1) FileOutputStream(File file,Boolean append):创建一个向指定File对象表示的文件中写入数据的文件输出流。
(2) FileOutputStream(String name,boolean append):创建一个向具有指定name的文件中写入数据的输出文件流。
给文件中续写数据和换行,代码演示:
public class FileOutputStreamDemo2 {
public static void main(String[] args) throws Exception {
File file = new File("c:\\file.txt");
FileOutputStream fos = new FileOutputStream(file, true);
String str = "\r\n"+"fdm";
fos.write(str.getBytes());
fos.close();
}
}
1.4.1、写出多个数据&追加数据
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 1.创建流对象
* 2.写出数据
* 3.关闭流资源
*
* 当使用流对象 ,写出数据到一个文件时, 原来文件中的内容会被清掉.新的数据 写出.
*
* 为了解决这个问题.
* FileOutputStream(String name, boolean append) 创建一个向具有指定 name 的文件中写入数据的输出文件流。
*/
public class Demo3 {
public static void main(String[] args) throws IOException {
//fun();
//fun2();
//追加数据
//创建流对象
FileOutputStream fos = new FileOutputStream("ccc.txt" , true ); // true 表示可以追加 .
//写出数据
fos.write(65);
// 关闭 资源
fos.close();
}
private static void fun2() throws FileNotFoundException, IOException {
// * 1.创建流对象
FileOutputStream fos = new FileOutputStream("ccc.txt");
// * 2.写出数据
String s = "hello io " ;
byte[] bytes = s.getBytes();
fos.write(bytes);
// * 3.关闭流资源
fos.close();
}
private static void fun() throws FileNotFoundException, IOException {
// 1.创建流对象
FileOutputStream fos = new FileOutputStream("bbb.txt");
// 2.写出数据
fos.write(98);
fos.write(99);
fos.write(100);
fos.write(101);
// 3.关闭流资源
fos.close();
}
}
1.5、字节输入流
输入流:InputStream(抽象类):FileInputStream(基本输入流)
构造方法:需要绑定IO资源
public FileInputStream(String name)
其他方法:读取时,返回数据时,使用int替代了byte
(1) abostract int read():从输入流中读取数据的下一个字节。
(2) int read(byte[] b):从输入流中读取一定数量的字节,并将其存储在缓冲区数组。
(3) lose(): 由于每个IO流都需要绑定一个IO资源,在使用时,需要回收资源
1.6、FileInputStream类
InputStream有很多子类,其中子类FileInputStream可用来读取文件内容。
FileInputStream 从文件系统中的某个文件中获得输入字节。
构造方法
(1)FileInputStream(file):通过打开一个到实际文件的链接来创建一个FileInputStream,该文件通过文件系统中的File对象file指定。
(2)FileInputStream(String name):通过打开一个到实际文件的链接来创建一个FileInputStream,该文件通过文件系统中的路径名name指定。
1.7、FileInputStream类读取数据read方法
abstract int read():从输入流中读取数据的下一个字节。
在读取文件中的数据时,调用read方法,实现从文件中读取数据
1.7.1、读取一个字节
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
* 字节输入流
* 构造方法 FileInputStream(String name)
*
* 字节流在读取数据的时候,字节类型的数据会被提升为int类型, 读取到文件结尾,返回 -1.
*/
public class Demo {
public static void main(String[] args) throws IOException {
//fun();
//创建 字节输入流
FileInputStream fis = new FileInputStream("bbb.txt");
// 读取数据
int i = fis.read();
System.out.println((char) i);
i = fis.read();
System.out.println((char) i);
i = fis.read();
System.out.println((char) i);
i = fis.read();
System.out.println((char) i);
i = fis.read();
System.out.println(i);
i = fis.read();
System.out.println(i);
i = fis.read();
System.out.println(i);
i = fis.read();
System.out.println(i);
// 关闭资源
fis.close();
}
private static void fun() throws FileNotFoundException, IOException {
//创建 字节输入流
FileInputStream fis = new FileInputStream("aaa.txt");
// 读取一个字节
int i = fis.read();
System.out.println(i); // i 就表示你读取到数据.
char ch =(char)i; // 基本的类型强制转换.
System.out.println(ch);
// 关闭资源
fis.close();
}
}
1.7.2、循环读取文件(读取字节)
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
* 循环读取文件.
*
* 1.创建输入流对象
* 2.读取文件 read
* 3.关闭资源
*/
public class Demo2 {
public static void main(String[] args) throws IOException {
// * 1.创建输入流对象
FileInputStream fis = new FileInputStream("ccc.txt");
// * 2.读取文件 read
//定义 变量.保存读取的字节数据.
int i ;
while ((i=fis.read())!=-1) {
System.out.println((char)i);
}
// * 3.关闭资源
fis.close();
}
}
1.8、读取数据read(byte[])方法
在读取文件中的数据时,调用read方法,每次只能读取一个,太麻烦了,于是我们可以定义数组作为临时的存储容器,这时可以调用重载的read方法,一次可以读取多个字符。
int read(byte[] b):从输入六种读取一定数量的字节,并将其存储在缓冲区的数组b中。
1.8.1、使用字节数组读取文件
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
* 使用字节数组读取文件. 提高读取的效率
*
* 使用数组读取,每一个都把数据添加到数组中返回, 返回值 len ,表示当前次读取到的有效字符数.
*/
public class Demo3 {
public static void main(String[] args) throws IOException {
// 创建输入流对象
FileInputStream fis = new FileInputStream("aaa.txt");
// 使用字节数组读取.
byte[] b = new byte[2];
int len = fis.read(b); // 每一次读取, 会向 字节数组中,添加2个字节
//打印 读取的数据
System.out.print((char)b[0]);
System.out.println((char)b[1]);
System.out.println(len);
System.out.println("===========");
len = fis.read(b);
System.out.print((char)b[0]);
System.out.println((char)b[1]);
System.out.println(len);
System.out.println("===========");
len = fis.read(b);
System.out.print((char)b[0]);
System.out.println((char)b[1]);
System.out.println(len);
// 关闭资源
fis.close();
}
}
1.8.2、len有效字节数组(复制文本文件)
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* len 有效字节数组 ,
*
*/
public class Demo4 {
public static void main(String[] args) throws IOException {
// 创建流对象
FileInputStream fis = new FileInputStream("aaa.txt");
FileOutputStream fos = new FileOutputStream("aaa2.txt");
// 操作数据
byte[] b = new byte[2]; // 建议 1024的整数倍. 2,4, 8 .
int len; // 有效字节 数.如果是文件结尾 返回 -1
while (( len = fis.read(b))!=-1) {
fos.write(b , 0 , len); // b表示存数据的数组, 0表示开始的位置, len有效字符个数
}
// 关闭资源
fos.close();
fis.close();
}
}
1.8.3、字节数组复制图片文件
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 边读边写,复制文本文件.
*
* 1.创建流对象. 输入和输出流
* 2.操作数据 . 读取数据和写出数据
* 3.关闭资源 . 关两个流.
*/
public class Demo {
public static void main(String[] args) throws IOException {
// copy_txt();
// copy_pic();
// copy_pic2();
// 创建 流对象
FileInputStream fis = new FileInputStream("hi.jpg");
FileOutputStream fos = new FileOutputStream("hi2.jpg");
// 读写数据, 使用 数组 .
byte[] b = new byte[1024];
int len ;
// 循环读取
while ((len = fis.read(b))!=-1) {
fos.write(b, 0, len);
}
// 关闭资源
fos.close();
fis.close();
System.out.println("高效复制完毕");
}
private static void copy_pic2() throws FileNotFoundException, IOException {
FileInputStream fis = new FileInputStream("hi.jpg");
FileOutputStream fos = new FileOutputStream("hi_copy.jpg");
int b;
while ((b = fis.read()) != -1) {
fos.write(b);
}
fos.close();
fis.close();
System.out.println("复制图片完毕");
}
private static void copy_pic() throws FileNotFoundException, IOException {
FileInputStream fis = new FileInputStream("aa.jpg");
FileOutputStream fos = new FileOutputStream("aa_copy.jpg");
int b;
while ((b = fis.read()) != -1) {
fos.write(b);
}
fos.close();
fis.close();
System.out.println("复制图片完毕");
}
private static void copy_txt() throws FileNotFoundException, IOException {
// 创建流对象
FileInputStream fis = new FileInputStream("ccc.txt");
FileOutputStream fos = new FileOutputStream("E:\\ccc.txt");
// 操作数据
int i;
// 读取数据
while ((i = fis.read()) != -1) {
// 写出数据
fos.write(i);
}
// 关闭资源 . 后开先关, 先开后关.
fos.close();
fis.close();
System.out.println("复制文件完毕");
}
}
1.9、字节流练习
1.9.1、复制文件
原理;读取一个已有的数据,并将这些读到的数据写入到另一个文件中。
代码示例:
public class CopyFileTest {
public static void main(String[] args)throws IOException {
//1,明确源和目的。
File srcFile = new File("c:\\YesDir\test.JPG");
File destFile = new File("copyTest.JPG");
//2,明确字节流 输入流和源相关联,输出流和目的关联。
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
//3,使用输入流的读取方法读取字节,并将字节写入到目的中。
int ch = 0;
while((ch=fis.read())!=-1){
fos.write(ch);
}
//4,关闭资源。
fos.close();
fis.close();
}
}
上述代码输入流和输出流之间是通过ch这个变量进行数据交换的。
上述复制文件有个问题,每次都从源文件读取一个,然后在写到指定文件,接着再读取一个字符,然后再写一个,一直这样下去。效率极低。
1.9.2、临时数组方式复制文件
上述代码复制文件效率太低了,并且频繁的从文件读数据,和写数据,能不能一次多把文件中多个数据都读进内容中,然后在一次写出去,这样的速度一定会比前面代码速度快。
public class CopyFileByBufferTest {
public static void main(String[] args)throws IOException {
File srcFile = new File("c:\\YesDir\test.JPG");
File destFile = new File("copyTest.JPG");
// 明确字节流 输入流和源相关联,输出流和目的关联。
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
//定义一个缓冲区。
byte[] buf = new byte[1024];
int len = 0;
while ((len = fis.read(buf)) != -1) {
fos.write(buf, 0, len);// 将数组中的指定长度的数据写入到输出流中。
}
// 关闭资源。
fos.close();
fis.close();
}
}
2、字符流
2.1、方便程序员的IO流
在IO开发过程中,我们传输最频繁的数据为字符,而以字节方式传输字符需要每次将字符串转换成字节再处理,而且也丧失了程序员对数据内容的判断(因为程序员只认识字符,不认识字节)。所以,为了让程序员方便对字符进行操作,Java提供了专门以字符作为操作单位的类——字符流,其底层仍然为字节流。
显然,字符流只能操作字符,无法操作其他数据,如声音、视频等。
2.2、字符输出流FileWirter
既然有专门用于读取字符的流对象,那么肯定也有写的字符流对象,查阅API,发现有一个Writer类,Writer是写入字符流的抽象类。其中描述了相应的写的动作。
(1)void write(char[] cbuf):写入字符数组;
(2)abstract void write(char[] cbuf,int off,int len):写入字符数组的某一部分;
(3)void write(int c):写入单个字符;
(4)void write(String str):写入字符串;
(5)void write(String str,int off,int len):写入字符串的某一部分。
2.3、FileWriter类
查阅FileOutputStream的API,发现FileOutputStream 用于写入诸如图像数据之类的原始字节的流。要写入字符流,请考虑使用 FileWriter。
打开FileWriter的API介绍。用来写入字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节高效区大小都是可接受的。
构造方法
(1)FileWriter(File file):根据给定的File对象构造一个FileWriter对象。
(2)FileWriter(File file,Boolean append):根据给定的File对象构造一个FileWriter对象。
(3)FileWriter(String fileName):根据给定的文件名构造一个FileWriter对象。
(4)FileWriter(String filename,Boolean append):根据给定的文件名以及指示是否附加写入数据的boolean值来构造FileWrter对象。
2.4、FileWirter写数据
构造方法
(1)FileWriter(String fileName) 传递一个文件名称
成员方法
(1)void write(String str):往文件中写入一个字符串。
(2)void flush() 刷新该流的缓冲,把内存缓冲区中的数据刷新到文件中。
(3)void close():关闭此流,但要先刷新它。
输出流写数据的步骤:
(1)创建输出流对象
(2)调用输出流对象的写数据的方法
(3)释放资源
2.5、FileWriter写入中文到文件中
写入字符到文件中,先进行流的刷新,再进行流的关闭。
public class Demo01FileWriter {
public static void main(String[] args)throws
IOException {//创建输出流对象
FileWriter fw = new FileWriter("d:\\a.txt");
/*
* 创建输出流对象做了哪些事情:
* A:调用系统资源创建了一个文件
* B:创建输出流对象
* C:把输出流对象指向文件
*/
//调用输出流对象的写数据的方法
//写一个字符串数据
fw.write("IO流你好");
//数据没有直接写到文件,其实是写到了内存缓冲区
fw.flush();
//释放资源
//通知系统释放和该文件相关的资源
fw.close();
//while(true) {}
}
}
2.6、FileWriter写数据路径问题及关闭和刷新方法的区别
2.6.1、路径:
(1)相对路径:相对当前项目而言的,在项目的根目录下(a.txt)
(2)绝对路径:以盘符开始的路径(d:\\a.txt)
2.6.2、close()和flush()方法的区别:
(1)abstract void close():关闭此流,但是要先刷新他。关闭资源,但在关闭前会将高效区中的数据先刷新到目的地,否则丢失数据,然后在关闭流。流不可以使用。如果写入数据多,一定要一边写一边刷新,最后一次可以不刷新,由close完成刷新并关闭。
(2)abstract void flush():刷新该流的缓冲。将流中的高效区高效的数据刷新到目的地中,刷新后,流还可以继续使用。
代码示例:
public class Demo02FileWriter {
public static void main(String[] args)throws IOException {
//创建输出流对象
//FileWriter fw = new FileWriter("d:\\a.txt");
FileWriter fw = new FileWriter("a.txt");
//调用输出流对象的写数据方法,并刷新缓冲区
fw.write("helloworld");
fw.flush();
fw.write("java");
fw.flush();
//释放资源
fw.close();
//Stream closed
//fw.write("javaee");
//fw.flush();
}
}
2.7、FileWriter写数据的5个方法
(1)void write(String str):写一个字符串数据
(2)void write(String str,int index,int len):写一个字符串中的一部分数据, index:开始索引,len:写几个
(3)void write(int ch):写一个字符数据,这里写int类型的好处是既可以写char类型的数据,也可以写char对应的int类型的值。'a',97
(4)void write(char[] chs):写一个字符数组数据
(5)void write(char[] chs,int index,int len):写一个字符数组的一部分数据, index:开始索引,len:写几个
代码示例:
public class Demo03FileWriter {
public static void main(String[] args)throws IOException {
//创建输出流对象
FileWriter fw = new FileWriter("b.txt");
//void write(String str):写一个字符串数据
fw.write("abcde");
//void write(String str,int index,int len):写一个字符串中的一部分数据, index:开始索引,len:写几个
fw.write("abcde",0,5);
fw.write("abcde",1,3);
//void write(int ch):写一个字符数据,这里写int类型的好处是既可以写char类型的数据,也可以写char对应的int类型的值。'a',97
fw.write('a');
fw.write(97);
//void write(char[] chs):写一个字符数组数据
char[] chs = {'a','b','c','d','e'};
//fw.write(chs);
//void write(char[] chs,int index,int len):写一个字符数组的一部分数据, index:开始索引,len:写几个
fw.write(chs,0,5);
fw.write(chs,2,3);
//释放资源
fw.close();
}
}
2.8、FileWriter写数据之换行和追加写
2.8.1、续写问题
FileWriter(String fileName, boolean append)
构造放中参数的作用:
第一个参数:写入文件的目的地
第二个参数:append作用
true:可以续写
false:不能续写,覆盖之前的文件
2.8.2、换行问题
windows:\r\n
linux:\n
mac:\r
换行符可以写在第一个数据的结尾,也可以写在第二个数据的开头
2.9、字符输入流FileReader
2.9.1、FileReader读数据
构造方法
(1)FileReader(String fileName) 传递要读取的文件名称
成员方法
(1)int read() 读取单个字符并返回
(2)int read(char[] cbuf) 一次读取一个字符数组的数据,返回的是实际读取的字符个数
输入流读文件的步骤:
(1)创建输入流对象
(2)调用输入流对象的读数据方法
(3)释放资源
代码示例:
public class Demo01FileReader {
public static void main(String[] args) throws IOException {
//创建输入流对象
//FileReader fr = new FileReader("fr.txt");
FileReader fr = new FileReader
("Demo01FileWriter.java");
//调用输入流对象的读数据方法
//int read():一次读取一个字符
int ch;
/*
* while循环的条件表达式一共做了3件事情
* 1:fr.read() 读取一个字符
* 2:ch=fr.read() 把读取的字符赋值给ch
* 3:ch != -1 判断ch是否为-1
*/
while((ch=fr.read())!=-1) {
//System.out.println(ch);
//System.out.println((char)ch);
System.out.print((char)ch);
}
//释放资源
fr.close();
}
}
注意:如果构造方法中的文件不存在,会抛异常
java.io.FileNotFoundException: fr.txt (系统找不到指定的文件。)
2.9.2 FileReader类
查阅FileInputStream的API,发现FileInputStream 用于读取诸如图像数据之类的原始字节流。要读取字符流,请考虑使用 FileReader。
打开FileReader的API介绍。用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节高效区大小都是适当的
构造方法
(1)FileReader(File file):在各顶从中读取数据的File的情况下创建一个新FileReader;
(2)FileReader(String fileName):在给定从中读取数据的文件名的情况下创建一个新FileReader;
2.9.3、FileReader读取包含中文的文件
使用FileReader读取包含中文的文件
public class CharStreamDemo {
public static void main(String[] args)throws IOException {
//给文件中写中文
writeCNText();
//读取文件中的中文
readCNText();
}
//读取中文
public static void readCNText() throws IOException {
FileReader fr = new FileReader("D:\\test\\cn.txt");
int ch = 0;
while((ch = fr.read())!=-1){
//输出的字符对应的编码值
System.out.println(ch);
//输出字符本身
System.out.println((char)ch);
}
}
//写中文
public static void writeCNText() throws IOException {
FileOutputStream fos = new FileOutputStream("D:\\test\\cn.txt");
fos.write("a奋斗蒙教程".getBytes());
fos.close();
}
}
2.10、字符流:读取文件,一次读写一个字符
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/*
* 字符流 :读取文本文件
*
* 字符输入流 Reader 的子类, FileReader .
*/
public class Demo {
public static void main(String[] args) throws IOException {
//fun();
// 循环读取
FileReader fr = new FileReader("ddd.txt");
int c ;
while (( c = fr.read())!=-1) {
System.out.print((char)c);
}
fr.close();
}
private static void fun() throws FileNotFoundException, IOException {
//创建字符输入流对象
FileReader fr = new FileReader("ddd.txt");
// 读取数据
int c = fr.read(); // 读取一次,返回一个字符.
System.out.println((char)c); //20320 你
c = fr.read();
System.out.println((char)c); //22909 好
c = fr.read();
System.out.println(c);
// 关闭资源
fr.close();
}
}
2.11、复制文本文件: 一次读写一个字符复制文本文件
操作步骤:
(1)创建FileReader对象,并且绑定数据源
(2)创建FileWriter对象,并且绑定数据目的地
(3)调用FileReader中读取字符的方法read
(4)调用FileWriter中写入字符的方法write
(5)释放资源
代码示例:
public class Demo01CopyFile {
public static void main(String[] args)throws IOException {
//创建输入流对象
FileReader fr = new FileReader("Demo01FileWriter.java");
//创建输出流对象
FileWriter fw = new FileWriter("Copy.java");
//读写数据
int ch;
while((ch=fr.read())!=-1) {
fw.write(ch);
}
//释放资源
fw.close();
fr.close();
}
}
2.12、FileReader读数据一次一个字符数组
int read(char[] cbuf):一次读取一个字符数组的数据,返回的是实际读取的字符个数
public class Demo02FileReader {
public static void main(String[] args)throws IOException {
//创建输入流对象
//FileReader fr = new FileReader("fr2.txt");
FileReader fr = new FileReader("FileWriterDemo.java");
//调用输入流对象的读数据方法
//int read(char[] cbuf):一次读取一个字符数组的数据,返回的是实际读取的字符个数
char[] chs = new char[1024]; //这里可以是1024及其整数倍
int len;
/*
* while循环的条件表达式一共做了3件事情
* 1:fr.read(chs) 把数据读取到数组中
* 2:len=fr.read(chs) 把读取的有效个数赋值给len
* 3:len != -1 判断读取的有效个数是否为-1
*/
while((len=fr.read(chs))!=-1) {
System.out.print(new String(chs,0,len));
}
//释放资源
fr.close();
}
}
2.13、FileReader读取数据的两种方式图解
2.13.1、复制文本文件: 一次读写一个字符数组复制文本文件
public class Demo02CopyFile {
public static void main(String[] args)throws IOException {
//创建输入流对象
FileReader fr = new FileReader("Demo01FileWriter.java");
//创建输出流对象
FileWriter fw = new FileWriter("Copy.java");
//读写数据
char[] chs = new char[1024];
int len;
while((len=fr.read(chs))!=-1) {
fw.write(chs, 0, len);
}
//释放资源
fw.close();
fr.close();
}
}