一、IO流的基础知识:
1、IO流的作用:是用来处理设备之间的数据传输。
Java对数据的操作是通过流的方式完成,而用于操作流的对象存在于Java的IO包中。
2、IO流的分类:
①、按操作的数据不同:字节流和字符流。
②、按流的方向不同:输入流和输出流。
注意:早期IO包里面只有字节流,因为计算机中(内存中或者硬盘中)的数据的体现形式都是字节,都是二进制数据。
3、字符流的由来:
由于文本数据比较常见,使用也比较频繁,为了方便处理文本数据,就从字节流中单独分离出了字符流。
字符流基于字节流。
4、IO流常用基类:
①、字节流的抽象基类:
InputStream(输入流--->读取)、OutputStream(输出流--->写入)
②、字符流的抽象基类:
Reader(输入流--->读取)、Writer(输出流--->写入)
注意:由IO流的4个常用基类派生出来的子类名称都是以其父类名称做为子类名的后缀。
例如:InputStream的子类:FileInputStream
Reader的子类:FileReader
5、IO流继承体系图
字符流继承体系图:
字节流继承体系图:
二、字符流(Writer & Reader)
1、字符输出流(写入)——Writer类
①、Writer类的定义:
public abstract class Writer
extends Object
implements Appendable,Closeable,Flushable
是一个抽象类,如果要使用Writer类则必须要使用其子类。
②、Writer类中的常用方法介绍:
abstract void flush():刷新流对象中的缓冲中的数据。将数据刷到目的地中。
abstract void close():关闭流。但是关闭之前会刷新一次内部的缓冲中的数据。
void write(String str):将字符串写入到流中。
2、FileWriter类
①、概述:是Writer类的间接子类,用于文本输出流的操作。
②、FileWriter类常用构造方法:
FileWriter(String fileName):在创建对象时就明确被操作的文件。如果文件不存在,就会在指定目录下创建一个。如果指定目录下已经存在一个同名文件,则该文件会被覆盖。
代码示例:
import java.io.*;
class FileWriterDemo
{
public static void main(String[] args) throws IOException
{
/*
创建一个FileWriter对象。该对象一被初始化就必须要明确被操作的文件。而且该文件会被创建到指定目录下。如果该目录下已有同名文件,将被覆盖。其实就步骤就是在明确数据要存放的目的地。
*/
FileWriter fw = new FileWriter("demo.txt");
//调用write方法将字符串写入到流中。
fw.write("abcde");
//刷新流对象中的缓冲中的数据。
//将数据刷到目的地中。
//fw.flush();
//关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据。
//将数据刷到目的地中。
//和flush的区别:flush刷新后,流可以继续使用。close刷新后,会将流关闭。
fw.close();
fw.write("haha"); //会出现IOException异常,因为流已经被关闭了,无法再写入内容。
}
}
FileWriter(String fileName, boolean append):可以通过添加一个boolean类型的参数来对已有的文件进行续写操作。
代码示例:
import java.io.*;
class FileWriterDemo3
{
public static void main(String[] args) throws IOException
{
//传递一个true参数,代表不覆盖已有的文件。并在已有文件的末尾处进行数据续写。
FileWriter fw = new FileWriter("demo.txt",true);
fw.write("hellojava");
fw.close();
}
}
注意:Windows中换行是用两个转移字符进行表示的:\r\n。而Linux中的换行用的是一个字符\n。
3、IO异常处理方式
import java.io.*;
class FileWriterDemo2
{
public static void main(String[] args)
{
FileWriter fw = null; //因为要操作的文件可能存在路径不存在的缘故,所以可能在对象创建之前就发生了异常,所以要在异常处理语句外部创建流对象的引用。
try
{
fw = new FileWriter("demo.txt");
fw.write("abcdefg");
}
catch(IOException e)
{
System.out.println(e.toString());
}
finally
{
try
{
if(fw != null) //必须要对不为null的流进行判断,防止出现空指针异常。
fw.close(); //为了节省资源,所以关闭流的动作一定要被执行,就放到异常处理语句的finally部分来执行。
}
catch(IOException e)
{
System.out.println(e.toString());
}
}
}
}
4、字符输入流(读取)——Reader类
①、Reader类声明:也是一个抽象类,需要使用其子类实例化该类对象。
public abstract class Reader
extends Object
implements Readable, Closeable
②、Reader类中常用方法介绍:
int read():读取单个字符。一次只读一个字符,而且会自动往下读。当没有可读内容的时候就返回-1。
int read(char[] cbuf):读取一个字符数组。返回值是读取到的字符个数。数组长度确定,一般长度定义为1024的倍数。
abstract int read(char[] cbuf,int off,int len):读取字符数组,并指定读取的范围。
abstract void close():关闭读取流。
5、FileReader类
①、概述:是Reader的间接子类。用于文本读取流的操作。
②、FileReader类常用构造方法:
FileReader(String fileName):在创建文件读取流对象时就关联一个指定名称的文件。如果该文件不存在,则会发生FileNotFoundException异常。
文本文件读取示例:第一种方式
import java.io.*;
class FileReaderDemo
{
public static void main(String[] args) throws IOException
{
//创建一个文件读取流对象,和指定名称的文件相关联。
//要保证该文件是已经存在的,如果不存在,会发生异常:FileNotFoundException
FileReader fr = new FileReader("demo.txt");
//调用读取流对象的方法。
//read():一次读一个字符,而且会自动往下读。
int ch = 0;
while((ch = fr.read()) != -1)
{
System.out.println((char)ch);
}
fr.close();
}
}
文本文件读取示例:第二种方式
import java.io.*;
class FileReaderDemo2
{
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("demo.txt");
//定义一个字符数组,用于存储读到的字符。
//该read(char[])方法返回的是读到的字符个数。
char[] buf = new char[1024]; //字符数组的长度一般定义成1024的倍数。
int num = 0; //定义表示读取到的字符个数的变量。
while((num = fr.read(buf)) != -1)
{
System.out.println(new String(buf,0,num));
}
fr.close();
}
}
6、文件复制综合案例:
①、文件复制原理:其实就是将一个文件数据复制到另一个文件中存储。
②、实现步骤:
1) 先通过字符输出流创建一个目的文件,用于存放从源文件中拷贝过来的数据。
2) 定义一个字符读取流和源文件相关联。
3) 通过不断的读写操作完成数据的复制存储。
4) 关闭流资源。
③、实现方式:两种(一次读一个字符的方式:read()方法。一次读多个字符用临时容器存储的方式:read(char[] buf))
④、文件复制实现图例:
第一种方式:
实现代码:
import java.io.*;
class CopyText
{
public static void main(String[] args) throws IOException
{
copy_1();
}
public static voidcopy_1() throws IOException
{
//创建目的地文件。
FileWriter fw = new FileWriter("RuntimeDemo_copy.txt");
//与已有文件关联。
FileReader fr = new FileReader("FileReaderDemo.java");
int ch = 0;
while((ch = fr.read()) != -1)
{
fw.write(ch);
}
fw.close();
fr.close();
}
}
第二种方式:
实现代码:
import java.io.*;
class CopyText
{
public static void main(String[] args)
{
copy_2();
}
public static void copy_2()
{
FileWriter fw = null;
FileReader fr = null;
try
{
fw = new FileWriter("RuntimeDemo_copy2.txt");
fr = new FileReader("FileReaderDemo2.java");
char[] buf = new char[1024];
int len = 0;
while((len = fr.read(buf)) != -1)
{
fw.write(buf,0,len);
}
}
catch(IOException e)
{
throw new RuntimeException("读写失败");
}
finally
{
if(fr != null)
try
{
fr.close();
}
catch(IOException e)
{
e.printStackTrace();
}
if(fw!=null)
try
{
fw.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
}