Java流与文件操作
数据流的基本概念
Java中把不同的数据源与程序间的数据传输都抽象表述为 流,
用来实现相对统一和简单的输入/输出(Input/Output,I/O)
在java.io包中定义了多种类型的接口和和类来实现数据的输入/输出功能,也称之为I/O流类型;
使用这些数据可以在此程序和数据源之间建立数据传输通道,即I/O流;
然后就可以使用基本统一而简洁的方式从流中读取或向流中写出数据。
总体流程图
文件相关操作
创建文件
new File(String pathname)//根据路径构建一个File对象
new File(File parent,String child)//根据父目录文件+子路径构建
new File(String parent,String child)//根据父目录+子路径构建
获取文件的相关信息方法
getName 获取文件名
getAbsplutePath 获取绝对路径
getParent 获取父目录的路径名
length 获取文件字节大小
exists 文件是否存在
isFile 是不是一个文件
isDirectory 是不是一个目录
目录的操作和文件删除
mkdir 创建一级目录
mkdirs 创建多级目录
delete 删除空目录或文件
Java IO流原理
1.I/O是Input/Output的缩写,I/O技术用于处理数据传输。如读写文件,网络通讯等。
2.java程序中,对于数据的输入/输出操作以“流(Stream)”的方式进行。
3.Java.io包下提供各种各种流的类和接口,用来获取不同种类的数据,并通过方法输入或输出数据。
流的分类
按操作数据单位不同分为:字节流,字符流(按字符)
按数据流的流向不同分为:输入流、输出流
按流的角色的不同分为:节点流、处理流/包装流
抽象基类 | 字节流 | 字符流 |
---|---|---|
输入流 | InputStream | Reader |
输出流 | OutputStream | Writer |
Java的io流共有四十多个类,实际上非常规则,都是从四个抽象基类衍生的
由四个类派生出来的子类名称都是以父类类名作为子类类名后缀
FileInputStream
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class NewFile03 {
public static void main(String[] args) throws IOException {
//声明路径地址
String filepath = "D:\\FFOutput\\1.txt";
//声明条件
int read =0;
//创建导入路径地址的字节输入流的实例化,用于读取文件
FileInputStream fileInputStream = new FileInputStream(filepath);
//从这个输入流读取一个字节的数据,没有输入可用,将方法阻止
//返回-1,表示读取完毕
while ((read = fileInputStream.read()) != -1){
//转成char显示
System.out.print((char) read);
}
//关闭输入流
fileInputStream.close();
}
}
FileOutPutStream
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutPutStream01 {
public static void main(String[] args) throws IOException {
writeFile();
}
public static void writeFile() throws IOException {
//声明一个路径
String filePath = "D:\\FFOutput\\1.txt\\";
//创建一个FileOutPutStream实例化
FileOutputStream fileOutputStream = new FileOutputStream(filePath);
String str = "一名少年,为救母加入骑士圣殿,奇迹、诡计,不断在他身上上演。在这人类六大圣殿与魔族七十二柱魔神相互倾轧的世界,他能否登上象征着骑士最高荣耀的神印王座";
//将字符串输出到文件1.txt里
//getBytes()字符串转换成字节数组
fileOutputStream.write(str.getBytes());
//关闭输入流
fileOutputStream.close();
}
}
文件拷贝
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileCopy {
public static void main(String[] args) throws IOException {
copyFile();
}
public static void copyFile() throws IOException {
//拷贝文件思路分析
//1.创建文件的输入流,将文件读入到程序
//2.创建文件的输出流,将读取到的文件数据,写入到指定的文件
//文件的起始位置
String filePath = "D:\\FFOutput\\first\\神印王座.txt";
//拷贝文件的最终位置
String FinalFilePath = "D:\\FFOutput\\second\\神印王座.txt";
//读取文件实例化
FileInputStream fileInputStream = new FileInputStream(filePath);
//输出文件实例化
FileOutputStream fileOutputStream = new FileOutputStream(FinalFilePath);
//创建一个字节数组
byte[] buf = new byte[10000];
//声明条件
int readLen = 0;
//循环读取起始文件中的字节,直到读取完止
while ((readLen = fileInputStream.read(buf))!=-1){
//输出到输出字节流的数组
fileOutputStream.write(buf);
}
//关闭流操作
fileInputStream.close();
fileOutputStream.close();
}
}
文件字符流
FileReader和FileWrite是字符流;
FileReader相关方法
1、new FileReader(File/String)
2.read:每次读取单个字符,返回该字符,如果到文件末尾就返回-1
3.read(char[]):批量读取多个字符到数组,返回读取到的字符数,如果到文件末尾返回-1
相关API:
1.new String(char[]):将char[]转换成String
2.new String(char[],off ,len):将char[]的指定部分转换成String
FileWrite常用方法
1.new FileWriter(File/String):覆盖模式,相当于流的指针在首端
2.new FileWriter(File/String,true):追加模式,相当于流的指针在尾端
3.write(int):写入单个字符
4.write(char[]):写入指定数组
5.write(char[],off,len)写入指定数组的指定部分
6.write(string):写入整个字符串
7.write(string,off,len):写入字符串的指定部分
注意:FileWriter使用后,必须关闭(close)或刷新(flush),否则写入不到指定的文件
FileReader
import java.io.FileReader;
import java.io.IOException;
public class FileReader01 {
public static void main(String[] args) throws IOException {
//声明文件路径
String filePath = "D:\\FFOutput\\first\\酒神.txt\\";
//声明条件
int data = ' ';
//创建字符读取流实例化
FileReader fileReader = new FileReader(filePath);
//循环读取使用read,单个字符读取
while ((data = fileReader.read()) != -1){
System.out.print((char) data);
}
//关闭流
fileReader.close();
}
}
FileWriter
import java.io.FileWriter;
import java.io.IOException;
public class FileWriter01 {
public static void main(String[] args) throws IOException {
String str = " 一个懒惰的少年,因性格原因选学了无人问津的光系魔法,却无意中踏近了命运的巨轮,一步一步的成为了传说中的大魔导师。 正是在他的努力下结束了东西大陆的分界,让整个大陆不再有种族之分,成为了后世各族共尊的光之子。";
String filePath = "D:\\FFOutput\\first\\光之子.txt\\";
FileWriter fileWriter = new FileWriter(filePath);
fileWriter.write(str);
fileWriter.close();
}
}
节点流和处理流
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 | |
---|---|---|---|---|---|
抽象基类 | InputStream | OutPutStream | Reader | Writer | |
访问文件 | FileInputStream | FileOutPutStream | FileReader | FileWriter | 节点流 |
访问数组 | ByteArrayInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter | 节点流 |
访问管道 | PipedInputStream | PipedIntputStream | PipedReader | PipedWriter | 节点流 |
访问字符串 | StringReader | StringWriter | 节点流 | ||
缓冲流 | BufferedInputStream | BufferedOutputStream | BuffteredReader | BufferedWriter | 处理流 |
转换流 | InputStreamReader | OutputStreamReader | 处理流 | ||
对象流 | ObjectInputStream | ObjectOutputStream | 处理流 | ||
抽象基类 | FilterInputStream | FilterOutputStream | FilterReader | FilterWriter | 处理流 |
打印流 | PrintStream | PrintWriter | 处理流 | ||
推回输入流 | PushbackInputStream | PushbackReader | 处理流 | ||
特殊流 | DataInputStream | DataOutputStream | 处理流 |
节点流和处理流的区别和联系
1.节点流是底层源流/低级流,直接跟数据源相接
2.处理流包装节点流,即可以消除不同节点流的实现差异,又可以提供方便的方法来完成输入输出
3.处理流(包装流)对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相连
处理流的功能主要体现
1.性能的提高:主要增加缓冲的方式提高输入输出的效率
2.操作的便携:处理流可能提供一系列方便的方法来一次输入输出大批量的数据,使用更加灵活方便
BufferedReader
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Buffered01 {
public static void main(String[] args) throws IOException {
String filePath = "D:\\FFOutput\\second\\神印王座.txt\\";
FileReader fileReader = new FileReader(filePath);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String Line;
while ((Line = bufferedReader.readLine())!=null){
System.out.println(Line);
}
bufferedReader.close();
}
}
BufferedWriter
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class BudderedWriter01 {
public static void main(String[] args) throws IOException {
String filePath = "D:\\FFOutput\\second\\光之子.txt\\";
//创建实例化
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath,true));
//写入文字
bufferedWriter.write("三生三世的遗憾,三生三世的眷念");
//换行
bufferedWriter.newLine();
bufferedWriter.write("天青古莲,万法星辰!");
bufferedWriter.newLine();
bufferedWriter.write("一条枷锁,链住万千星域");
bufferedWriter.newLine();
bufferedWriter.write("一颗心脏,沉浮黎明破晓。");
bufferedWriter.close();
}
}
字符处理流拷贝文件
import java.io.*;
public class Copy01 {
public static void main(String[] args) throws IOException {
String srcFilePath = "D:\\FFOutput\\first\\酒神.txt\\";
String destFilePath = "D:\\FFOutput\\second\\酒神.txt\\";
BufferedReader br = new BufferedReader(new FileReader(srcFilePath));
BufferedWriter bw = new BufferedWriter(new FileWriter(destFilePath));
String line;
while((line = br.readLine())!=null){
bw.write(line);
bw.newLine();
System.out.println("复制文件成功...");
}
br.close();
bw.close();
}
}
字节处理流拷贝文件
public class copy02 {
public static void main(String[] args) throws IOException {
String srcFilePath = "D:\\FFOutput\\first\\龙皓晨.jpg\\";
String destFilePath = "D:\\FFOutput\\second\\456.jpg\\";
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFilePath));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFilePath));
byte[] buff = new byte[10000];
int readLen = 0;
while((readLen = bis.read(buff))!=-1){
bos.write(buff,0,readLen);
System.out.println("文件拷贝完毕");
}
bis.close();
bos.close();
}
}
对象处理流
序列化和反序列化
1.序列化就是在保存数据时,保存数据的值和数据类型
2.反序列化吧就是在恢复数据时,恢复数据的值和数据类型
3.需要让某个对象支持序列化机制,则必须让其类是可序列化的,为了让某个
类是可序列化的,该类必须实现两个接口Seralizable、Externalizable
注意事项
1.读写顺序一致
2.要求实现序列化或反序列化对象,需要实现Seralizable
3.序列化的类中建议添加SerivalVersionUID,提高版本的兼容性
4.序列化对象时,默认将里面所有属性都进行序列化,但除了static或transient修饰的成员
5.序列化对象时,要求里面属性的类型也需要实现序列化接口
6.序列化具备可继承性,也就是如果某类已经实现了序列化,则它的所有子类也已经默认实现了序列化
ObjectOutPutStream(序列化)
import java.io.*;
public class ObjectOutPutStream_ {
public static void main(String[] args) throws IOException {
String filePath = "D:\\FFOutput\\second\\oos.txt\\";
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
oos.writeInt(100);
oos.writeBoolean(true);
oos.writeDouble(4.5);
oos.writeUTF("碧海笙箫鸣鸣响");
oos.writeObject(new Dog("志成",10));
oos.close();
}
}
class Dog implements Serializable{
private String name;
private int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
}
ObjectInputPutStream(反序列化)
import java.io.*;
public class Pbject02 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
String filePath = "D:\\FFOutput\\second\\oos.txt\\";
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
System.out.println(ois.readInt());
System.out.println(ois.readBoolean());
System.out.println(ois.readDouble());
System.out.println(ois.readUTF());
Object dog = ois.readObject();
System.out.println("运行类型"+dog.getClass());
System.out.println("dog信息"+dog);
}
}
转换流
介绍
1.IntputStreamReader:Reader的子类,可以将IntPutStream(字节流)包装成Reader(字符流)
2.OutputStreamWriter:Writer的子类,实现将OutputStream(字节流)包装成Writer(字符流)
3、当处理纯文本数据时,如果使用字符流效率更高,并且可以有效解决中文问题,所以建议将字节流转换成字符流
4、可以在使用时指定编码格式(utf-8、gbk、gb2312等)
IntputStreamReader
import java.io.*;
public class InputStreamReader01 {
public static void main(String[] args) throws IOException {
String filePath = "D:\\FFOutput\\second\\光之子.txt\\";
InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath),"utf-8");
BufferedReader br = new BufferedReader(isr);
String s= br.readLine();
System.out.println("读取内容="+s);
br.close();
}
}
OutoutStreamWriter
import java.io.*;
public class XieRu {
public static void main(String[] args) throws IOException {
String filePath = "D:\\FFOutput\\first\\荣耀骑士.txt";
OutputStreamWriter gbk = new OutputStreamWriter(new FileOutputStream(filePath),"gbk");
gbk.write("手握日月摘星辰,世上无我这般人");
gbk.close();
}
}
String s= br.readLine();
System.out.println("读取内容="+s);
br.close();
}
}
OutoutStreamWriter
import java.io.*;
public class XieRu {
public static void main(String[] args) throws IOException {
String filePath = "D:\\FFOutput\\first\\荣耀骑士.txt";
OutputStreamWriter gbk = new OutputStreamWriter(new FileOutputStream(filePath),"gbk");
gbk.write("手握日月摘星辰,世上无我这般人");
gbk.close();
}
}