File类
file类是java.io下的一个重要的类,直接继承Object类,实现了Serializable和Comparable
File类的对象可以表示文件,还可以表示目录,在程序中的一个File类对象可以代表一个文件或目录;
import java.io.File;
import java.io.IOException;
public class FileDemo2 {
public static void main(String[] args) {
//file 类的几种构造方法:(即使文件不存在,也不会报错)
//File f = new File("E:\\demo.txt");//直接给文件的绝对路径
//File f = new File("E:","demo.txt");//父级和子集分开
/*File pf = new File("E:");
File cf = new File(pf,"demo.txt");*/
File f = new File("E:\\demotest.txt");
if (!f.exists()){//判断该路径下是否有目标文件
try {
f.createNewFile();//创建目标文件
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println(f.getParent());//获取f的父级
System.out.println(f.canExecute());
System.out.println(f.isHidden()?"此文件为隐藏文件":"此文件不是隐藏文件");
System.out.println(f.canRead()?"此文件为可读文件":"此文件是不可读文件");
System.out.println(f.canWrite()?"此文件为可修改文件":"此文件不可修改文件");
System.out.println(f.isFile());//判断f所表示的对象是不是文件
System.out.println(f.isDirectory());//判断f所表示的对象是不是文件夹(目录)
System.out.println(f.getAbsoluteFile());//获取此文件的绝对路径
System.out.println(f.length());//返回文件的字节大小.
System.out.println(f.lastModified());//输出最后一次修改文件的时间
try {
System.out.println(f.getCanonicalFile());//返回此抽象路径名的规范形式。
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(f.getName());//获取f对象所表示文件或目录的名字
System.out.println(f.getPath());//获取文件路径
f.delete();//删除文件,但是每次只能删除一个文件,并且所删的文件必须为空.
File file = new File("E:/wd/dy");
if (!file.exists()){
//file.mkdir();//只能创建一级文件夹
file.mkdirs();//可以创建多级级文件夹
}
file.delete();//删除文件夹时只能删除一级文件夹,并且该文件夹为空.
}
}
获取一个目录中所有的文件及文件夹
File file = new File("E:\\demo");
String [] fs = file.list();//获取的都是文件及文件的名字(string类型)
File[] files = file.listFiles();//将demo文件下的文件及文件夹 存放在一个File数组中,直接得到file对象;
// 过滤部分文件
File[] f=file.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".txt");
}
});
/*
File[] f=file.listFiles((file,name)->{
name.endsWith(".txt")
});*/
输入及输出的概念
输入: 把电脑上的数据读到程序中,称为输入(input),对数据进行read操作;
输出:从程序中往外部设写数据,称为输出(output),对数据进行write操作。
字节流与字符流
从数据编码格式上划分为:字节流和字符流。
字节流:每次读写数据时以字节为单位进行操作。
字符流:每次以字符进行操作。
流按照数据的传输方向分为:输入流和输出流。
InputStream和OutputStream的子类都是字节流,
可以读写二进制文件,主要处理音频,图片,歌曲,字节流处理单元为1字节。
Reader和Writer的子类都是字符流(涉及装换问题)
主要处理字符或字符串,字符流处理单元格为一字符。
原始读到的还是字节,字节流将读取到的字节数据,去指定的编码表中获取对应文字。
- 字节流常用的方法:
字节输入流:FileInputStream (文件字节输入流)
字节输出流:FileOutputStream (文件字符输出流)
- 字符流常用的方法:
字符输入流:FileReader
字符输入流:FileWriter
输入输出节点字节流
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo2 {
public static void main(String[] args) {
FileInputStream in=null;
FileOutputStream out=null;
try {
//创建一个字节输入流对象,并将流对象接入到指定的文件上,如果找不到制定文件,会报异常
in = new FileInputStream("E:/demo.txt");
//创建一个字节输出流对象,同时创建一个空文件
out = new FileOutputStream("F:/demo.txt");//如果F:/demo.txt不存在就会自动创建一个文件
int x;
//in.read()从输入文件中读取数据,每read一次就会向下读一个字节并以整数的形式返回(0~255),当返回-1时已到输入流的末尾
while ((x=in.read())!=-1){
System.out.println(x);
out.write(x);//将从输入文件中的得到的数据输出到out输出文件中
}
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("未找到文件");
} catch (IOException e) {
e.printStackTrace();
System.out.println("读或写发生错误");
}finally {
try {
if (in!=null){//防止在in为赋对象时就发生了异常
in.close();//关闭流,释放资源
}
if (out!=null){
out.close();
}
}catch (IOException ex){
}
}
}
}
使用byte数组的方式输入输出:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo2 {
public static void main(String[] args) throws IOException {
FileInputStream in=new FileInputStream("E:/demo.txt");
FileOutputStream out= new FileOutputStream("F:/demo.txt");
byte[] bytes = new byte[10];
int size;
//size = in.read(bytes);//把一个空的byte数组传入 , 将内容读到byte数组中 size表示实际向byte数组中装入的字节的个数;
while ((size=in.read(bytes))!=-1){
System.out.println(size);
//输出bytes数组个字节,每次从bytes数组的第0位置开始,到bytes的实际存放个数结束
out.write(bytes,0,size);//从byte数组中向外写,从0位置开始,到size位置结束
}
}
}
节点流与处理流
根据封装类型不同流又分为:节点流和处理流。
节点流:流对象中直接包含数据(文件,字符串等)。例如:FileInputStream ,FileOutputStream
处理流:流对象封装的是其他流对象。处理流提供了缓冲区功能,提高了读写效率,同时增加了一些新方法。
其实节点流和处理流的输入输出方法名都相同,使用方法也相同,只是底层实现原理不同。处理流底层有一个缓冲区。以BufferedInputStream缓冲字节输入为例,当时用byte数组形式读入时,如果所定义的数组长度小于缓冲区的大小,则数据不会立即被读入,会先存放在缓冲区直至缓冲区满了之后,将缓冲区的数据读入程序中来。
import java.io.*;
public class Demo3 {
public static void main(String[] args) throws IOException {
//节点流:直接包含数据,对数据进行操作
FileInputStream in = new FileInputStream("E:/feige.exe");
FileOutputStream out = new FileOutputStream("E:/feige1.exe");
//处理流(包装流):包含的是一个流对象,对流对象进行操作.其底层有一个缓冲数组,当数组满时才能进行操作,当我们自己定义的数组长度大于缓冲数组长度时,缓冲数组不起作用.
//创建处理流:
//BufferedInputStream 在创建时是需要传入一个 InputStream 流对象 此处传入FileInputStream类型的in对象体现出面向对象特点中多态的一种引用.
BufferedInputStream bin = new BufferedInputStream(in);
/*
public BufferedInputStream(InputStream in) {
this(in, DEFAULT_BUFFER_SIZE);
//DEFAULT_BUFFER_SIZE:使用处理流时,默认的缓冲区 大小为8192 (可以在创建对象时,自己给定值);
}
*/
BufferedOutputStream bout = new BufferedOutputStream(out);
byte[] bytes = new byte[1024];
int size=0;
while ((size=bin.read(bytes))!=-1){
bout.write(bytes,0,size);
}
bin.close();
bout.flush();//刷新
bout.close();
}
}
输入输出节点字符流
字符流:每次读取单位字符,字符流只能对纯文本文件进行操作(.txt ,.java ,.html等)。
计算机中的文件都是以字节的方式存储,而字符流每次能读到一个字符,是因为通过中间的转换流(如InputStreamReader,OutputStreamWriter),将读到的字符按照特定的编码转成字符。
//每次读取一个字符
public static void main(String[] args) throws IOException {
//最基本的输入输出与字节流相同
FileReader reader = new FileReader("E:/demo.txt");
FileWriter writer = new FileWriter("E:/demo1.txt");
int a;//表示赌读到的字符的编码
while ((a= reader.read())!=-1){
writer.write(a);
}
reader.close();
writer.close();
}
利用char数组一次读取多个字符
//一次读取多个 与字节流相同
public static void main(String[] args) throws IOException {
FileReader reader = new FileReader("E:/demo.txt");
FileWriter writer = new FileWriter("E:/demo3.txt");
char[] chars = new char[10];
int size;
while ((size= reader.read(chars))!=-1){
writer.write(chars,0,size);
}
reader.close();
writer.close();
}
每次读取一行
public static void main(String[] args) throws IOException {
FileReader reader = new FileReader("E:/demo.txt");
//为了每运行一次不覆盖之前的数据添加布尔数据append
FileWriter writer = new FileWriter("E:/demo3.txt",true);
BufferedReader breader = new BufferedReader(reader);
BufferedWriter bwrier = new BufferedWriter(writer);
String str;
while ((str= breader.readLine())!=null){//breader.readLine()返回string类型,当读取到null值时表示已经到结尾了。
bwrier.write(str);//输出读取到的一行
bwrier.newLine();//文件中换行
}
breader.close();
bwrier.flush();
bwrier.close();
}
Print流
Print流 打印流:只有输出,没有输入。可以分为打印字节流和打印字符流。
import java.io.FileNotFoundException;
import java.io.PrintWriter;
public class PrintDemo {
public static void main(String[] args) throws FileNotFoundException {
PrintWriter pWriter = new PrintWriter("E:/tmp.html");
pWriter.print(222);//打印不换行
pWriter.println(33333);//打印后换行
pWriter.write(55555);//
//print在底层调用的是write方法
pWriter.close();
}
}
对象输入输出流
我们在之前创建对象时都是程序运行时创建对象,当程序运行结束时,对象就一并“死亡”,IO中有一种功能,可以将程序运行过程中创建的对象记录下来,在下次需要使用时又可以提取出来。
对象输入输出流:主要作用于对 对象信息的写入和读取,对象信息一旦被写入文件上那么就可以做到持久化。
对象输出流:ObjectOutputStream
对象输入流:ObjectInputStream
import java.io.*;
public class Deemo1{
public static void main(String[] args) throws IOException, ClassNotFoundException {
FileOutputStream out = new FileOutputStream("E:/obj.txt");
Car car1 = new Car("bm",12);
//ObjectOutputStream中用writeObject()方法可以直接将对象保存到输出流中。
ObjectOutputStream obj= new ObjectOutputStream(out);
obj.writeObject(car1);//保存到文件中是看不懂的字节文件
FileInputStream in = new FileInputStream("E:/obj.txt");
//在ObjectInputStream 中用readObject()方法可以直接读取一个对象
ObjectInputStream oin = new ObjectInputStream(in);
System.out.println(oin.readObject());
}
}
对象序列化与反序列化
对象的输出流将指定的对象写入到文件的过程,就是将对象序列化的过程;
对象的输入流将指定序列化好的文件读出来的过程,就是对象反序列化的过程。
如果对象需要实现序列化,则必须实现Serializable接口,为该类生成一个唯一的编号。
Serializable接口中没有任何方法,当一个类声明实现Serializable接口后,表明该类可以被序列化。
唯一的编号可以隐式的生成,也可以显性的生成。隐式生成时当某个类的对象序列化后对该类进行了修改那么它所对应的唯一编号也会随之改变,该类对象反序列化就可能会报错。显性的生成唯一编号时,当某个类的对象在序列化后做出了修改,该对象依然可以被正确的序列化。建议显性的为类生成唯一编号。
import java.io.Serializable;
public class Car implements Serializable {
//显示的为Car类指定一个惟一的编号.
private static final long serialVersionUID = -8274307641185506171L;
private int on ;
private String name;
public Car(int on, String name) {
this.on = on;
this.name = name;
}
public int getOn() {
return on;
}
public void setOn(int on) {
this.on = on;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Car{" +
"on=" + on +
", name='" + name + '\'' +
'}';
}
}
设置提示生成序列化接口