目录
3.3.1、FileInputStream和FileOutputStream
3.3.2、字节缓冲流 BufferedInputStream 和 BufferedOutputStream
一、对于File类的介绍
内核中对于文件的管理也是通过描述和组织来完成的,描述:通过File来进行操作,组织:通过数据结构来管理若干个File对象。
1、File的初始化
方法 | 解释 |
public File(String pathname) | 创建指定路径文件对象 |
pubilc File(String parent,String child) | 在创建文件指定对象的同时,致命父路径和子路径 |
public static void main(String[] args) {
//第一种方法
File file=new File("d:/test.txt");
//第二种方法
File file1=new File("d:/","test.txt");
//第三种方法
String str="d:/";
String str2="test.txt";
String str3=str+str2;
File file2=new File(str3);
}
2、File类的常用方法
判断操作:
方法 | 解释 |
pubilc boolean exists() | 判断指定路径中文件或者目录是否存在 |
public boolean isDirectory() | 判断文件是否为目录 |
pubilc boolean isFile() | 判断是否为文件 |
public static void main(String[] args) {
File file=new File("d:/test.txt");
//判断是否存在
System.out.println(file.exists());//true
//是否为目录
System.out.println(file.isDirectory());//false
//是否为文件
System.out.println(file.isFile());//true
}
创建和删除操作:
方法 | 解释 |
pubilc boolean delete() | 删除文件 |
public boolean creatNewFile() | 新建一个文件 |
public static void main(String[] args) throws IOException {
File file=new File("d:/test.txt");
//删除
System.out.println(file.delete());//true
//新建
System.out.println(file.createNewFile());//true
}
对于目录的操作:
方法 | 解释 |
pubilc boolean mkdir() | 创建一个空目录 |
public boolean mkdirs() | 创建全部的目录 |
pubilc String getParent() | 获取父路径 |
pubilc File getParentFile() | 获得父路径的File对象 |
File file=new File("d:/test");
System.out.println("创建目录是否成功"+file.mkdir());//创建目录是否成功true
File file=new File("d:/test/1/2/3/4");
System.out.println("创建目录是否成功"+file.mkdirs());//创建目录是否成功true
File file=new File("d:/test/1/2/3/4");
System.out.println("获取父路径"+file.getParent());//获取父路径d:\test\1\2\3
File file=new File("d:/test/1/2/3/4");
System.out.println("获取父路径"+file.getParentFile());//获取父路径d:\test\1\2\3
文件属性:
方法 | 解释 |
public long length() | 取得文件大小(字节) |
public long lastModified() | 最后一次修改日期 |
public File[] listFiles() | 列出一个目录指定的全部组成 |
public static void main(String[] args){
File file=new File("d:/test/1/2/3/4");
System.out.println(file.length());//0
System.out.println(file.lastModified());//1638510767179
}
public static void main(String[] args){
File file=new File("d:/test_dir");
File[] files=file.listFiles();
for(File file1:files){
System.out.println(file1);
}
/*
结果:
* d:\test_dir\1
* d:\test_dir\test.txt
* */
}
3、递归打印文件中的内容
public static void main(String[] args){
File file=new File("d:/test_dir");
listAllFiles(file);
}
private static void listAllFiles(File f){
if(f.isDirectory()){
File[] files=f.listFiles();
for(File file:files){
listAllFiles(file);
}
}else{
System.out.println(f);
}
}
二、相对路径和绝对路径的区别
绝对路径:我们以C:/D:盘开头的路径我们叫做绝对路径。
相对路劲:先指定一个工作目录,然后使用.开头或者是..开头的路径,表示一个文件的具体位置。
例如:
工作目录为D:/test_dir/1/2
相对路径./3.2.txt(表示在2后面连接)
相对路径../2.2/1.1.txt(相当于父目录的父目录)
三、IO流的介绍
3.1、流的概念
在java中所有的数据都是使用流读写,流是一组有序的、有起点和终点的字节集合,是对数据传输的总称。
输入流:就是将各种输入设备读取到内存中去。
输出流:就是将数据写到各种输出设备中去。
3.2、字节流和字符流的介绍
字节流:数据中存储的最小数据的单元是字节。InputStream、OutputStream
字符流:数据中存储的最小数据的单元是字符。Reader、Writer
3.3、字节流
3.3.1、FileInputStream和FileOutputStream
文件的copy:
public static void main(String[] args) throws IOException {
copyFile05("d:/算法.png","d:/qwe.png");
}
public static void copyFile05(String srcPath, String destPath){
try(FileInputStream fileInputStream=new FileInputStream(srcPath);
FileOutputStream fileOutputStream=new FileOutputStream(destPath)){
byte[] bytes=new byte[1024];
int len=-1;
while((len=fileInputStream.read(bytes))!=-1){
fileOutputStream.write(bytes,0,len);
}
}catch (IOException e) {
e.printStackTrace();
}
}
注意:
流对象操作的核心操作:
1、打开文件(操作方法) 2、read:文件中把数据读到文件中
3、write:把数据从内存中写入到文件中 4、关闭文件close()
如果文件不关闭,pcb中的文件描述表是有上线的,文件描述表就会溢出,一旦文件描述表满了之后在打开新的文件就会失败。
3.3.2、字节缓冲流 BufferedInputStream 和 BufferedOutputStream
当我们读取文件时、每读一个文件就要访问一次硬盘。当我们创建一个buffer对象时,会创建一个缓冲区数组,当我们读取一个文件时,先从硬盘读取到缓冲区,直接从缓冲区中读取,这样大大提高了效率。
public static void copyFile(){
//内置了缓冲区
try(BufferedInputStream bufferedInputStream=new BufferedInputStream(new FileInputStream("d:/算法.png"));
BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(new FileOutputStream("d:/qweqwe.png"))){
byte[] bytes=new byte[1024];
int len=-1;
while ((len=bufferedInputStream.read(bytes))!=-1){
System.out.println(len);
bufferedOutputStream.write(bytes,0,len);
}
}catch (IOException e) {
e.printStackTrace();
}
}
对比:
package Test02;
/*
* FileInputStream和BufferedInputStream的比较
* BufferedInputStream中设置了缓冲区
* */
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Test03 {
public static void main(String[] args) {
// 分别不使用缓冲区和使用缓冲区来进行读取一个大文件操作~ 感受时间上的差异.
testNoBuffer();
testBuffer();
}
private static void testBuffer(){
long t1=System.currentTimeMillis();
try(BufferedInputStream bufferedInputStream=new BufferedInputStream(new FileInputStream("d:/算法.png"))){
int len=-1;
while ((len=bufferedInputStream.read())!=-1){
}
}catch (IOException e) {
e.printStackTrace();
}
long t2=System.currentTimeMillis();
System.out.println("创建缓冲区:" +(t2-t1));
}
private static void testNoBuffer(){
long t1=System.currentTimeMillis();
try(FileInputStream fileInputStream=new FileInputStream("d:/算法.png")){
int len=-1;
while ((len=fileInputStream.read())!=-1){
}
}catch (IOException e) {
e.printStackTrace();
}
long t2=System.currentTimeMillis();
System.out.println("没有创建缓冲区:"+(t2-t1));
}
}
3.4、字符流
和字节流的创建差不多
private static void copyFile02(){
try(BufferedReader bufferedReader=new BufferedReader(new FileReader("d:/test.txt"));
BufferedWriter bufferedWriter=new BufferedWriter(new FileWriter("d:/qwe.txt"))){
char[] chars=new char[1024];
int len=-1;
while((len=bufferedReader.read(chars))!=-1){
bufferedWriter.write(chars,0,len);
}
}catch (IOException e) {
e.printStackTrace();
}
}
private static void copyFile01(){
try (FileReader fileReader=new FileReader("d:/test.txt");
FileWriter fileWriter=new FileWriter("d:/qwe.txt")){
char[] chars=new char[1024];
int len=-1;
while((len=fileReader.read(chars))!=-1){
fileWriter.write(chars,0,len);
}
}catch (IOException e) {
e.printStackTrace();
}
}
这里强调一种方法通过readLine方法来书写
private static void copyFile() {
try (BufferedReader bufferedReader = new BufferedReader(new FileReader("d:/test.txt"));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("d:/qwe.txt"))) {
String str ="";
while ((str = bufferedReader.readLine()) != null) {
System.out.println(str);
bufferedWriter.write(str+"\n");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
3.5、字节流和字符流之间的区别
1、字节流操作的是字节,字符流操作的是Unicode码元。
2、字节流在操作的时候本身不会使用缓冲区,字符流在操作的时候使用了缓冲区。
3、所有文件的储存都是字节储存,在磁盘上保留的是字节。
4、字节流不用close方法可以输出,但是字符流不用close方法不会输出任何内容。
四、序列化和反序列化
序列化:将一个结构化数据变成一个二进制的bit流(这个bit流可以保存到文件或者进行网络传输)。
反序列化:将二进制bit流还原成原来的对象。
目的:就是为了让对象可以通过网络传输或者在文件中保存。
4.1、序列化
private static void serializeStudent(Student s) throws IOException {
ObjectOutputStream objectOutputStream=new ObjectOutputStream(new FileOutputStream("d:/test.txt"));
objectOutputStream.writeObject(s);
objectOutputStream.close();
}
字节文件
4.2、反序列化
private static Student deserializeStudent() throws IOException, ClassNotFoundException {
ObjectInputStream objectInputStream=new ObjectInputStream(new FileInputStream("d/test.txt"));
Student student= (Student) objectInputStream.readObject();
objectInputStream.close();
return student;
}
源码:
import java.io.*;
class Student implements Serializable {
String name;
String sex;
int age;
}
public class Test01 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Student student=new Student();
student.name="张三";
student.sex="男";
student.age=18;
serializeStudent(student);
Student s=deserializeStudent();
System.out.println(s.name);
System.out.println(s.sex);
System.out.println(s.age);
}
private static void serializeStudent(Student s) throws IOException {
ObjectOutputStream objectOutputStream=new ObjectOutputStream(new FileOutputStream("d:/test.txt"));
objectOutputStream.writeObject(s);
objectOutputStream.close();
}
private static Student deserializeStudent() throws IOException, ClassNotFoundException {
ObjectInputStream objectInputStream=new ObjectInputStream(new FileInputStream("d:/test.txt"));
Student student= (Student) objectInputStream.readObject();
objectInputStream.close();
return student;
}
}
注意:
创建的类要实现Serializable接口
4.3、序列化的方法(了解)
java对象序列化 | java中内置的方法 |
JSON序列化 | 常用 |
XML | 用的少 |
Protostuff | Google中的 |
Hession | 用的少 |
Dubbo Serialization | 阿里搞的 |
FST | 用的少 |
自定义序列化 | 上面写的 |