1 File类
1.1 基本介绍
File类代表系统中的文件对象(文件或目录),位于java.io包下。
存储介质上的文件或目录在Java程序中都是用File类的实例来表示。
通过File类,可以实现对系统中文件或目录的操作,类似我们在操作系统中借助鼠标、快捷键等对文件或目录进行增删改的操作。
1.2 通过File类操作文件或目录
File类中常用方法
方法名称 | 说明 |
---|---|
boolean exists( ) | 判断文件或目录是否存在 |
boolean isFile( ) | 判断是否是文件 |
boolean isDirectory( ) | 判断是否是目录 |
String getPath( ) | 返回此对象表示的文件的相对路径名 |
String getAbsolutePath( ) | 返回此对象表示的文件的绝对路径名 |
String getName( ) | 返回此对象表示的文件或目录的名称 |
boolean delete( ) | 删除此对象指定的文件或目录,如果是目录,必须为空才能删除 |
boolean createNewFile( ) | 创建名称的空文件,不创建文件夹 |
public boolean mkdir() | 创建此路径名指定的目录 |
long length() | 返回文件的长度,单位为字节, 如果文件不存在,则返回 0L |
public String[] list() | 返回目录中的文件和目录的字符串数组 |
public class App1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
// windows 以盘符开始的路径 绝对路径
//File file = new File("D:\\a.txt");
File file = new File("D:/a.txt");
//判断是否文件
System.out.println(file.isFile());
//判断是否是文件夹
System.out.println(file.isDirectory());
//得到文件或文件夹名称
System.out.println(file.getName());
//得到路径
System.out.println(file.getPath());
//得到绝对路径
System.out.println(file.getAbsolutePath());
//得到上一级路径
System.out.println(file.getParent());
//获取最后修改的时间,相对1970年开始的毫秒数
System.out.println(file.lastModified());
}
}
public class App2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
File file = new File("D:/a.txt");
//判断文件是否存在
if(!file.exists()){
// 创建文件,如果文件已经存在,返回false
boolean ret = file.createNewFile();
if (ret) {
System.out.println("创建文件成功");
} else {
System.out.println("创建文件失败");
}
}else{
System.out.println("文件已存在");
}
//删除文件
file.delete();
File file2 = new File("D:/test/text");
if(!file2.exists()){
// 创建路径
// 如果路径中包含不存在的目录,创建失败
boolean ret = file2.mkdir();
System.out.println(ret);
// 如果路径中包含不存在的目录,会一同创建
ret = file2.mkdirs();
System.out.println(ret);
}else{
System.out.println("文件夹已存在");
}
//删除目录,非空目录不能直接删除
file2.delete();
File f = new File("D:\\");
//只会遍历一级目录,返回的是文件夹中的文件和子目录的名字
String[] fileNames = f.list();
for (String name : fileNames) {
System.out.println(name);
}
//返回文件夹中的文件或目录的File对象数组
File[] files = f.listFiles();
for (File f1 : files) {
System.out.println(f1);
}
}
}
2 IO流
I/O:Input/Output,输入/输出。
stream:流,数据流,是数据传输、通信的通道
Java应用程序中,“流”是基本的传输数据的方式。JDK提供了各种“流”来操作数据
2.1 基本介绍
2.1.1 流的分类
按流向分:
输入流:从数据源到程序中的流
输出流:从程序到数据源的流
按数据传输单位分:
字节流:以字节为单位传输数据的流
可以操作文本文件(.txt、.java等)、二进制文件(图片、音视频文件等)
字符流:以字符为单位传输数据的流
操作文本文件
2.1.2 Java中的流
JDK提供的流类位于java.io包中,主要继承自以下四种抽象父类
字节流 | 字符流 | |
---|---|---|
输入流 | InputStream | Reader |
输出流 | OutputStream | Writer |
我们需要关注的:
2.2 字节流
2.2.1 InputStream抽象类
输入流
方法 | |
---|---|
public abstract int read() throws IOException | 从输入流中读取数据的下一个字节,返回读到的字节值,若到达流的末尾,返回-1 |
public int read(byte[] b) throws IOException | 从输入流中读取数据到缓冲区数组b中,返回实际读到的字节总数 |
public int read(byte[] b, int off, int len) throws IOException | 读取 len 个字节的数据,并从数组b的off位置开始写入到该数组中 |
public void close() throws IOException | 关闭此输入流并释放与此流关联的所有系统资源 |
2.2.2 FileInputStream
该类是字节输入流InputStream的常用实现类。
构造方法如下:
方法 | |
---|---|
public FileInputStream(File file) | 根据一个file实例来创建FileInputStream对象 |
public FileInputStream(String name) | 根据文件名称来创建FileInputStream对象 |
操作流程:
1)一次读取一个字节的数据:
public class App {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 输入字节流
FileInputStream fileInputStream = null;
try {
// 1 创建输入流的对象
fileInputStream = new FileInputStream("D:/a.txt");
// 2 进行操作 read() 一次读取一个字节 返回值为-1 表示读取结束
/*
* int info = fileInputStream.read(); System.out.println(info); // 将ascii码强转为字符
* System.out.println((char)info);
*
* info = fileInputStream.read(); System.out.println((char)info);
*/
// int info = -1;
// while((info = fileInputStream.read()) != -1) {
// System.out.println((char)info);
// }
int info = fileInputStream.read();
while(info != -1) {
System.out.println((char)info);
info = fileInputStream.read();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if(fileInputStream != null) {
try {
// 3 关闭流对象
fileInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
2)将数据读到字节数组中:
public class App2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream("D:/a.txt");
byte[] buff = new byte[1024];
// 将数据读到字节数组里,read(byte[]) 返回值表示读取的字节的长度
int length = inputStream.read(buff);
System.out.println(length);
// 将字节数组转为字符串
// 第一个参数:待转换的字节数组;第二个参数:起始位置;第三个参数:转换的长度
String info = new String(buff, 0, length);
System.out.println(info);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
2.2.3 OutputStream抽象类
输出流,OutputStream常用方法
方法 | |
---|---|
public abstract void write(int b) throws IOException | 将指定的字节写入此输出流 |
public void write(byte[] b) throws IOException | 将 b.length 个字节从指定的 byte 数组写入此输出流 |
public void write(byte[] b, int off, int len) throws IOException | 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流 |
public void flush() throws IOException | 刷新此输出流并强制写出所有缓冲的输出字节 |
pulbic void close() throws IOException | 关闭此输出流并释放与此流有关的所有系统资源(含刷新操作) |
2.2.4 FileOutputStream
该类是字节输出流OutputStream的常用实现类。构造方法如下:
方法 | |
---|---|
public FileOutputStream(File file) | 根据一个file实例来创建FileOutputStream对象 |
public FileOutputStream(File file, boolean append) | 根据一个file实例来创建输出流对象,指定是否可追加 |
public FileOutputStream(String name) | 根据文件名称来创建FileOutputStream对象 |
public FileOutputStream(String name, boolean append) | 根据一个file实例来创建输出流对象,指定是否可追加 |
操作步骤:
1)基本用法
public class App {
public static void main(String[] args) {
// TODO Auto-generated method stub
FileOutputStream outputStream = null;
try {
// 默认是覆盖写,将原来的内容删除,重新写入
// outputStream = new FileOutputStream("D:/b.txt");
// 第二个参数,表示是否采用追加写的方式
outputStream = new FileOutputStream("D:/b.txt", true);
// write参数表示的一个字节数据
outputStream.write('a');
outputStream.write(97);
String s = "hahaha今天天气不错";
// String中的getBytes() 将字符串转换为字节数组
outputStream.write(s.getBytes());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
outputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
2)文件拷贝
public class FileCopy {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 读取文件
FileInputStream inputStream = null;
// 写入文件
FileOutputStream outputStream = null;
try {
inputStream = new FileInputStream("D:/123.png");
outputStream = new FileOutputStream("D:/456.png");
// 存放读取的数据,长度不能太大
byte[] buff = new byte[1024];
// 读取的长度
int length = -1;
while((length = inputStream.read(buff)) != -1) {
outputStream.write(buff, 0, length);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
inputStream.close();
outputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
2.3 字符流
2.3.1 Reader抽象类
字符输入流,用于向程序中输入数据,且数据的单位为字符。
主要方法:
int read( )
int read(char[] c)
read(char[] c,int off,int len)
void close( )
2.3.2 FileReader
构造方法
FileReader(File file)
FileReader(String fileName)
public class FileReaderApp {
public static void main(String[] args) {
// TODO Auto-generated method stub
FileReader fileReader = null;
try {
// 如果编码格式不一致,会有乱码问题。
// 解决方案:使用InputStreamReader;或者想办法保持编码一致
fileReader = new FileReader("D:/a.txt");
int read = fileReader.read();
System.out.println((char)read);
char[] buff = new char[1024];
int length = fileReader.read(buff);
System.out.println(new String(buff, 0, length));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
fileReader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
2.3.3 BufferedReader
字符缓冲输入流
缓冲流中定义了一个缓冲数组,类似我们讲FileInputStream时,定义的自己数组,
使用缓冲数组后,整体的读取/写入效率提升很大
所有的缓冲流都没有任何的读取、写入文件能力,都需要借助对应的输入流和输出流来提供对应的能力。
在创建缓冲流流对象时,需要传入对应的输入流对象和输 出流对象。
缓冲流底层只是提供了一个默认大小的缓冲数组,用于提高效率
构造方法
BufferedReader(Reader in)
增加了 String readLine() ,用于读取一行数据,如果文件结束,返回null
public class BufferedReaderApp {
public static void main(String[] args) {
// TODO Auto-generated method stub
FileReader fileReader = null;
BufferedReader bufferedReader = null;
try {
fileReader = new FileReader("b.txt");
// 参数是Reader对象
bufferedReader = new BufferedReader(fileReader);
// 读取一行数据
String info = bufferedReader.readLine();
System.out.println(info);
// readLine返回null,表示读取结束
while((info = bufferedReader.readLine()) != null) {
System.out.println(info);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
bufferedReader.close();
fileReader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
2.3.4 Writer抽象类
字符输出流,用于程序向外输出数据,且数据的单位为字符
主要方法:
void write(int c)
void write(char[] carr)
void write(char[] carr, int off, int len)
void write(String str)
void flush() / close()
2.3.5 FileWriter
构造方法
FileWriter(File file)
FileWriter(File file, boolean append)
FileWriter(String fileName)
FileWriter(String fileName, boolean append)
public class FileWriterApp {
public static void main(String[] args) {
// TODO Auto-generated method stub
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter("c.txt", true);
fileWriter.write("又翻车了");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
fileWriter.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
2.3.6 BufferedWriter
字符缓冲输出流:该类为字符输出流Writer的缓冲流。
构造方法:
BufferedReader(Writer out)
增加了void newLine() ,用于换行
public class BufferedWriterApp {
public static void main(String[] args) {
// TODO Auto-generated method stub
FileWriter fileWriter = null;
// 效率相对高
BufferedWriter bufferedWriter = null;
try {
fileWriter = new FileWriter("c.txt");
bufferedWriter = new BufferedWriter(fileWriter);
// 写到缓冲区里。如果缓冲区满了;调用flush();流close() 都会将数据写入文件
bufferedWriter.write("hahahahah");
// 刷新缓冲区,将数据写入文件
bufferedWriter.flush();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
// 关闭流的时候,如果缓冲区中有数据,将数据写入文件
bufferedWriter.close();
fileWriter.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
2.4 转换流 (了解)
转换流用于字节流和字符流之间的转换。
JDK中的IO流,分为字节流、字符流。如果需要进行二者之间的转换,可以使用转换流。
2.4.1 InputStreamReader:
Reader的子类,将输入的字节流变为字符流,即:将一个字节流的输入对象变为字符流的输入对象
InputStreamReaderI是字节流通向字符流的桥梁,需要和InputStream“套接”
public class InputStreamReaderApp {
public static void main(String[] args) {
// TODO Auto-generated method stub
FileInputStream fileInputStream = null;
InputStreamReader inputStreamReader = null;
try {
fileInputStream = new FileInputStream("a.txt");
// 转换流 ,类似字节流和字符流之前的桥梁
inputStreamReader = new InputStreamReader(fileInputStream);
// 一次读取一个字符,返回值表示读取的字符
int read = inputStreamReader.read();
System.out.println((char)read);
char[] buff = new char[1024];
// 返回值表示读取的字符的长度(个数)
int length = inputStreamReader.read(buff);
System.out.println(new String(buff, 0, length));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
// 流对象之间如果有调用关系,一般建议后创建的先close
inputStreamReader.close();
fileInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
通过转换流可以解决编码不一致的问题
public class InputStreamReaderApp2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
FileInputStream fileInputStream = null;
InputStreamReader inputStreamReader = null;
try {
fileInputStream = new FileInputStream("utf8.txt");
// 默认eclipse用的gbk编码,一个中文字符占2个字节,如果读的文件是其他编码,比如utf-8,中文字符占3个字节
// 编码格式不一致,转换的时候,引起乱码问题
// inputStreamReader = new InputStreamReader(fileInputStream);
// 第二个参数,表示按照指定的格式转换字节流,解决乱码问题
inputStreamReader = new InputStreamReader(fileInputStream, "utf-8");
// 一次读取一个字符,返回值表示读取的字符
int read = inputStreamReader.read();
System.out.println((char)read);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
// 流对象之间如果有调用关系,一般建议后创建的先close
inputStreamReader.close();
fileInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
2.4.2 OutputStreamWriter:
Writer的子类,将输出的字符流变为字节流,即:将一个字符流的输出对象变为字节流的输出对象
OutputStreamWriter是字符流通向字节流的桥梁,需要和OutputStream“套接”
public class OutputStreamWriterApp {
public static void main(String[] args) {
// TODO Auto-generated method stub
OutputStream outputStream = null;
OutputStreamWriter outputStreamWriter = null;
try {
outputStream = new FileOutputStream("c.txt");
outputStreamWriter = new OutputStreamWriter(outputStream);
// 参数可以是字符串 write 覆盖写
outputStreamWriter.write("hello world你好世界");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
outputStreamWriter.close();
outputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
2.5 对象流 (了解)
2.5.1 序列化、反序列化
序列化:把对象转换为字节序列的过程称为对象的序列化
反序列化:把字节序列恢复为对象的过程称为对象的反序列化
JDK提供ObjectOutputStream和ObjectInputStream类,用于对象的序列化、反序列化
ObjectOutputStream:保存对象状态到文件,序列化
ObjectInputStream:读取对象二进制文件到内存,反序列化
2.5.2 ObjectOutputStream
构造方法
public ObjectOutputStream(OutputStream out)
public ObjectInputStream(InputStream in)
注意:
能被序列化的对象所对应的类必须实现java.io.Serializable接口
读入的顺序必须和写出的顺序一致
transient(暂态的)关键字:修饰成员变量时,该成员变量将不被序列化,读取的值为null
//序列化的类,必须实现Serializable接口,该接口中没有任何方法
//序列化类中的成员变量如果是引用类型,必须支持序列化
public class Dog implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private int age;
//如果某个成员不需要序列化,可以使用transient修饰
public Dog(String name, int age){
this.name = name;
this.age = age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return this.name + " " + this.age + " " + this.toy;
}
}
public class Demo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// TODO Auto-generated method stub
writeObject();
}
private static void writeObject() throws IOException{
//参数为字节输出流
ObjectOutputStream oo = new ObjectOutputStream(
new FileOutputStream("D:/o.txt"));
Dog dog = new Dog("wangcai", 5);
oo.writeObject(dog);
oo.close();
}
}
2.5.3 ObjectInputStream
public class Demo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// TODO Auto-generated method stub
readObject();
}
private static void readObject() throws IOException, ClassNotFoundException{
ObjectInputStream oi = new ObjectInputStream(
new FileInputStream("D:/o.txt"));
Dog dog = (Dog)oi.readObject();
System.out.println(dog);
oi.close();
}
}