Java javase14

一、File类
(一) 概述
1.java.io.File类是文件和目录路径名的抽象表示,主要用于文件和目录的创建。
2.我么可以使用File类的方法

  • 创建、删除、获取一个文件/文件夹

  • 判断文件是否存在

  • 对文件进行遍历

  • 获取文件的大小
    File类是一个与系统无关的类,任何操作系统都可以使用这个类中的方法。
    3、重点

  • file:文件

  • directory:文件夹/目录

  • path:路径
    (二)File类的静态成员变量

  • static String pathSeparator与系统有关的路径分隔符,为了方便,它被表示为一个字符串。

  • static char pathSeparatorChar与系统有关的路径分隔符。

  • static String separator与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。

  • static char separatorChar与系统有关的默认名称分隔符。
    (三)绝对路径和相对路径
    1、绝对路径:是一个完整的路径,以盘符开始的路径。
    2、相对路径:是一个简化的路径,相对指的是相对于当前项目的根目录。
    注意:

  • 路径不区分大小写

  • 路径中文件名称分隔符windows中使用两个反斜杠
    (四)File的构造方法

  • File(File parent, String child)根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。
    好处
    父路径是File类型,可以使用File的方法对路径进行一些操作,再使用路径创建对象。

  • File(String pathname)通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。
    参数
    1、参数为字符串的路径名称
    2、路径可以是以文件结尾也可以是以文件夹结尾
    3、路径可也是相对路径也可以是绝对路径
    4、路径可也是存在也可以是不存在
    5、创建File对象,只要把字符串路径封装为File对象,不考虑真假路径的情况

  • File(String parent, String child)根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。
    好处
    父路径和子路径可以单独书写,使用起来非常灵活,父路径子路径都可以变化。

  • File(URI uri)通过将给定的 file: URI 转换为一个抽象路径名来创建一个新的 File 实例
    (五)获取功能的方法

  • public String getAbsolutePath():返回File的绝对路径名字符串
    无论路径是绝对的还是相对的,返回的都是绝对路径。

  • public String getPath():将此File转换为路径名字符串

  • public String getName():返回由此File表示的文件或目录的名称。

  • public long length():返回由此File表示的文件的长度。

  • 注意

  • 获取的是构造方法指定文件的大小,以字节为单位。

  • 文件夹没有大小概念不能获取文件夹大小。

  • 如果构造方法给出的路径不存在,那么该方法返回0.

public class F1 {
    public static void main(String[] args) {
        show1();
        show2();
        show3();
        show4();
    }

    private static void show4() {
            File f = new File("C:\\Users\\阚开豪\\Desktop\\javaFile\\a.txt");
            long length = f.length();
            System.out.println(length);
    }
    private static void show3() {
        File f1 = new File("C:\\Users\\阚开豪\\Desktop\\javaFile\\a.txt");
        String ab1 =f1.getPath();
        System.out.println(ab1);

        File f2 = new File("C:\\Users\\阚开豪\\Desktop\\javaFile\\a.txt");
        String ab2 =f1.getName();
        System.out.println(ab2);
    }
    private static void show2() {
        File f1 = new File("C:\\Users\\阚开豪\\Desktop\\javaFile\\a.txt");
        String ab1 =f1.getPath();
        System.out.println(ab1);

        File f2 =new File("a.txt");
        String ab2 = f2.getPath();
        System.out.println(ab2);
        //返回的为绝对路径

    }

    private static void show1() {
        File f1 = new File("C:\\Users\\阚开豪\\Desktop\\javaFile\\a.txt");
        String ab1 = f1.getAbsolutePath();
        System.out.println(ab1);

        File f2 =new File("a.txt");
        String ab2 = f2.getAbsolutePath();
        System.out.println(ab2);
    }
}

输出为:
C:\Users\阚开豪\Desktop\javaFile\a.txt
C:\Users\阚开豪\IdeaProjects\java练习\a.txt
C:\Users\阚开豪\Desktop\javaFile\a.txt
a.txt
C:\Users\阚开豪\Desktop\javaFile\a.txt
a.txt
5

(六)File类判断功能的方法

  • public boolean exists( ):此File表示的文件或目录是否实际存在。
  • public boolean isDirectory( ):此File表示的是否为目录。
  • public boolean isFile( ):此File表示的是否为文件。
  • 测试代码:
import java.io.File;

public class F2 {
    public static void main(String[] args) {
        File f1 = new File("C:\\Users\\阚开豪\\Desktop\\javaFile\\a.txt");
        File f2 =new File("C:\\Users\\阚开豪\\Desktop\\javaFile");
        //判断是否存在
        System.out.println("存在?"+f1.exists());
        System.out.println("存在?"+f2.exists());
        //判断是文件还是目录
        System.out.println("是文件?"+f2.isFile());
        System.out.println("是目录?"+f2.isDirectory());

    }
}

输出为:
存在?true
存在?true
是文件?false
是目录?true

(七)创建删除功能的方法

  • public boolean creatNewFile( ):当且仅当具有该名称的文件尚不存在的时候,创建一个新的文件。

  • public boolean delete ( ):删除由此File表示的文件或者目录。

  • pubic boolean mkdir( ):创建由此File表示的目录

  • public boolean mikdirs( ):创建由此File表示的目录,包括任何必需但不存在的目录。

  • 测试代码

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

public class F3 {
    public static void main(String[] args) {
        //文件的创建
        File f= new File("a.txt");
        System.out.println("是否存在"+f.exists());
        try {
            System.out.println("是否创建"+f.createNewFile());
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("是否存在"+f.exists());

        //目录的创建
        File f1=new File("test");
        System.out.println("是否存在"+f1.exists());
        System.out.println("是否创建"+f1.mkdir());
        System.out.println("是否存在"+f1.exists());
        //创建多级目录
        File f2 =new File("test\\t1");
        System.out.println("是否存在"+f1.exists());
        System.out.println("是否创建"+f1.mkdirs());
        System.out.println("是否存在"+f1.exists());

        //删除目录
        f2.delete();
        System.out.println("是否存在"+f2.exists());
    }
}

输出为
是否存在true
是否创建false
是否存在true
是否存在true
是否创建false
是否存在true
是否存在true
是否创建false
是否存在true
是否存在false

(八)目录的遍历

  • public String[ ] list( ):返回一个Strings数组,表示该File目录中的所有子文件或目录。
  • public File[ ] listFiles( ):返回一个File数组,表示该File目录中的所有的子文件或目录。
  • 测试代码:
import java.io.File;

public class F4 {
    public static void main(String[] args) {
        File dir = new File("C:\\Users\\阚开豪\\Desktop\\javaFile");

        //获取当前目录下的文件以及文件夹名称
        String [] names = dir.list();
        for(String name:names){
            System.out.println(name);
        }
        //获取当前目录下的文件以及文件夹对象,只要拿到了文件都西昂,那么就可以获取更多信息
        File [] files = dir.listFiles();
        for(File file:files){
            System.out.println(file);
        }
    }
}

输出为:
a.txt
b.txt
c.txt
C:\Users\阚开豪\Desktop\javaFile\a.txt
C:\Users\阚开豪\Desktop\javaFile\b.txt
C:\Users\阚开豪\Desktop\javaFile\c.txt

二、递归
(一)概述

  1. 递归:指在当前方法内调用自己的这种现象
  2. 递归的分类
    • 递归分为两种,直接递归和间接递归
    • 直接递归成为方法本身调用自己
    • 间接递归可以A方法调用B方法,B方法调用C方法,C方法调用A方法
  3. 注意事项
    • 递归一定要有条件限定,保证递归停止否则会发生栈内存溢出
    • 递归中虽然有限定条件但是递归次数不能太多,否则会发生栈内存溢出。
    • 构造方法,禁止递归
      (二)递归打印多级目录
      分析:多级目录的打印实际就是目录的嵌套。遍历之前无从知道有多少级目录,所以需要使用递归实现。
      代码实现
import java.io.File;

public class F5 {
    public static void main(String[] args) {
        File file =new File("C:\\Users\\阚开豪\\Desktop\\javaFile");
        getALLfile(file);
    }

    private static void getALLfile(File file) {
        File [] files =file.listFiles();
        for(File f:files){
            if(f.isDirectory())
                getALLfile(f);
            else
                System.out.println(f);
        }
    }
}

输出为:
C:\Users\阚开豪\Desktop\javaFile\a\a.txt
C:\Users\阚开豪\Desktop\javaFile\a\b.txt
C:\Users\阚开豪\Desktop\javaFile\a\c.txt
C:\Users\阚开豪\Desktop\javaFile\b\d.txt
C:\Users\阚开豪\Desktop\javaFile\e.txt
C:\Users\阚开豪\Desktop\javaFile\f.doc

(三)FileFiter过滤器的原理和使用
FileFilter过滤器的使用和原理
在File类中有两个和ListFiles重载的方法,方法的参数传递的就是过滤器。

  1. FIle[ ] Listfiles( FileFilter filter )
    java.io.FileFilter接口:用于抽象路径名(File)过滤器。
  • 作用:用来过滤文件(File对象)
  • 抽象方法:用来过滤文件(File)
  • boolean accept(File pathname):测试指定抽象路径名是否应该包含在某个路径名的列表中。
    参数:
    File pathname:使用ListFiles方法遍历目录,得到每一个文件对象。
  1. File [ ] ListFiles (FilenameFilter filter)
    java.io.FilenameFilter接口:实现此接口的类实例可以用于过滤文件器文件名
  • 作用:用于过滤文件名称
  • 抽象方法:用来过滤文件的方法
  • boolean accept( File dir, String name ):测试指定文件是否应该包含在某一文件列表当中。
    参数:
    File dir:构造方法中传递的被遍历的目录
    String name:使用ListFiles方法遍历目录,获取的每一个文件/文件夹名称。
    注意:两个过滤器接口没有实现类,需要我们自己写实现类,重写过滤的方法accept,在方法中定义过滤的规则。
import java.io.File;
import java.io.FileFilter;

public class Fmpl implements FileFilter {

    @Override
    public boolean accept(File pathname) {
    if(pathname.isDirectory()){
            return true;
        }
        return pathname.getName().toLowerCase().endsWith(".java");
    }
}

import java.io.File;

public class F {
    public static void main(String[] args) {
                File file =new File("C:\\Users\\阚开豪\\Desktop\\javaFile");
                getALLfile(file);
            }

            private static void getALLfile(File file) {
                File [] files =file.listFiles(new Fmpl());
                for(File f:files){
                    if(f.isDirectory())
                        getALLfile(f);
                    else
                        System.out.println(f);
                }
            }
        }

输出为:C:\Users\阚开豪\Desktop\javaFile\g.java

Lambda优化

import java.io.File;

public class F {
    public static void main(String[] args) {
                File file =new File("C:\\Users\\阚开豪\\Desktop\\javaFile");
                getALLfile(file);
            }

            private static void getALLfile(File file) {
               File[] files = file.listFiles(pathname ->
                       pathname.isDirectory()||pathname.getName().
                               toLowerCase().endsWith(".java"));
                for(File f:files){
                    if(f.isDirectory())
                        getALLfile(f);
                    else
                        System.out.println(f);
                }
            }
        }

三、IO概述
(一)IO简介和分类

  • 我们把数据的传输,可以看作是数据流动,按照流动的方向以内存为基准分为输入和输出,即流向内存的是输入流,流出内存的是输出流。
  • Java中I/O操作主要指使用java.io包下内容进行输入输出操作。输入也叫做读取数据,输出也叫写出数据。
    分类
  • 输入流:把数据从其他设备上读取到内存的流
  • 输出流:把数据从内存中写出到其他设备的流。
  • 格局数据类型分为:字节流字符流
    1个字符=2个字节;1个字节=8个二进制位。
输入流输出流
字节输入流 InputStrean字节输出流 OutputStream
字符输入流 Reader字符输出流 Writer

注意:一切皆为字节。

(二)字节输出流【OutputStream】

java.io.OutpuStream:此抽象类是表示输出字节流的所有类的超类。
成员方法:

  • pubilc void coles( ):关闭此输出流并释放与此流相关联的任何系统资源
  • public void flush( ):刷新此输出流并强制任何缓冲的输出字节被写出。
  • public void write( byte[ ] b ):将b.length字节从指定的字节数组写入此输出流。
  • public void write( byte[ ] b, int off, int len):从指定的字节数组中写入len字节,从偏移量off开始输出到此输出流。
  • public abstract void write(int b):将指定的字节输出流。

FileOutputStream

  • java.io.FileOutputStream:文件字节输出流
  • 作用:把内存中的数据写入到硬盘的文件中。
    构造方法
  • FileOutputStream(String name):创建一个 向具有指定名称的文件中写入数据的输出文件流。
  • FileOutputStream(File file):创建一个向指定File对象表示的文件中写入数据的文件输出流。
  • 参数:写入数据的目的
    String name:目的是一个文件的路径。
    File file:目的是一个文件
  • 构造方法的作用
    1. 创建一个FileOutputStream对象
    2. 根据构造方法中传递的文件/文件路径,创建一个空的文件。
    3. 会把FileOutputStream对象指向创建好的文件。

写入数据的原理
java程序 -> JVM -> OS(操作系统)-> OS调用写数据的方法 -> 把数据写入到文件中

字节输出流的使用步骤

1.创建一个FileOutputStream对象,构造方法中传递写入数据的目的地
2. 调用write方法,把数据写到文件中
3. 释放资源
测试代码

import java.io.FileOutputStream;
import java.io.IOException;

public class FileOut1 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos =new FileOutputStream
                ("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
        fos.write(98);
        fos.close();
    }
}

注意:任意的文本编辑器打开文件时,都会查询编码表把字节转换为字符表示。

字节输出流写多个字节的方法

  • public void write( byte[ ] b ):将b.length字节从指定的字节数组写入此输出流。
    注意
  1. 如果写的第一个字节是正数(0-127),查询ASCII表
  2. 如果第一个字节是负数,那第一个字节会和第二个字节两个字节组成一个中文表示,查询GBK。`
public class FileOut2 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos1 = new FileOutputStream
                ("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
        //byte [] b={65,66,67,68};  ABCD
        byte [] b={-65,-9,90,80};//亏ZP
        fos1.write(b);
        fos1.close();
    }
}
  • public void write( byte[ ] b, int off, int len):从指定的字节数组中写入len字节,从偏移量off开始输出到此输出流。
  • int off:数组开始的索引
  • int len:几个字节
import java.io.FileOutputStream;
import java.io.IOException;

public class FileOut2 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream
                ("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
        byte [] b={65,66,67,68};//ABCD
        fos.write(b,2,2);//CD

        /*写入字符的方法:使用String类中的方法把字符串转化为字符数组
            byte[ ] getBytes()
         */
        byte [] b1 = "你好Java!".getBytes();
        fos.write(b1);//CD你好Java!
        fos.close();
    }
}

(三)字节输入流【InputStream】

  • java.io.InputStream:字节输入流。此抽象类是表示字节输入流的所有类的超类。
    定义所有子类共性的方法
  • int read():从输入流中读取数据的下一个字节。
  • int read(byte [ ]):从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中。
  • void close( ):关闭此输入流释放与该流关联的所有系统资源。
    构造方法
  • FileInputStream(String name)
  • `FileInputStream(File file)
  • 参数
    `String name:文件的路径
    File file:文件
    作用
    1. 会创建一个FIleInputStream对象
    2. 会把该对象指定构造方法中要读取的文件
    字节输入流读取一个字节
    字节输入流的使用步骤(重点):
    1. 创建FileInputStream对象,构造方法中绑定要读取的数据源
    2. 使用该对象中的方法read,读取文件
    3. 释放资源
import java.io.FileInputStream;
import java.io.IOException;

public class FileIn1 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
        while (true){
            int len = fis.read();
            if(len==-1)
                break;
            System.out.println(len);
        }
        fis.close();
    }
}

字节输入流读取多个字节

  • int read (byte [ ] b ):从输入流读取一定数量的字节,并将其存储到缓冲区数组b中。
  1. byte[ ]作用:起到缓冲作用,存储每次读取到的多个字节,数组的长度一般定义为1024(1kb)或者1024整数倍。
  2. 返回值int是每次读取的有效字节个数
  3. String类的构造方法
  • String ( byte [ ] bytes):把字节数组转换为字符串
  • String ( byte[ ] bytes, int offset, int ength):把字节数组的一部分转换为字符串 offset:数组的开始索引 length:转换的字节个数
import java.io.FileInputStream;
import java.io.IOException;

public class FileIn2 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
        byte[] bytes = new byte[1024];
        int len =0;
        while(fis.read(bytes)!=-1){
            System.out.println(new String(bytes));//CD你好Java!                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
        }
    }
}

字节流练习:文件复制
文件复制的步骤

  1. 创建一个字节输入流对象,构造方法中绑定要输入的数据源
  2. 创建一个字节输出流对象,构造方法中绑定要写入的目的地
  3. 使用字节输入流对象中的方法read读取文件
  4. 使用字节输出流的方法write,把读取到的字节写入目的地文件中
  5. 释放资源
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Filea {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
        FileOutputStream fos =new FileOutputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\b\\d.txt");

        byte [] bytes =new byte[1024];
        int len=0;
        while((len=fis.read(bytes))!=-1){
            fos.write(bytes,0,len);
        }
        fis.close();
        fos.close();
    }
}

使用字节流读取中文文件
1个中文
GBK:占用两个字节
UTF-8:占用三个字节
(四)字符输入流【Reader】

  • java.io.Reader:字符输入流,是字符输入流最顶层父类,定义了一些共性的成员方法,是一个抽象类。
    共性的成员方法
  • int read( ):读取单个字符并返回
  • int read( char [ ] cbuf ):一次读取多个字符,将字符读入数组。
  • void close( ):关闭该流并释放与之关联的所有资源。
  • java.io.FileReader extends InputStremReader extends Reader
    FileReader:文件字符输入流
    作用:把硬盘文件中的数据以字符的方式读取到内存中
    构造方法:
  • FileReader( String filename)
  • FileReader(File file)
    参数:读取文件的数据源
    String filename:文件的路径
    File file:一个文件
    FileReader构造方法作用
    1. 创建一个FileReader对象
    2. 会把FileReader对象指向要读取的文件
    字符输入流使用步骤
  1. 创建FileReade对象,构造方法中绑定要读取的数据源
  2. 使用FileReader对象中的方法read读取文件
  3. 释放资源
import java.io.FileReader;
import java.io.IOException;

public class Fr1 {
    public static void main(String[] args) throws IOException {
        FileReader fr=new FileReader("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
        /*int len=0;
        while((len=fr.read())!=-1){
            System.out.println((char)len);
        }*/


        char [] cs =new char[1024];
        int len1=0;
        while((len1=fr.read(cs))!=-1){
            System.out.println(new String(cs,0,len1));
        }
        fr.close();
    }
}

(五)字符输出流【Writer】

  • java.io.Writer:字符输出流,是所有字符输出流最顶层父类,是一个抽象类。
    共性的成员方法
  • void write(int c):写入单个字符
  • void write( char [ ] cbuf ):写入字符数组
  • abstract void write( char [ ] cbuf, int off, int len):写入字符数组的某一部分,off数组开始索引,len写的字符个数。
  • void write( String str):写入字符串
  • void write( String str, int off ,int len):写入字符串的一部分,off字符串的开始索引,len写的字符个数。
  • void flush( ):刷新该流的缓冲
  • void colse( ):关闭此流
    FileWriter:文件字符输出流
    作用:把内存中字符数据写入到文件中。
    构造方法
    - FileWriter( File file):根据给定的File对象构造一个FileWriter对象。
    - FileWriter(String filename):根据给定的文件名构成一个FileWriter对象。
    参数:写入数据的目的地
    - String filename:文件的路径
    - File file:一个文件
    构造方法的作用
    1. 会创建一个FileWriter对象
    2. 会根据构造方法中传递的文件/文件路径,创建文件
    3. 会把FileWriter对象指向创建好的文件
    字符输出流的使用步骤
    1. 创建FileWriter对象,构造方法中绑定要写入数据的目的地
    2. 使用FileWriter中的方法write,把数据写到内存缓冲区中(字符转换为字节的过程)
    3. 使用FileWriter中的方法flush,把内存缓冲区中的数据,刷新到文件中
    4. 释放资源(会先把内存缓冲区中的数据刷新到文件中)
import java.io.FileWriter;
import java.io.IOException;

public class Fw {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
        fw.write(98);
        fw.flush();

    }
}

关闭和刷新的区别

  • flush:刷新缓冲区,流对象可以继续使用
  • colse:先刷新缓冲区,再通知系统释放资源。流对象不可以再被使用了。

字符数据流写数据的其他方法

  • void write( char[ ] cbuf):写入字符数组
  • abstract void write(char [ ] cbuf ,int off, int len):写入字符数组的某一部分,off数组的开始索引,len写的字符个数
  • void write( String str):写入字符串
  • void write( String str,int off, int len):写入字符串的某一部分,off字符串的开始索引,len写的字符个数。
import java.io.FileWriter;
import java.io.IOException;

public class Fwelse {
    public static void main(String[] args) throws IOException {
        FileWriter fw =new FileWriter("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
        char [] cs={'a','b','c','d'};
        fw.write(cs);
        fw.write(cs,1,3);
        fw.write("你好");
        fw.write("世界",2,3);
        
        fw.close();
    }
}

续写和换行

import java.io.FileWriter;
import java.io.IOException;

public class Fw1 {
    public static void main(String[] args) throws IOException {
        FileWriter fw =new FileWriter("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt",true);
        fw.write("zhangsan");
        fw.write("\n\n");
        fw.write("java");
        fw.close();

    }
}

(六)异常处理
格式

try { 
		可能会出现异常的代码
	}catch(异常类 变量名){
		异常的处理逻辑
	}finally{
		一定会指定的代码
		资源释放
	}
  • jdk1.7以前格式
import java.io.FileWriter;
import java.io.IOException;

public class Fe {
    public static void main(String[] args) {
        FileWriter fw =null;
        try{
            fw =new FileWriter("C:\\Users\\阚开豪\\Desktop\\javaFile\\z.txt");
        }catch (IOException e){
            System.out.println(e);
        }finally {
            if(fw!=null){
                try{
                    fw.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
}

jdk7

try(定义流对象;定义流对象...){
	可能会出现异常的代码
	}catch(异常类变量 变量名){
	异常处理逻辑
	}

jdk9

A a= new A();
B b=new B():
try(a,b){
	可能会出现异常的代码
	}catch(异常类变量 变量名){
	异常处理逻辑
	}

四、属性集
(一)概述

  • java.util.Properties集合extengds Hashtabe<k,v> implemrnts Map<k,v>
  • Properties类表示一个持久的属性集,可以保存在流中或从流中加载。
  • Properties集合是一个唯一和IO流相结合的集合。
    1. 可以使用方法store,把集合中临时数据持久化写入硬盘中存储。
    2. 可以使用方法load,把硬盘中保存的文件,读取到集合中使用
  • Properties是一个双列集合,key和value默认都是字符串。
  • Properties集合中有一操作字符串的特有方法
  1. Object setProperty(String key,String value):调用Hashtable方法put。
  2. String getProperty(String key):通过key找到value值,此方法相当于Map集合中的get(key)方法。
  3. Set<String> stringPropertyNames():返回此属性列表中的键集。
import java.util.Properties;
import java.util.Set;

public class Pm {
    public static void main(String[] args) {
        Properties prop = new Properties();
        prop.setProperty("zhangsan","shanghai");
        prop.setProperty("lisi","beijing");
        prop.setProperty("zhaosi","xian");

        Set<String> set =prop.stringPropertyNames();

        for(String key : set){
            String values = prop.getProperty(key);
            System.out.println(key+"=="+values);
        }
    }
}

(二)store方法

  • void store(OutputStream out,String comments)
  • void store(Writer writer,String comments)
  • 参数
    1. OutputStream out:字节输出流,不能写入中文
    2. Writer writer:字节输出流,可以写中文
    3. String comments:注释。不能使用中文,一般使用空字符串。
  • 使用步骤
    1. 创建Properties集合对象,添加数据
    2. 创建流对象,构造方法中绑定要输出的目的地
    3. 使用方法store,把集合中临时数据,持久化写入到硬盘中存储。
    4. 释放资源
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;

public class Pm {
    public static void main(String[] args) throws IOException {
        Properties prop = new Properties();
        prop.setProperty("zhangsan","shanghai");
        prop.setProperty("lisi","beijing");
        prop.setProperty("zhaosi","xian");

        /*FileWriter fw =new FileWriter("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
        prop.store(fw,"C:\\Users\\阚开豪\\Desktop\\javaFile\\b\\d.txt");
        fw.close();*/

        prop.store(new FileOutputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\b\\d.txt"),"");
    }
}

(三)load方法

  • void load(InputStream inStream)
  • void load(Reader reader)
  • 参数
    1. InputStream inStream:字节输入流,不能读取含有中文的键值对
    2. Reader reader:字符输入流,能读取含有中文的键值对
  • 使用步骤
    1. 创建Properties集合对象
    2. 使用Properties集合对象方法load读取保存键值对的文件
    3. 遍历集合
  • 注意
    存储键值对的文件中可以使用#进行注释。
import java.io.*;
import java.util.Properties;
import java.util.Set;

public class Pm {
    public static void main(String[] args) throws IOException {
        Properties prop = new Properties();
        prop.setProperty("zhangsan","shanghai");
        prop.setProperty("lisi","beijing");
        prop.setProperty("zhaosi","xian");

        //prop.load(new FileReader("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"));
        prop.load(new FileInputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"));
        Set <String> set =prop.stringPropertyNames();
        for(String key:set){
            String value = prop.getProperty(key);
            System.out.println(key+" "+value);
        }
    }
}

五、缓冲流
(一)概述
缓冲流也叫高效流,是对四个基本的FilesXxx流的增强。

  • 字节缓冲流:BufferedInuputStream `BufferedOutputStream
  • 字符缓冲流:BufferedReader BufferderedWriter
  • 缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统的IO次数,从而提高读写的效率
    (二)字节缓冲输出流
  • java.io.BufferedOutputStream extends OutputStream
  • 构造方法
  1. BufferedOutputStream(OutputStream out):创建一个新的缓冲输出流,将数据写入指定的底层输出流
  2. BufferedOutputStream(OutputStream out, int size):创建一个新的缓冲输出流,将具有指定缓冲区大小的数据写入指定的底层输出流
  • 参数:
  1. OutputStream:字节输出流
  2. int size:指定缓冲流内部缓冲区的大小,不指定默认
  • 使用步骤
    1. 创建FileOutputStream对象,构造方法中绑定要输出的目的地
    2. 创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象,提高效率
    3. 使用write方法,把数据写入到内部缓冲区中
    4. 使用flush方法,把内部缓冲区中的数据,刷新到文件中
    5. 释放资源(会先调用flush方法刷新数据,第四步可省略)
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class BFO {
    public static void main(String[] args)throws IOException {
        FileOutputStream fos = new FileOutputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        bos.write("Hello,java!".getBytes());
        bos.flush();
        bos.close();
    }
}

文件复制

  1. 创建字节缓冲输入流对象,构造方法中传递字节输入流
  2. 创建字节缓冲输出流对象,构造方法中传递字节输出流
  3. 使用字节缓冲输出流方法read,读取文件
  4. 使用方法write,把读取到的数据写入到内部缓冲区中
  5. 释放资源(会先把缓冲区中的数据,刷新到文件中)

(三)字符缓冲输出流

  • java.io.BufferdWriter extends Writer
    构造方法
  • BufferedWriter( Writer out ):创建一个使用默认大小的输出缓冲区的缓冲字符输出流
  • BufferedWriter( Writer out, int sz):创建一个使用给定大小的输出缓冲区的新缓冲字符输出流
    参数
    1. Writer out:字符输出流
    2. int sz:指定缓冲区的大小,不写默认大小
      特有的成员方法
      • void newline( ):写入一个行分隔符。
        使用步骤
    3. 创建字符缓冲输出流对象,构造方法中传递字符输出流
    4. 调用字符缓冲输出流对象中方法write,把数据写到内存缓冲区中
    5. 调用方法flush,把内存缓冲区的数据刷新到文件中
    6. 释放资源
import java.io.*;

public class BFO {
    public static void main(String[] args)throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"));
        for (int i = 0; i < 10; i++) {
            bw.write("你好Java!");
            bw.newLine();
        }
        bw.flush();
        bw.close();
    }
}

(五)字符缓冲输入流
构造方法

  • BufferedReader( Reader in ):创建一个使用默认大小输入缓冲区的缓冲字符输入流
  • BufferedReader( Reader in , int sz):创建一个使用指定大小输入缓冲区的缓冲字符输入流
    参数
  • Reader in :字符输入流
    特有的成员方法
  • String readline( ):读取一个文本行。读取一行数据的行的终止符号。(黄行,回车,回车后加换行)
  • 返回值:包含该行内容的字符串,不包含任何终止符,如果到达流末尾,则返回null。
    使用步骤
  1. 创建字符缓冲输入流对象,构造方法中传递字符输入流
  2. 使用字符缓冲输入流中的方法read/readline读取文本
  3. 释放资源
import java.io.*;

public class BFO {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"));
        String line;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
        br.close();
    }
}

六、转换流
(一)字符编码和字符集
字符编码

  • 编码:字符(能看懂的)-- 字节(看不懂的)
  • 解码:字节(看不懂的)-- 字符(能看懂的)
    字符编码:就是一套自然语言的字符与二进制之间的对应规则。
    编码表:生活中文字和计算机中二进制的对应规则
    字符集:也叫编码表。是一个系统支持的所有字符的合集,包括个国家文字、标点符号、图像符号和数字。常见的有
    1. ASCII字符集
    2. GBK字符集
    3. Unicode字符集
      (二)转换输出流
  • java.io.OutputStreamWriter extends Writer
  • OutputStreamWriter:是字符流通向字节流的桥梁,使用指定的charset将要写入流中的字符编码成字节。
    构造方法
  • OutputStreamWriter(OutputStream out):创建使用默认字符编码的OutputStreamWriter。
  • OutputStreamWriter(OutputStream out, String charsetName):创建使用指定字符集的OutputStreamWriter。
    参数
    • OutputStream out:字节输出流,可以用来写转换之后的字节到文件中
    • String charsetName:指定的编码表名称,不区分大小写(UTF-8、GBK…)
      使用步骤
    1. 创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称
    2. 使用OutputStreamWriter中的方法write,把字符转换为字节存储缓冲区中
    3. 使用flush方法,把内存缓冲区的字节刷新到文件中
    4. 释放资源
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class OS {
    public static void main(String[] args) throws IOException{
        write_utf();
        write_gbk();
    }

    private static void write_utf() throws IOException {
        OutputStreamWriter osw  =new OutputStreamWriter(new FileOutputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"),"utf-8");
        osw.write("你好");
        osw.flush();
        osw.close();
    }

    private static void write_gbk() throws IOException{
        OutputStreamWriter osw  =new OutputStreamWriter(new FileOutputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"),"gbk");
        osw.write("你好");
        osw.flush();
        osw.close();
    }
}

(三)转换输入流

  • java.io.InputStreamReader extends Reader
  • InputStreamReader:是字节流通向字符流的桥梁,它使用指定的charset读取字节并将其解码为字符。`
    构造方法
    • InputStream(InputStream in):创建一个使用默认字符集的InputStreamReader。
    • InuputStreamReader(InputStram in, String charsetName):创建使用指定字符集的的InputStreamReader。
      参数
  • InputStream in:字节输入流,用来读取文件中保存的字节
  • String charsetName:指定编码表名称。不指定默认使用UTF-8。
    使用步骤
    1. 创建InputStream对象,构造方法中传递字节输入流和指定的编码表名称
    2. 使用InputStreamReader对象中的方法read读取文件
    3. 释放资源
      注意事项:构造方法中的指定编码表名称要和文件的编码相同。
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class IS {
    public static void main(String[] args) throws IOException {
        read_utf();
        read_gbk();
    }

    private static void read_gbk() throws IOException {

            InputStreamReader isr = new InputStreamReader(new FileInputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"),"gbk");
            int len=0;
            while ((len=isr.read())!=-1){
                System.out.println((char)len);
            }
            isr.close();
        }

    private static void read_utf() throws IOException{
        InputStreamReader isr = new InputStreamReader(new FileInputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"),"utf-8");
        int len=0;
        while ((len=isr.read())!=-1){
            System.out.println((char)len);
        }
        isr.close();
    }
}

案例:转换文件编码

  1. 指定GBK编码的转换流读取文件
  2. 使用UTF-8编码的转换流写出文件
import java.io.*;

public class IOS {
    public static void main(String[] args) throws IOException {
        InputStreamReader isr =new InputStreamReader(new FileInputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"),"GBK");
        OutputStreamWriter osw =new OutputStreamWriter(new FileOutputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\z.txt"),"UTF-8");

        int len=0;
        while((len=isr.read())!=-1){
            osw.write(len);
        }
        osw.close();
        isr.close();
    }
}

七、序列化和反序列化
(一)概述

  • 把对象以流的方式写入到文件中保存。叫写对象也叫对象的序列化。
  • 对象中包含的不仅仅是字符,使用字节流。(ObjectOutputStream:对象的序列化流)
  • 把文件中保存的对象以流的方式读取出来,叫读对象也叫对象的反序列化。
  • 读取的文件保存的都是字节,使用字节流(ObjectInputStream:对象的反序列化流)

(二)对象的序列化流

  • java.io.ObjectOutputStream extends OutpuStream
  • 作用:把对象以流的方式写入到文件保存
    构造方法
    -ObjectOutputStream(OutputStream out):创建写入指定OutputStream的ObjectOutputputStream。
    -参数:OutputStream out:字节输出流
    特有的成员方法
  • void writeObject(Objecr obj):将指定的对象写入ObjectOutputStream。
    使用步骤
    1. 创建ObjectOutputStream对象,构造方法中传递字节输出流
    2. 使用方法writeObject;把对象写入到文件中
    3. 释放资源
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class OOS {
    public static void main(String[] args) throws IOException {
        ObjectOutputStream oos =new ObjectOutputStream(new FileOutputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"));
        oos.writeObject(new Person("zhangsan",18));
        oos.close();
    }
}

注意:序列化和反序列化时会抛出没有序列化异常。

  • 通过实现java.io.Serializable接口启用序列化功能。
    (三)对象的反序列化流
  • java.io.ObjectInputStream extends InputStream
  • 作用:把文件中保存的对象,以流的方式读取出来使用
    构造方法
    -ObjectInputStream(InputStream in):创建从指定InputStream读取的ObjectInputStream。
    • 参数:InputStream in:字节输入流
      特有的成员方法
    • Object readObject( )从ObjectInputStream读取对象。
      使用步骤
    1. 创建ObjectInputStream对象,构造方法中国传递字节输入流
    2. 使用ObjectInputStream对象中的方法readObject读取保存对象的文件
    3. 释放资源
    4. 使用读取出来的对象(打印)
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class OIS {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectInputStream ois =new ObjectInputStream(new FileInputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"));
        Object o =ois.readObject();
        System.out.println(o);
        ois.close();
    }
}

反序列化的前提

  1. 类必须实现Serializable
  2. 必须存在类对应的class文件
    (四)瞬态关键字
  3. static关键字:静态
    静态优先于非静态加载到内存中。
    被static修饰的成员变量不能被序列化,序列化的都是对象
  4. transient关键字:瞬态
    被transient修饰成员变量不能被序列化。
    (五)反序列化操作异常处理
  • 在class文件在序列化对象后发生修改,反序列化会失败并抛出InvalidClassException异常,原因如下:
    1. 该类的序列版本号与从流中读取的类描述的版本号不匹配
    2. 该类包含未知数据类型
    3. 该类没有可访问的无参数构造方法
      -解决方法
      加入序列版本号
      -private static final long serialVersionUID = long int;
      (六)案例:序列化集合
  • 将存储的集合对象序列化后输出
import java.io.*;
import java.util.ArrayList;

public class OOIIS {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ArrayList<Person> list = new ArrayList<>();
        list.add(new Person("zhangsan",18));
        list.add(new Person("lisi",90));
        list.add(new Person("wangmazi",25));

        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"));
        oos.writeObject(list);
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt"));
        Object o = ois.readObject();
        ArrayList<Person> list1 = (ArrayList<Person>) o;
        for(Person p:list1){
            System.out.println(p);
        }
        ois.close();
        oos.close();
    }
}

八、打印流
(一)概述
-java.io.PrintStream:打印流。为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。

  • 特点:
    1. 只负责数据的输出,不负责数据的读取。
    2. 与其他输出流不同,打印流不会抛出IO异常。
    3. 有特有的方法,print和println。
    (二)使用
    构造方法
    - PrintStream(File file):输出的目的地是一个文件
    - PrintStream(OutputStream out):输出的目的地是一个字节输出流
    - PrintStream(String fileName):输出的目的地是一个文件路径
    注意
    1. 如果使用继承自父类的write方法写数据,那么查看数据的时候会查询编码表
    2. 如果使用在自己特有的方法写数据,写的数据原样输出。
import java.io.FileNotFoundException;
import java.io.PrintStream;

public class PSM {
    public static void main(String[] args) throws FileNotFoundException {
        PrintStream psm = new PrintStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
        psm.write(97);//a
        psm.println(97);//97
    }
}

  • 使用System.setOut方法改变输出语句的目的地改为参数中传递的打印流的目的地。
  • static void setOut(PrintStream Out):重新分配标准输出流
import java.io.FileNotFoundException;
import java.io.PrintStream;

public  class PSM {
    public static void main(String[] args) throws FileNotFoundException {
        PrintStream psm = new PrintStream("C:\\Users\\阚开豪\\Desktop\\javaFile\\e.txt");
        System.setOut(psm);
        System.out.println("Hello,java!");
        psm.close();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值