IO流:传输数据的一套机制
I:input (输入)
O:output(输出)
存储数据:内存 持久化存储
持久化存储:长期保存
IO流分为输入流和输出流
IO流从功能上来说分为字符流和字节流
字符流是只能操作字符(txt)
字节流:可以操作所有文件
字符流 Reader Writer
字节流 InputStream OutpurStream
以上4种都是抽象类,不能直接使用
输入还是输出是相对于内存来说
如果向内存中读取内容,就是输入到内存。输入流
如果从内存中向外面写入内容,就是输出。
字符输出流:FileWriter 将字符写入到文件中
如果想要追加数据,在构造方法后面提供 true
举例:
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterDemo {
public static void main(String[] args) throws IOException {
//字符输出流
//如果路径有,就直接创建文件
//如果文件已经存在。会创建新的文件覆盖掉以前的文件
FileWriter fw=new FileWriter("F:\\a,txt,true");
//写入数据到缓存区
fw.write("趁阳光正好,趁微风不燥");
//冲刷缓冲区
fw.flush();
//关闭,释放资源
//注意:关闭会自动冲刷缓冲区,因此有时就没必要再冲刷缓冲区
fw.close();
//清空对象
fw=null;
}
}
文件的异常处理:
1、现在trycatch外面声明对象,设置为null,保证对象的作用域在try…catch…finally里面
2、创建对象,并且在finally里面判断是否为null。因为一旦对象为null,那么就会出现空指针异常。
3、在finally的判断方法中,关闭流。关闭流也需要捕获异常,因为关闭流也不一定成功。
4、在捕获关闭流异常的trycatch中添加finally,无论关闭流是否成功,都给对象设置为null。
5、如果写入数据,需要去冲刷缓冲区,防止数据的丢失。
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterExceptioonTest {
public static void main(String[] args) {
// 创建对象
FileWriter fw = null;
try {
fw = new FileWriter("F:\\b.txt");
fw.write("你好,周杰伦");
// 冲刷
fw.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if (fw != null){
try {
fw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
fw = null;
}
}
}
}
}
JDK1.7的特性
Try with resource
try(AutoCloseable的子类/子接口){
对象可以保证自动关闭
}
注意:try小括号中内容不能是传递过来
import java.io.FileWriter;
public class TryWithResourceDemo {
public static void main(String[] args) {
// JDK1.7特性
// try ... with ... resouce 可以保证自动关闭
// 使用格式 try(AutoCloseable的子类或者子接口)
// 可以保证里面的对象自动关闭
try (FileWriter fw = new FileWriter("F:\\b.txt")){
fw.write("再见,周杰伦");
}catch(Exception e){
e.printStackTrace();
}
}
}
字符输入流:
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo {
public static void main(String[] args) throws IOException {
//字符输入流:将文件的内容读取到内存中
//创建对象
FileReader fr=new FileReader("F:\\c.txt");
//读取字符
//一次读取一个字符
//如果读到最后,没有字符,返回-1
//因为是从文件中一个个读取,所以这种写法,效率比较低
int ch;
while((ch=fr.read())!=-1){
System.out.println((char)ch);
}
fr.close();
}
}
字符输入流:FileReader
FileReader默认一次读取一个字符,效率比较低下,可以通过字符数组形成一个缓冲区,从而来提升效率。
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo02 {
public static void main(String[] args) throws IOException {
// 通过字符数组作为缓冲区,读取数据
FileReader fr = new FileReader("F:\\c.txt");
// 定义一个字符数组
char[] chs = new char[3];
// 读一次就获取对应字符数组长度的内容
// 如果没有读取到数据,那么返回-1
// 读取到的字符长度
int len;
while((len = fr.read(chs)) != -1){
System.out.println(new String(chs,0,len));
}
fr.close();
}
}
练习 :copy文件
import java.io.FileReader;
import java.io.FileWriter;
public class CopyTxt {
public static void main(String[] args) {
// 拷贝文件 思路:先去对应的文件中读取内容
// 读取一行写入一行
// 读取时候使用字符数组
long startTime = System.currentTimeMillis();
FileReader fr = null;
FileWriter fw = null;
try{
fr = new FileReader("F:\\667.txt");
fw = new FileWriter("F:\\a556.txt");
// 先读再写
// 读取需要使用到字符数组,那么先创建数组
char[] chs = new char[1024 * 8];
// 定义一个变量来接收实际读取到的长度
int len;
while ((len = fr.read(chs)) != -1){
// 表示读取到了内容 长度就是len
// 写入到文件中
// fw.write(new String(chs,0,len));
fw.write(chs, 0, len);
}
fw.flush();
}catch(Exception e){
e.printStackTrace();
}finally{
// fr和fw都有可能是null
if (fr != null){
try{
fr.close();
}catch(Exception e){
e.printStackTrace();
}finally{
fr = null;
}
}
if (fw != null){
try{
fw.close();
}catch(Exception e){
e.printStackTrace();
}finally{
fw = null;
}
}
}
// 复制文本花费的总时间
System.out.println(System.currentTimeMillis() - startTime);
}
}