FileReader/FileWriter应用
将hello.txt文件内容读入程序中,并输出到控制台
说明点:
read()
的理解:返回读入的一个字符。如果达到文件末尾,返回**-1**- 异常的处理:为了保证流资源一定可以执行关闭操作。需要使用
try-catch-finally
处理 - 读入的文件一定要存在,否则就会报
FileNotFoundException
。
@Test
public void fileReaderTest1() {
FileReader fileReader = null;
try {
//1.实例化File对象
File file = new File("hello.txt");
//2.提供具体流
fileReader = new FileReader(file);
//3.数据读取
//read():返回读入的一个字符。如果达到文件末尾,返回-1
int data = -1;
while ( (data = fileReader.read()) != -1){
System.out.print((char) data); //将int类强制转化为char输出
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.关闭流
if(fileReader != null){ //先判断是否为null,避免NullPointerException
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
对read()操作升级
使用read的重载方法 (read(char[] cbuf))
@Test
public void fileReaderTest2() {
FileReader fileReader = null;
try {
//1.File类的实例化
File file = new File("hello.txt");
//2.具体流的提供
fileReader = new FileReader(file);
//3.数据读取
//read(char[] cbuf):返回每次读入cbuf数组中的字符的个数。如果达到文件末尾,返回-1
char[] cbuf = new char[5];
int len = -1;
while ((len = fileReader.read(cbuf)) != -1){
//第一种写法:
// for(int i =0;i<len;i++){
// System.out.print(cbuf[i]);
// }
//错误写法
// for(int i=0;i<cbuf.length;i++){
// System.out.print(cbuf[i]);
// }
//第二种写法:
String data = new String(cbuf,0,len);
System.out.print(data);
//错误写法
// String data = new String(cbuf);
// System.out.print(data);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fileReader!=null){
//4.流的关闭
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
从内存中写出数据到硬盘的文件里
说明:
- 输出操作,对应的File可以不存在的。并不会报异常
- File对应的硬盘中的文件
如果不存在,在输出的过程中,会自动创建此文件。
如果存在:
如果流使用的构造器是:FileWriter(file,false) / FileWriter(file)
:对原有文件的覆盖
如果流使用的构造器是:FileWriter(file,true)
:不会对原有文件覆盖,而是在原有文件基础上追加内容
@Test
public void fileWriterTest() {
FileWriter fileWriter = null;
try {
//1.File类实例化
File file = new File("hello1.txt");
//2.具体流实例化
fileWriter = new FileWriter(file,false);
//3.数据写入
fileWriter.write("I have a dream!\n");
fileWriter.write("You need to have a dream!");
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fileWriter!=null){
//4.关闭流
try {
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
实现文本文件的复制
- 源文件必须存在
- 目标文件可以不存在
- 读取时常用:
read(char[] cbuf)
写入时常用:write(char[] cbuf,int off,int len)
- 不能使用字符流来处理图片等字节数据
@Test
public void copyFileTest() {
FileReader fr = null;
FileWriter fw = null;
try {
//File实例化
File srcFile = new File("hello.txt");
File destFile = new File("hello2.txt");
//具体流实例化
fr = new FileReader(srcFile);
fw = new FileWriter(destFile);
//数据读取与写入
char[] cbuf = new char[5]; //每次读取5个字符并存放在数组中
int len; //记录每次读入到cbuf数组中的字符的个数
while((len = fr.read(cbuf)) != -1){
//每次写出len个字符
fw.write(cbuf,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭流
try {
if(fr!=null)
fr.close();
} catch (IOException e) {
e.printStackTrace();
} //若第一个try-catch发送异常,会进行处理,后面语句会执行
try {
if(fw!=null)
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
FileInputStream/FileOutputStream应用
处理文本文件,可能出现乱码
- 1.若文本没有中文,是没有乱码(英文对应的ASCII码,一个字节)
- 2.若有中文时,可能会主线乱码(一个中文占三个字节)
@Test
public void copyDocFileTest() {
FileInputStream fis = null;
try {
//实例化File
File file = new File("hello.txt");
//实例化Stream
fis = new FileInputStream(file);
//数据操作
byte[] buffer = new byte[5];
int len;
while( (len = fis.read(buffer)) != -1){
String str = new String(buffer,0,len);
System.out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if( fis != null){
//关闭Stream
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
实现对图片的复制操作
@Test
public void copyImgFileTest() {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
//实例化File
File srcFile = new File("爱情与友情.jpg");
File destFile = new File("爱情与友情dest.jpg");
//实例化Stream
fis = new FileInputStream(srcFile);
fos = new FileOutputStream(destFile);
//数据操作
byte[] buffer =new byte[5];
int len;
while( (len = fis.read(buffer)) != -1){
fos.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭Stream
if(fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
封装复制操作方法,对指定路径下文件复制
@Test
public void copyFileTest(){
//对非文本文件复制操作
// String srcPath = "D:\\BaiduNetdiskDownload\\videotest.avi";
// String destPath = "D:\\BaiduNetdiskDownload\\videotest_dest.avi";
//对文本文件复制操作
String srcPath = "hello.txt";
String destPath = "hello_dest.txt";
long start = System.currentTimeMillis();
copyFile(srcPath,destPath);
long end = System.currentTimeMillis();
System.out.println("复制完成!耗时:"+(end-start)+"ms!");
}
//非文本或文本文件都可以使用字节流进行复制操作
public void copyFile(String srcPath, String destPath){
FileInputStream fis = null;
FileOutputStream fos = null;
try {
//实例化File
File srcFile = new File(srcPath);
File destFile = new File(destPath);
//实例化Stream
fis = new FileInputStream(srcFile);
fos = new FileOutputStream(destFile);
//数据操作
byte[] buffer =new byte[1024];
int len;
while( (len = fis.read(buffer)) != -1){
fos.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭Stream
if(fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
结论
- 对于文本文件(.txt,.java,.c,.cpp),使用字符流处理
- 对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt,.xsl,…),使用字节流处理
- 对于复制操作,文本文件也可以使用字节流处理,相当于进行底层搬运;
反之,非文本文件,是不可以用字符流来处理的