File类与IO流
一.File类
File类提供了对文件的操作接口,Java中万事万物都是对象,文件也有它相应的类。
- File是文件和目录路径名的抽象表示。
- 文件和目录可以通过File封装成一个对象
- File封装的不是一个真实存在的文件,仅仅是一个路径而已,对应该路径的文件可以存在,也可以不存在
1 创建一个File对象
//1.通过路径名称字符串创建
File f1 = new File("D:\\IO\\a.jpg");
//2.通过父路径名称字符串和子路径名称字符串创建
File f2 = new File("D:\\IO","a.jpg");
//3.通过父抽象路径名和子路径名称字符串创建
File parent = new File("E:\\IO");
File f3 = new File(parent,"a.jpg");
2 通过File对象创建真实的文件
createNewFile() //创建一个空文件,前提是父路径存在,且在该路径不含具有该名称的文件
mkdir() //创建由此抽象路径名命名的目录
mkdirs()//创建由此抽象路径名命名的目录,包括任何必须但不存在的父目录
//路径分隔符
//windows下使用
File f1 = new File("D:\\IO\\java.txt");
//Linux下使用
File f2 = new File("D:/IO/JavaSE");
//通用,File.separator会自动转换成所属操作系统的路径分隔符
File f3 = new File("D:" + File.separator+"IO"+File.separator+"JavaWeb"+File.separator+"HTML");
3 File类的判断和获取功能
exists() //测试此抽象路径名表示的文件或目录是否存在。
isAbsolute() //测试这个抽象路径名是否是绝对的。
isDirectory() //测试此抽象路径名表示的文件是否为目录。
isFile() //测试此抽象路径名表示的文件是否为普通文件。
isHidden() //测试此抽象路径名命名的文件是否为隐藏文件。
getAbsolutePath() //返回此抽象路径名的绝对路径名字符串。
getName() //返回由此抽象路径名表示的文件或目录的名称。
getParent() //返回此抽象路径名的父 `null`的路径名字符串,如果此路径名未命名为父目录,则返回null。
getParentFile() //返回此抽象路径名的父,或抽象路径名 `null`如果此路径名没有指定父目录。
getPath() //将此抽象路径名转换为路径名字符串
list() //返回一个字符串数组,命名由此抽象路径名表示的目录中的文件和目录
listFiles() //返回一个抽象路径名数组,表示由该抽象路径名表示的目录中的文件。
4 File类的删除功能和重命名功能
delete() //删除由此抽象路径名表示的文件或目录。
renameTo(File) //将当前文件重命名到 File所表示的抽象路径中
注意:1.只能删除文件和空目录,若目录不为空,则删除失败
2.用该方法删除的文件和目录不会进入回收箱
3.renameTo 方法还可以实现对文件的移动
二.IO流
流:是一个抽象的概念,是对数据传输的总称
IO流是用来处理设备间数据传输问题的
input:指的是将磁盘 硬盘 其他的外部存储设备上的文件 读入到内存
output: 指的是将内存的数据输出到外部存储设备
1 IO流的分类
按数据类型,可以分为字节流(InputStream和OutputStrean)和字符流(Reader和Writer)
按流的方向,可分为输入流和输出流
若操作的是纯文本文件,优先使用字符流
若操作的图片 音频 视频等二进制文件 优先使用字节流
如果不能确定文件的类型,推荐使用字节流,字节是万能的
2 字节流的使用
InputStream是所有字节输入流的抽象父类
OutputStream是所有字节输出流的抽象父类
子类的命名都是以InputStream/OutputStream 结尾的 常用的子类 FileInputStream
2.1 输出字节流的基本方法
//输出字节流可以用路径字符串或抽象路径 来指定要写入的文件
FileOutputStream(File file)
FileOutputStream(String name)
FileOutputStream(File file, boolean append) //append为true时表示在文件的末尾追加数据(在同一个字节流对象中时)
FileOutputStream(String name, boolean append)
//写入的方法,可以写入字节数组,或单个字节
write(byte[] b)
write(byte[] b, int off, int len)
write(int b)
close() //关闭此文件输出流并释放与此流相关联的任何系统资源。
注意在不同操作系统中表示换行的字符是不同的: windowns: \r\n linux: \n max: \r
2.2 字节流写输出的异常处理
public class OutputStreamDemo2 {
public static void main(String[] args) {
OutputStream os = null;
try{
os = new FileOutputStream("day_12/dir/fos.txt");
os.write("hello".getBytes(StandardCharsets.UTF_8));
}catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(os != null){//只有当字节输出流不为空才关闭
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2.3 字节输出流的基本方法
FileInputStream(File file)
FileInputStream(String name)
//读取一个字节,或字节数组长度,返回读入缓存区的总字节数,当读取到文件末尾时,返回-1
read()
read(byte[] b)
read(byte[] b, int off, int len)
两种读取方式
InputStream is = new FileInputStream("day_12/dir/fos.txt");
int i ;
while( (i = is.read()) != -1){
System.out.print((char)i);
}
is.close();
public static void main(String[] args) throws IOException {
InputStream is = new FileInputStream("day_12/dir/fos.txt");
byte[] bytes = new byte[1024];//1KB
int len;// 每次读取到缓冲区的字节数
while((len = is.read(bytes)) != -1){
//String(byte[] bytes, int offset, int length, String charsetName)
//构造一个新的 String通过使用指定的字符集解码指定的字节子阵列。
System.out.print(new String(bytes,0,len,"UTF-8"));
}
is.close();
}
2 字节缓冲流
字节缓冲流有BufferedInputStream和BufferedOutputStream两种,它们会创建一个指定大小的缓冲区;数据在传输过程会先进入缓冲区暂存,然后一次性将缓冲区的数据读出或写入目标文件
//创建字节缓冲流需要提供底层字节流
BufferedOutputStream(OutputStream out, int size)
BufferedInputStream(InputStream in, int size)
注意事项:BufferedOutputStream会先把数据写到缓冲区,缓冲区写满时,才会将缓冲区的内容写出到磁盘
可以通过flush方法刷新缓存流,将缓冲区的内容写入磁盘,它不会释放资源
close方法,在关闭流,释放资源之前,会先刷新缓冲流
为什么缓冲流的构造方法需要的是一个字节流,而不是具体的文件或路径呢?
字节流仅仅提供缓冲区,而真正的读写数据离不开基本字节流对象进行操作
3 字符流
介绍:
- 字符流 = 字节流+字符集
- 由于字节流操作中文不是特别方便,所以出现了字符流
- 汉字在存储的时候无论使用哪种编码格式存储,第一个字节都是负数
- 用字节流赋值文本文件时,文本文件也会有中文,但没问题,因为最终底层操作会自动进行字节拼接成中文。
字符串的编码和解码问题:
//使用编码集将字符串编码为字节序列
byte[] getBytes() //默认是UTF-8
byte[] getBytes(String charsetName)
//使用编码集将字节序列解码为字符串
`String(byte[] bytes, String charsetName)`
字符流的类和方法:
Reader Writer //字符输入流和字符输出流的抽象基类
InputStreamReader OutputStreamWriter//是字符流和字节流的桥梁,会使用指定字符集编码或解码字节流
//构造方法有:
OutputStreamWriter(OutputStream out) //使用默认字符集
OutputStreamWriter(OutputStream out, String charsetName)
InputStreamReader(InputStream in) //使用默认字符集
InputStreamReader(InputStream in, String charsetName)
写入单个字符,字符数组,或字符串
write(char[] cbuf, int off, int len)
write(int c)
write(String str, int off, int len)
write(String str)
write(char[] cbuf)
刷新和关闭,字符流自带缓冲区
close() //关闭流,先刷新
flush() //刷新流
读取单个字符或字符数组,到达文件末尾返回-1
read()
read(char[] cbuf, int offset, int length)
read(char[] cbuf)
//创建实例
Reader r = new InputStreamReader(new FileInputStream("txt"));
Writer w = new OutputStreamWriter(new FileOutputStream("txt"));
字符流操作的便捷类:FileReader FileWriter
Reader r = new FileReader("day");
Writer w = new FileWriter("day");
字符缓冲流
BufferedReader BufferedWriter
String readLine() //读一行文字,到文件末尾返回null(不保存回车符)
void newLine() //写行分隔符
flush() close()
write() //可以写入字符数组,单个字符或字符串
3.标准输入输出流
static PrintStream err //标准”错误输出流
static InputStream in // 标准”输入流。 默认指的键盘
static PrintStream out //标准”输出流。 默认是屏幕
InputStream is = System.in;
InputStreamReader isr = new InputStreamReader(is); //将字节流转换成字符流
4.打印流
- 字节打印流 PrintStream
- 字符打印流 PrintWtriter
- 特点:只负责数据的输出,不能读数据 有一些特有的方法
PrintStream(File file) //使用抽象路径名创建
PrintStream(OutputStream out) //使用已有的字节流创建
PrintStream(String fileName) //使用路径名字符串创建
print()
println()
append()
PrintWriter操作方法类似PrintStream
5.对象的序列化流
对象序列化: 就是将对象保存到磁盘或者在网络中传输对象 为了对象保存的正确性 和传输的安全性,需要对对象进行编码处理,那么把这种处理方式称为对象的序列化
反序列化:将序列化的对象解析为原对象的过程 就称为反序列化
- ObjectOutputStream
- ObjectInputStream
传输对象必须实现java.io.Serializable接口
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day_13/dir/oos.txt"));
//创建学生对象
Student stu1 = new Student("张三",22);
oos.writeObject(stu1);//写出一个对象
oos.close();
// 反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day_13/dir/oos.txt"));
Object obj = ois.readObject();
Student stu = (Student) obj;
System.out.println(stu);
}
6.Porperties
Porperties是Map集合的一个实现类
Porperties可以保存到流中或者从流中加载。 属性列表中的键及其对应的值都是字符串
Porperties和IO流结合的方法
load(InputStream inStream) //从输入字节流读取属性列表(键和元素对)
load(Reader reader) //从输入字符流读取属性列表(键和元素对)
store(OutputStream out, String comments) //将此属性列表(键和元素对)写入此 Properties表中
store(Writer writer, String comments) //将此属性列表(键和元素对)写入此 Properties表中
public class ProPertiesDemo {
public static void main(String[] args) throws IOException {
// myLoad();
myStore();
}
public static void myLoad() throws IOException {
Properties prop = new Properties();
Reader r = new FileReader("day_13/dir/test.properties");
prop.load(r);
r.close();
System.out.println(prop.get("username"));
}
public static void myStore() throws IOException {
Properties prop = new Properties();
prop.setProperty("001","张三");
prop.setProperty("002","李四");
prop.setProperty("003","王五");
prop.setProperty("004","admin");
FileWriter fw = new FileWriter("day_13/dir/test.properties");
prop.store(fw,"这是存储一些对象");
fw.close();
}
}