目录
File类概述
File类常用方法
IO流
io流分类
Writer字符输出流
覆盖写入
追加写入
Reader字符输入流
字节流
字节输出流
覆盖写入
字符输入流
文件的拷贝
字符流文件的拷贝
字节流文件拷贝
字节流缓冲区
缓存流
字节缓存流
字节缓存输出流
字节缓存输入流
字符缓存输出流
字符缓存输入流
使用字节缓存输入输出流拷贝文件
对象流--对java对象进行IO操作
序列化与反序列化
io流可以对文件内容进行读写操作,而其中的File类对文件本身进行操作,比如创建文件、删除文件、重命名文件、等操作。该类封装了一个路径,并提供了一系列方法用于操作该路径指向的文件。
File类位于java.io包中。
public class Add {
public static void main(String[] args) throws IOException {
//创建目录
File f = new File("F:/java151/FileTest/YTR");
f.mkdir();
//创建文件
File f2 = new File("F:/java151/FileTest/YTR/Text.txt");
f2.createNewFile();
for(int i = 9;i<=13;i++){
File f3 = new File("F:/java151/FileTest/YTR/Text" + i + ".txt");
f3.createNewFile();
}
//创建多级目录
File f4 = new File("F:/java151/FileTest/YTR/ytr/aaa");
f4.mkdirs();
//查询
//查询文件名
String s1 = f2.getName();
System.out.println(s1);
//查询文件夹名
String s2 = f.getName();
System.out.println(s2);
//查询文件路径
String s3 = f.getPath();
System.out.println(s3);
//查询父级文件路径
String s4 = f.getParent();
System.out.println(s4);
//判断是否为文件
boolean b = f.isFile();
System.out.println(b);
//判断是否为目录
boolean b2 = f.isDirectory();
System.out.println(b2);
//判断文件是否可读
boolean b3 = f2.canRead();
System.out.println(b3);
//判断文件是否可写
boolean b4 = f2.canWrite();
System.out.println(b4);
//判断文件或目录是否存在。
boolean b5 = f2.exists();
System.out.println(b5);
//列出指定目录下所有子文件名包括目录名
String[] arr = f.list();
System.out.println(Arrays.toString(arr));
//列出指定目录下所有子文件包括目录的完整路径
File[] arr2 = f.listFiles();
System.out.println("+++++++"+arr2[2].toString());
System.out.println(Arrays.toString(arr2));
for (File file: arr2) {
//获取文件名和目录名
System.out.println(file.getName());
//获取完整路径
System.out.println(file.toString());
}
}
}
输出目录下所有文件
//输出目录下所有文件
public class Test3 {
public static void main(String[] args) {
showAllFiles("f:/java151/FileTest/YTR");
}
public static void showAllFiles(String path){
File file = new File(path);
if(!file.exists() || !file.isDirectory()){
return;
}
File[] files = file.listFiles();
for (File f : files){
if(f.isDirectory()){
System.out.println(f.getPath()+">>>");
showAllFiles(f.getPath());
}else {
System.out.println(f.getPath());
}
}
}
}
input输入流,程序从文件读数据。 output输出流,程序向文件写数据。
io流有很多种:
按操作数据的不同分为:
字节流(以字节为传输单位)
字符流(以字符为传输单位)
按照数据传输方向的不同分为:
输入流
输出流
根据功能不同分为:
节点流(直接和文件进行交互)
处理流(不是直接作用在文件上)
四个基本的流: 其他的流都是在这四个流的基础上进行扩展的
字节输入流
字节输出流
字符输入流
字符输出流
用于向某目标设备写入字符,它是所有字符输出流的根类,我们用FileWriter实现类。
public class Charipop {
public static void main(String[] args) throws Exception{
//输出流
//指定对哪个文件(路径)进行写操作
//覆盖写入,会覆盖文件原有内容。
Writer file = new FileWriter("F:/java151/FileTest/YTR/Text.txt");
String s = "不必说碧绿的菜畦,光滑的石井栏\n";
//直接在方法里写内容
file.write("不必说碧绿的菜畦,光滑的石井栏,高大的皂荚树\n");
//写在字符串里然后加入
file.write(s);
file.flush(); //刷新流
file.close(); //关闭流资源
}
}
public class Charipop {
public static void main(String[] args) throws Exception{
//输出流
//指定对哪个文件(路径)进行写操作
//追加写入
Writer file = new FileWriter("F:/java151/FileTest/YTR/Text.txt",true);
String s = "不必说碧绿的菜畦,光滑的石井栏\n";
//直接在方法里写内容
filep.write("不必说碧绿的菜畦,光滑的石井栏,高大的皂荚树\n");
//写在字符串里然后加入
file.write(s);
file.flush(); //刷新流
file.close(); //关闭流资源
}
}
用于从设备读取数据,它是所有字符输入流的根类 它的实现类有很多,我们使用FileReader实现类。
//输入流 //指定操作的文件
Reader r = new FileReader("F:/java151/FileTest/YTR/Text.txt");
//一次读取一个字符,int接收的是个ASCII码值
int str = r.read();
//将ASCII码值转为字符
System.out.println((char)str);
//一次都读多个
//定义一个字符数组
char[] ch = new char[5];
//将读取的字符存入数组,数组长度就是读取个数,int接收数组长度
int str2 = r.read(ch);
//从指定下标开始存,存入3个
//int str2 = r.read(ch,1,3);
//将字节数组转为字符串
String st = new String(ch);
//从指定的下标开始转换,转换个数为数组长度。
//String st = new String(ch,0,str2);
System.out.println(st);
在计算机中,无论是文本、图片、视频与音频都是以二进制形式存在的,IO流针对字节的输入输出提供了一系列的流,统称为字节流。
字节流是程序中最常用的流,根据传输方向分为:
字节输入流:InputStream
字节输出流:OutputStream
他们都是字节流的顶级父类。
字节输入流注意点:
中文一个字占3字节,中文标点也是。英文1个字母占1个字节。
比如中文有两个字,只读5字节,那最后的一个字会乱码。
//若文件不存在会创建文件
OutputStream ops = new FileOutputStream("F:\\java151\\FileTest\\0420\\aaa\\aaa.txt");
String val = "窗前明月光";
//将字符串转为字节数组
byte[] b = val.getBytes();
//写入文件
ops.write(b);
ops.close();
追加写入
//若文件不存在会创建文件
OutputStream ops = new FileOutputStream("F:\\java151\\FileTest\\0420\\aaa\\aaa.txt",true);
String val = "疑是地上霜";
//将字符串转为字节数组
byte[] b = val.getBytes();
//写入文件
ops.write(b);
ops.close();
//要操作的文件
InputStream ips = new FileInputStream("F:/java151/FileTest/0420/aaa/aaa.txt");
//中文一个字占3字节,所以这里一次读一个字,中文的标点也是一个占3字节
byte[] c= new byte[3];
//int接收数组长度。
int a = ips.read(c);
//将byte数组转为字符串,从下标0开始转,长度为数组长度
String s1 = new String(c,0,a);
System.out.println(s1);
//读取多个,指针为空就返回-1,所以这里是读取文件全部内容
byte[] b5 = new byte[3];
int a1 = 0;
while ((a1 = ips.read(b5))!=-1){
String s2 = new String(b5,0,a1);
System.out.println(s2);
}
在应用程序中,IO流都是成对出现的,即输入输出一起使用,文件的拷贝就是通过输入流读取数据,然后输出流写数据。
字符流文件的拷贝字符文件,对于图片、视频登字节文件无法拷贝。
字节流既可以拷贝字符,又可以拷贝图片、视频等,但用字节拷贝字符可能乱码等问题,所以对于纯字符文件,建议使用字符流拷贝。
//字符流复制文本
File file = new File("F:\\java151\\FileTest\\0420");
file.mkdir();
File file1 = new File("F:\\java151\\FileTest\\0420\\text1.txt");
file1.createNewFile();
File file2 = new File("F:\\java151\\FileTest\\0420\\text2.txt");
file2.createNewFile();
//要复制的文件
FileReader fileReader = new FileReader("F:\\java151\\FileTest\\0420\\text1.txt");
//复制到
FileWriter fileWriter = new FileWriter("F:\\java151\\FileTest\\0420\\text2.txt");
int a =0;
//一次读10个字符
char[] chars = new char[10];
while ((a = fileReader.read(chars)) != -1){
//从下标0开始,到数组长度。
fileWriter.write(chars,0,a);
fileWriter.flush();
}
//先关读
fileReader.close();
//再关写
fileWriter.close();
//创建输入流
InputStream isp1 = new FileInputStream("F:/java151/FileTest/0420/aaa/aaa.txt");
//创建输出流
OutputStream ops1 = new FileOutputStream("F:/java151/FileTest/0420/aaa/aaa2.txt");
byte[] barr = new byte[3];
int n = 0;
//将读取的ASCII码值存入字节数组,然后将数组长度给n
while ((n = isp1.read(barr))!=-1){
//将读取的内容写入到另一个文件
ops1.write(barr,0,n);
}
//先关读
isp1.close();
//再关写
ops1.close();
字节流读写文件是一个字节一个字节的读写,读一个写一个,少量文件不影响,但文件量大的话这种频繁的操作文件,效率非常低。为了提高效率,可以定义一个字节数组作为缓冲区,在拷贝文件时,可以一次性读取多个字节数据,并保存在字节数组中,然后将字节数组一次性写入文件。
//创建输入流
InputStream isp1 = new FileInputStream("F:/java151/FileTest/0420/aaa/aaa.txt");
//创建输出流
OutputStream ops1 = new FileOutputStream("F:/java151/FileTest/0420/aaa/aaa2.txt");
//定义一个字节数组,作为缓冲区
byte[] barr = new byte[1024];
//定义一个整型记住缓冲区的字节数。
int n = 0;
//将读取的ASCII码值存入字节数组,然后将数组长度给n,并判断是否到文件尾部。
while ((n = isp1.read(barr))!=-1){
//将读取的内容写入到另一个文件,从第一个字节开始,写入n个字节
ops1.write(barr,0,n);
}
//先关读
isp1.close();
//再关写
ops1.close();
缓存流是在四类基础流[InputStream、OutputStream、Reader、Writer]之上 添加了一个缓存池功能.
BufferInutStream BufferOutputStream BufferReader BufferWriter 提高IO的效率,降低IO的次数。缓存流要作用在基础流上,缓存流不再直接接收文件地址,而是接收基础流对象。
缓存流拷贝文件
关闭时先关闭读入,再刷新读入缓存,再关闭读入缓存,再刷新写入缓存,再关闭写入缓存,再刷新写入,然后关闭写入。
OutputStream out=new FileOutputStream("D:/AAA/g.txt");
BufferedOutputStream bos=new BufferedOutputStream(out);//缓存流要作用再基础流上
String str="abcdefhijglmn";
byte[] bytes = str.getBytes();
bos.write(bytes); //因为你写的内容 暂时放入缓存池中 并没有直接放入文件中。 所以文件中没有你的内容。
//bos.flush();//刷新缓存池---把池子中的内容输入到文件上
bos.close(); //关闭----先刷新缓冲池 再关闭流资源jj
在IO包中提供了两个带缓冲流的字节流,BufferInutStream 、BufferOutputStream,这两个流内部都定义了一个大小为8192的字节数组,当调用缓存流的read()或write()方法时,首先将读写的数据存入定义好的字节数组,然后再写入文件。这种方式类似于方法给我们在内部定义了一个字节流缓冲区。
//创建字节流输出对象
InputStream ip = new FileInputStream("F:/java151/FileTest/0420/test3.txt");
//创建缓存字节流输出对象,接收字节流对象
BufferedInputStream bps = new BufferedInputStream(ip);
byte[] b = new byte[3];
bps.read(b);
String s = new String(b,0,b.length);
System.out.println(s);
ip.close();
bps.close();
OutputStream ops = new FileOutputStream("F:/java151/FileTest/0420/test3.txt",true);
BufferedOutputStream bops = new BufferedOutputStream(ops);
String s1 = "tyrafhgoasdfcgnoaiuyesofcakshdfnoiagtoasdfsdfasdf";
byte[] b1 = s1.getBytes();
bops.write(b1);
bops.flush();
bops.close();
Reader r = new FileReader("F:/java151/FileTest/0420/test3.txt");
BufferedReader br = new BufferedReader(r);
char[] c = new char[1024];
int i = br.read(c);
String si = new String(c);
System.out.println(si);
Writer w = new FileWriter("F:/java151/FileTest/0420/test3.txt",true);
BufferedWriter bw = new BufferedWriter(w);
bw.write("不必说碧绿的菜畦,光滑的石井栏,高大的皂荚树,紫红的桑葚;也不必说鸣蝉在树叶里长吟,肥胖的黄蜂伏在菜花上,轻捷的叫天子忽然从草间");
bw.flush();
bw.close();
w.close();
public class Aaa {
public static void main(String[] args) throws IOException {
//创建字节输入流
InputStream is = new FileInputStream("F:/java151/FileTest/0420/aaa/js.png");
//创建字节缓存输入流,接收字节输入流
BufferedInputStream bis = new BufferedInputStream(is);
//创建字节输出流
OutputStream os = new FileOutputStream("F:/java151/FileTest/0420/aaa/js3.png");
//创建字节缓存输出流,接收字节输出流
BufferedOutputStream bos = new BufferedOutputStream(os);
int len;
while ((len = bis.read())!=-1){
bos.write(len);
}
//关字节输入流
is.close();
//关字节缓存输入流
bis.close();
//关字节缓存输出流
bos.close();
//关字节输出流
os.close();
}
}
为什么需要对象流
我们现在操作IO流的时候 都是将字符串读写操作 可不可以将java对象在文件中进行读写呢?
将java对象进行读写操作 意义在于持久化信息 例如: 游戏存档。因为运行的时候所有的数据都是在运行内存中的,持久化是将运行内存的数据保存到硬盘上。java对象所属的类必须实现序列化接口Serializable,否则会抛出异常NotSerializabileException;
对象输出流经过oops.writeObject(xx),首先将对象按照其结构转换为一组字节,这个过程为对象序列化;
对象输入流oips.readObject(),和上面是反过来的,把字节转换为对象。这个过程为对象反序列化;
1. 序列化: 把内存中的java对象存储到磁盘[网盘]的过程。
2. 反序列化: 把磁盘中的内容读取到java对象内存中的过程。
//必须实现Serializable接口
public class xinxi implements Serializable {
private String name;
private int id;
public xinxi(String name, int id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "xinxi{" +
"name='" + name + '\'' +
", id=" + id +
'}';
}
}
public class Test {
public static void main(String[] args) throws IOException {
OutputStream ops = new FileOutputStream("F:/java151/FileTest/0420/xulie.txt");
ObjectOutputStream oops = new ObjectOutputStream(ops);
xinxi xx = new xinxi("张三",10);
//序列化
oops.writeObject(xx);
oops.close();
}
}
class Test2{
public static void main(String[] args) throws Exception{
InputStream ips = new FileInputStream("F:/java151/FileTest/0420/xulie.txt");
ObjectInputStream oips = new ObjectInputStream(ips);
//反序列化
Object o = oips.readObject();
System.out.println(o);
oips.close();
}
}
IO流分为字节流与字符流,有时他们之间需要互相转换,JDK提供了两个类可以完成此操作,InputStreamReader、OutputStreamWriter
InputStreamReader是Reader的子类,它可以将一个字节输入流转换为字符输入流,方便直接读取字符。 OutputStreamWriter是Writer的子类。它可以将一个字节输出流转换为字符输出流,方便直接写入字符。 需要注意,转换流只针对操作文本文件的字节流进行转换,如果是字节流操作的是图片等非文本,此时进行转换会造成数据丢失。
public class IpzhuanWr {
public static void main(String[] args) throws IOException {
//创建字节文件输入流
InputStream is = new FileInputStream("F:/java151/FileTest/test.txt");
//创建字节转换字符流
InputStreamReader isr = new InputStreamReader(is);
//创建字节文件输出流
OutputStream ops = new FileOutputStream("F:/java151/FileTest/test9.txt",true);
//创建字节转换字符流
OutputStreamWriter osw = new OutputStreamWriter(ops);
String s = "不必说碧绿的菜畦,光滑的石井栏,高大的皂荚树,紫红的桑葚;也不必说鸣蝉在树叶里长吟,肥胖的黄蜂伏在菜花上,轻捷的叫天子忽然从草间";
osw.write(s);
is.close();
isr.close();
osw.flush();
ops.flush();
osw.close();
ops.close();
}
}