File与Io流

1、java.io.File类

1、File类是用来在程序中表示一个文件或目录,这个文件或目录可能是真实存在的,也可能暂时不存在的。
如果它真实存在,即根据创建File类的“路径”能够找到这个文件或目录的,那么系统会将文件或目录的相关信息自动赋值给File类对象。
否则除了路径名(path,name等)之外,所有其他属性都是默认值。

2、File类API
(1)String getName():获取文件或目录名
(2)long length():只能得到文件的大小,返回字节数,如果是目录(文件夹)需要把它下面的所有文件大小都累加起来
(3)long lastModified():获取文件或目录的最后时间,返回毫秒值
(4)boolean isFile():如果文件不存在,就算是File类的对象是表示一个文件,也仍然返回false
只有真实存在的,确实是一个文件的,才会返回true
File f3 = new File("D:\Download\img\美女\chailinyan.jpg");//这个chailinyan.jpg没有
(5)boolean isDirectory():如果目录不存在,就算是File类的对象是表示一个目录,也仍然返回false
只有真实存在的,确实是一个目录的,才会返回true
(6)boolean exists():是否存在
(7)boolean canRead():是否可读
(8)boolean canWrite():是否可写
(9)boolean isHidden():是否隐藏
(10)路径
A:标准的,在所有的操作平台都支持的路径分隔符“/"
B:在创建File时,构造器的()中描述的路径名称为构造路径,它可以是绝对路径也可以是相对路径,
还可以包含“../”非规范路径。
C:String getAbsolutePath():获取绝对路径
D:String getPath():获取构造路径
E:String String getCanonicalPath()throws IOException:获取规范路径,会把构造路径中的../进行解析
(11)boolean createNewFile():只能创建一个文件
(12)boolean mkdir():只能创建一个文件夹,如果父目录不存在,创建不成功,但不报异常
boolean mkdirs():创建文件夹,如果父目录不存在,会一并创建
(13) boolean delete() :只能删除文件或者说空目录
(14)boolean renameTo(File dest) :当前的File对象调用了renameTo方法之后,就会把当前File对象的相关属性赋值给dest的File对象。
(15)String[] list():获取某个目录的下一级的文件或目录的名称
(16)File[] listFiles()获取某个目录的下一级的文件或目录的File对象
(17)File[] listFiles(FileFilter f)获取某个目录的下一级的文件或目录的File对象,可以过滤File对象,看是否满足xx条件

2、IO流

(1)四个抽象父类

InputStream:字节输入流
OutputStream:字节输出流
Reader:字符输入流
Writer:字符输出流

(2)四个抽象父类的方法

InputStream:

int read():读取一个字节,返回读取的字节值,如果到达流末尾,再读就返回-1。
int read(byte[] data):一次最多读取data.length个字节,返回实际本次读取的字节数量。如果到达流末尾,再读就返回-1。
读取的数据就临时的存储到data中,从data[0]开始存储,
如果data数组循环使用的话,每一次读取都会从data[0]开始覆盖,
如果本次读取的字节数量没有凑够data.length个,本次一共读取count个字节,
那么要注意剩下的data[count, data.length-1]元素可能默认值0,也可能是上次读取的内容。
int read(byte[] data, int off, int len):一次最多读取len个字节,返回实际本次读取的字节数量。如果到达流末尾,再读就返回-1。
读取的数据就临时的存储到data中,从data[off]开始存储,
void close():关闭IO流

Reader:

int read():读取一个字符,返回读取的字符的Unicode值,如果到达流末尾,再读就返回-1。
int read(char[] data):一次最多读取data.length个字符,返回实际本次读取的字符数量。如果到达流末尾,再读就返回-1。
读取的数据就临时的存储到data中,从data[0]开始存储,
如果data数组循环使用的话,每一次读取都会从data[0]开始覆盖,
如果本次读取的字符数量没有凑够data.length个,本次一共读取count个字节,
那么要注意剩下的data[count, data.length-1]元素可能默认值0,也可能是上次读取的内容。
int read(char[] data, int off, int len):一次最多读取len个字符,返回实际本次读取的字符数量。如果到达流末尾,再读就返回-1。
读取的数据就临时的存储到data中,从data[off]开始存储,
void close():关闭IO流

OutputStream:

void write(int d):输出一个字节
void write(byte[] data):输出整个字节数组
void write(byte[] data,int off, int len):输出字节数组data的len个字节,从data[off]开始
void close()

Writer:

void write(int d):输出一个字符
void write(char[] data):输出整个字符数组
void write(char[] data,int off, int len):输出字节数组data的len个字符,从data[off]开始
void write(String str):输出整个字符串
void write(String str,int off, int len):输出字符串一部分,len个字符,从str[off]开始
void close():关闭IO流

void flush():刷新流中的数据

3、文件IO流

FileInputStream:文件字节输入流
FileOutputStream:文件字节输出流
FileReader:文件字符输入流,而且要求文件的编码和程序编码一致。
FileWriter:文件字符输出流,而且要求文件的编码和程序编码一致。

FileInputStream和FileOutputStream适用于操作任意类型的文件。
FileReader和FileWriter只适用于操作纯文本文件,文件中不能有图片,视频等各种多媒体素材,即文件中只有各种字符。

FileInputStream和FileReader只能用来读取文件的内容。
FileOutputStream和FileWriter只能用来输出数据到文件。

什么是纯文本文件?
文件中只能出现字符。
通常纯文本文件的类型:
    .txt,.java,.html,.js,.css,.sql......
不是纯文本的文件:
    word,excel,ppt

4、缓冲IO流

BufferedInputStream:给InputStream系列的IO加缓冲功能
BufferedOutputStream:给OutputStream系列的IO加缓冲功能
BufferedReader:给Reader系列的IO加缓冲功能
或者是需要按行读取 String readLine()方法
BufferedWriter:给Write系列的IO加缓冲功能

​ 或者是需要按行输出 void newLine()

5、转换流

InputStreamReader:
(1)需要把字节输入流的类型转为字符输入流的类型。包装的是字节流,本身是字符流。
(2)当读纯文本文件的数据时,遇到了文件的编码和程序的编码不一致,
需要它配合FileInputStream完成。
OutputStreamWriter:
(1)需要把字节输出流的类型转为字符输出流的类型。包装的是字节流,本身是字符流。
(2)当输出纯文本数据时,遇到了文件的编码和程序的编码不一致,
需要它配合FileOutputStream完成。

6、读写Java各种数据类型的IO流

DataOutputStream:要输出的数据除了字符串之外还有其他Java的基本数据类型的数据或者字节数组
DataInputStream:用于读取用DataOutputStream输出的数据

ObjectOutputStream:支持输出Java的各种数据,包括基本数据类型和对象。要输出Java对象时,配合Serializable接口。
ObjectInputStream:支持读取Java的各种数据类型的数据,包括基本数据和对象。要读取Java对象时,读取ObjectOutputStream输出的数据时。

序列化:

  • 把Java的对象转为字节数据进行输出。
  • 需要Java对象类型实现java.io.Serializable接口。如果Java对象中某个属性也是引用数据类型,那么这个属性想要参与序列化也要求该类型实现Serializable接口。
  • 序列化过程中某些 成员变量的值是不能序列化:static和transient修饰的成员变量值是不序列化
  • 为了在类做了修改之后,原来的数据仍然可以被反序列化,通常要求在实现Serializable接口时,加一个序列化版本ID。
private static final long serialVersionUID = -6849794470754667710L;

反序列化:

  • 把字节数据转换为一个Java对象。
  • 反序列化时,要求Java对象对应的类必须存在,否则会报ClassNotFoundException。

7、IO流的选择

/*
IO流的分类:
(1)根据数据的流向分:
输入流:InputStream、Reader系列,
        只能从输入流中读取数据,调用read系列的方法
        read() readInt()  readUTF()  readObject()....
输出流:OutputStream、Writer系列、包括PrintStream、PrintWriter
        只能往输出流中写数据,调用write,print系列的方法
        write(...)  writeInt(...) writeUTF(...) print(..) println(...)

(2)根据操作数据的基本单位分:
字节流:以字节为单位,所有的操作都要转为字节、字节数组
    InputStream和OutputStream系列
    FileOutputStream、BufferedOutputStream、DataOutputStream、ObjectOutputStream
    FileInputStream、BufferedInputStream、DataInputStream、ObjectInputStream

PrintStream:从流的类型来说是字节流,但是它里面的print,println方法支持各种数据类型。
字符流:以字符为单位,只支持纯文本数据的处理
    Reader和Writer
    FileReader、BufferedReader、InputStreamReader、Scanner
    FileWriter、BufferedWriter、OutputStreamWriter、PrintWriter

(3)根据流的角色分:
节点流:FileInputStream、FileOutputStream、FileReader、FileWriter
处理流:BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter   装饰流,需要包装别人才能
        DataInputStream、DataOutputStream
        ObjectInputStream、ObjectOutputStream
        PrintStream、PrintWriter

IO流的整个体系设计是采用了“装饰者设计模式”。

什么是装饰者设计模式?
(1)被装饰者
A:节点流只能作为被装饰者
节点流(例如节点流:FileInputStream、FileOutputStream、FileReader、FileWriter),
节点流(例如节点流:ByteArrayInputStream、ByteArrayOutputStream),只能作为被装饰者
节点流(例如节点流:CharArrayReader、CharArrayWriter),只能作为被装饰者
它们的构造器指定的是数据的来源或者数据的目的地,例如:文件、数组。

B:装饰者同时也可以作为被装饰者


(2)装饰者
处理流,都是装饰者,必须依赖于其他的IO流
例如:BufferedInputStream bis = new BufferedInputStream(其他InputStream流的对象);

装饰?
比喻:穿衣服加装饰
加个丝巾、领带、胸针等
装饰品属于在原来被装饰的衣物或其他装饰品基础上再加新的功能(更好看、更暖和)。


装饰者设计模式是替换继承的方式。
如果不用装饰者模式,那么子类的数量是爆炸式的增长。

继承的方式:
文件流是最基础的,
需要一个新的类型:在文件流的基础上仅支持缓冲  FileBufferedXxx
需要一个新的类型:在文件流的基础上既支持缓冲又支持转码  FileBufferedTransferXxx
需要一个新的类型:在文件流的基础上只支持转码  FileTransferXxx
。。。。


 */


8、try...catch的新语法(JDK1.7之后)

try(需要自动关闭的资源类对象的声明和创建){
    可能发生异常的业务逻辑代码
}catch(异常类型 e){
    异常处理代码
}【finally{
    其他必须执行的代码。
}】    

注意:

(1)写在 try()中的资源类对象的类型必须实现AutoCloseable接口

(2)写在 try()中的资源类对象自动加final

(3)资源类类的类型有哪些,通常有IO流类,后面有数据库连接类,网络连接类。这些通常操作完都需要close,,它们实现AutoCloseable接口之后,就可以自动关闭,不用手动写close方法了。当执行完try...catch部分的代码之后,就会自动关闭。

巩固题

第1题

(1)使用绝对路径,在D盘下创建一个testIO文件夹,然后在testIO文件夹中创建一个1.txt文件

(2)使用相对路径,在当前模块下创建一个testIO文件夹,然后在testIO文件夹中创建一个1.txt文件

package com.atguigu.homework1;

import java.io.File;
import java.io.IOException;

import org.junit.Test;

public class Homework1 {
    @Test
    public void test01() throws IOException {
        File dir = new File("d:/testIO");
        dir.mkdir();

        File file = new File("d:/testIO/1.txt");
        file.createNewFile();
    }

    @Test
    public void test02() throws IOException {
        File dir = new File("testIO");
        dir.mkdir();

        File file = new File("testIO/1.txt");
        file.createNewFile();
    }
}

第2题

(1)检查D盘的testIO文件夹下是否存在文件a.txt,如果不存在则创建该文件。

(2)获取D盘的testIO文件夹下的a.txt文件的文件名,文件大小,文件的绝对路径和父路径等信息,并将信息输出在控制台

(3)判断File file = new File("d:\testIO");是否文件,是文件则输出:xxx是一个文件,是否文件夹,是文件夹则输出:xxx是一个文件夹

(4)删除D盘的testIO文件夹下的a.txt文件

(5)删除当前模块下的testIO文件夹下的1.txt文件,然后删除testIO文件夹

package com.atguigu.homework2;

import org.junit.Test;

import java.io.File;
import java.io.IOException;

public class Homework2 {
    @Test
    public void test05(){
        File file = new File("d:/testIO/1.txt");
        file.delete();

        File dir = new File("d:/testIO");
        dir.delete();
    }

    @Test
    public void test04(){
        File file = new File("d:/testIO/a.txt");
        file.delete();
    }
    @Test
    public void test03(){
        File file = new File("d:/testIO");
        if(file.isFile()){
            System.out.println(file+"是一个文件。");
        }else if(file.isDirectory()){
            System.out.println(file + "是一个文件夹");
        }
    }
    @Test
    public void test02(){
        File file = new File("d:/testIO/a.txt");
        System.out.println("文件名:" + file.getName());
        System.out.println("文件大小:" + file.length());
        System.out.println("文件的绝对路径:" + file.getAbsolutePath());
        System.out.println("文件的父目录:" + file.getParent());
    }
    @Test
    public void test01(){
        File file = new File("d:/testIO/a.txt");
        try {
            if(!file.exists()){
                file.createNewFile();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

第3题

把老师的pdf笔记文档《第14章 IO流.pdf》,复制到当前模块的testIO文件夹下。要求使用缓冲流和文件流一起实现

package com.atguigu.homework3;

import java.io.*;

public class Homework3 {
    public static void main(String[] args) {
        try(
                BufferedInputStream bis = new BufferedInputStream(
                        new FileInputStream("D:/atguigu/第14章 IO流.pdf"));
                BufferedOutputStream bos = new BufferedOutputStream(
                        new FileOutputStream("testIO/第14章 IO流.pdf"));
        ){
            byte[] data = new byte[1024];
            int len;
            while((len = bis.read(data))!=-1){
                bos.write(data, 0, len);
            }
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

第4题

把今天的作业文件夹下的《我想对你说.txt》字符编码为GBK,复制到当前项目的testIO文件夹下的《柴老师的话.txt》字符编码为UTF-8。

package com.atguigu.test04;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class Test04 {
	public static void main(String[] args) {
		try(
			FileInputStream fis = new FileInputStream("d:/atguigu/尚硅谷_19_IO流_homework/我想对你说.txt");
			BufferedInputStream bis = new BufferedInputStream(fis);
			InputStreamReader isr = new InputStreamReader(bis,"GBK");
				
			FileOutputStream fos = new FileOutputStream("testIO/柴老师的话.txt");
			BufferedOutputStream bos = new BufferedOutputStream(fos);
			OutputStreamWriter osw = new OutputStreamWriter(bos, "UTF-8");	
		){
			char[] data = new char[1024];
			int len;
			while((len = isr.read(data))!=-1){
				osw.write(data, 0, len);
			}
		}catch(IOException e){
			e.printStackTrace();
		}
	}
}

第5题

把如下这些数据存放到一个data.dat文件中,并且再次读取显示

int a = 10;
char c = 'a';
double d = 2.5;
boolean b = true;
String str = "尚硅谷";
package com.atguigu.homework5;

import org.junit.Test;

import java.io.*;

public class Homework5 {
    @Test
    public void test02() throws IOException {
        ObjectInputStream dis = new ObjectInputStream(new FileInputStream("data.dat"));
        System.out.println(dis.readInt());
        System.out.println(dis.readChar());
        System.out.println(dis.readDouble());
        System.out.println(dis.readBoolean());
        System.out.println(dis.readUTF());
        dis.close();
    }

    @Test
    public void test01() throws IOException {
        int a = 10;
        char c = 'a';
        double d = 2.5;
        boolean b = true;
        String str = "尚硅谷";

        ObjectOutputStream dos = new ObjectOutputStream(new FileOutputStream("data.dat"));
        dos.writeInt(a);
        dos.writeChar(c);
        dos.writeDouble(d);
        dos.writeBoolean(b);
        dos.writeUTF(str);
        dos.close();
    }
}

第6题

(1)声明一个Message类,包含:发送者、接收者、消息内容、发送时间等属性,属性私有化,提供有参构造,get/set,重写toString

(2)创建一个Message对象,并写到message.dat文件中,并再次读取显示

package com.atguigu.homework6;

import java.io.Serializable;

public class Message implements Serializable {
    private static final long serialVersionUID = 1L;
    private String fromUser;
    private String toUser;
    private String content;
    private long sendTime;

    public Message(String fromUser, String toUser, String content, long sendTime) {
        super();
        this.fromUser = fromUser;
        this.toUser = toUser;
        this.content = content;
        this.sendTime = sendTime;
    }

    public Message() {
        super();
    }

    public String getFromUser() {
        return fromUser;
    }

    public void setFromUser(String fromUser) {
        this.fromUser = fromUser;
    }

    public String getToUser() {
        return toUser;
    }

    public void setToUser(String toUser) {
        this.toUser = toUser;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public long getSendTime() {
        return sendTime;
    }

    public void setSendTime(long sendTime) {
        this.sendTime = sendTime;
    }

    @Override
    public String toString() {
        return "Message [fromUser=" + fromUser + ", toUser=" + toUser + ", content=" + content + ", sendTime="
                + sendTime + "]";
    }
}
package com.atguigu.homework6;

import org.junit.Test;

import java.io.*;

public class Homework6 {
    @Test
    public void test02() throws FileNotFoundException, IOException, ClassNotFoundException{
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("message.dat"));
        Object msg = ois.readObject();
        System.out.println(msg);
        ois.close();
    }
    @Test
    public void test01() throws FileNotFoundException, IOException{
        Message msg = new Message("柴老师", "佟老师", "加工资", System.currentTimeMillis());

        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("message.dat"));
        oos.writeObject(msg);
        oos.close();
    }
}

第7题

(1)用从键盘输入三句话,用PrintStream打印到一个words.txt文件中

(2)再用Scanner一行一行读取显示

package com.atguigu.homework7;

import org.junit.Test;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.Scanner;

public class Homework7 {
    @Test
    public void test02() throws FileNotFoundException {
        Scanner input = new Scanner(new File("words.txt"));
        while(input.hasNextLine()){
            System.out.println(input.nextLine());
        }
        input.close();
    }


    @Test
    public void test01() throws FileNotFoundException{
        Scanner input = new Scanner(System.in);
        PrintStream ps = new PrintStream("words.txt");
        for (int i = 0; i < 3; i++) {
            System.out.println("请输入第" + (i+1) + "句要对柴老师说的话:");
            String content = input.nextLine();
            ps.println(content);
        }
        input.close();
        ps.close();
    }
}

拔高题

第8题

复制“今日资料的整个文件夹”到当前项目的testIO文件夹中

package com.atguigu.homework8;

import org.junit.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Homework8 {
    @Test
    public void test01() throws IOException{
        File src = new File("d:/尚硅谷-JavaSE-第20天上课资料");
        File dest = new File("testIO");
        copyDir(src, dest);
    }

    public void copyDir(File src, File dest) throws IOException{
        if(dest.isFile()){
            throw new RuntimeException(dest +"不是文件夹");
        }
        if(src.isFile()){
            File destFile = new File(dest.getPath()+"/" + src.getName());
            copyFile(src, destFile);
        }else if(src.isDirectory()){
            File destFile = new File(dest.getPath()+"/" + src.getName());
            destFile.mkdir();

            File[] listFiles = src.listFiles();
            for (File sub : listFiles) {
                copyDir(sub,destFile);
            }
        }
    }

    public void copyFile(File srcFile, File destFile) throws IOException {
        FileInputStream fis = new FileInputStream(srcFile);
        FileOutputStream fos = new FileOutputStream(destFile);
        byte[] data = new byte[1024];
        int len;
        while((len = fis.read(data)) !=-1){
            fos.write(data, 0, len);
        }
        fis.close();
        fos.close();
    }
}

第9题

先备份今日上课资料,然后剪切“今日资料的整个文件夹”到当前项目的homework文件夹中

package com.atguigu.homework9;

import org.junit.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Homework9 {
    @Test
    public void test01() throws IOException{
        File src = new File("d:/尚硅谷-JavaSE-第20天上课资料_备份");
        File dest = new File("homework");
        cutDir(src, dest);
    }

    public void cutDir(File src, File dest) throws IOException{
        if(dest.isFile()){
            throw new RuntimeException(dest +"不是文件夹");
        }
        if(src.isFile()){
            File destFile = new File(dest.getPath()+"/" + src.getName());
            copyFile(src, destFile);
        }else if(src.isDirectory()){
            File destFile = new File(dest.getPath()+"/" + src.getName());
            destFile.mkdir();

            File[] listFiles = src.listFiles();
            for (File sub : listFiles) {
                cutDir(sub,destFile);
            }
        }
        src.delete();
    }

    public void copyFile(File srcFile, File destFile) throws IOException {
        FileInputStream fis = new FileInputStream(srcFile);
        FileOutputStream fos = new FileOutputStream(destFile);
        byte[] data = new byte[1024];
        int len;
        while((len = fis.read(data)) !=-1){
            fos.write(data, 0, len);
        }
        fis.close();
        fos.close();
    }
}
posted @ 2022-10-13 11:08  傻孩子不吃辣  阅读(84)  评论(0)    收藏  举报