java基础总结2


File类

java.io.File类

  • 作用:文件和目录路径名的抽象表现形式,把电脑中的文件和文件夹封装为了File类,我们可以使用File操作文件和文件夹
  • 提示:File类是与系统无关的类,任何操作系统都可使用这个类

File类静态成员变量

  • pathSeparator : 路径分隔符

  • separator : 路径名称分隔符

    注意:

      1. 操作路径不能写死,用File的静态变量来表示分隔符
      1. 路径不区分大写
      1. 路径中的文件名称分隔符windows使用反斜杠,反斜杠是转义字符,两个反斜杠表示一个普通反斜杠

File类构造方法

  • 1.File(String pathname) : 将指定路径名字符串转换为抽象路径名来创建一个File实例
  • 2.File(String parent , String child) : 根据父子路径创建File类实例
  • 3.File(File parent , String child) : 根据parent抽象路径和child路径创建File类实例

常用功能方法

    1. public String getAbsolutePath(): 返回File的绝对路径
    1. public String getPath(): 将File转换为路径名字符创
    1. public String getName(): 返回由此File表示的文件或目录的名称
    1. public long length(): 返回文件的长度(大小,以字节为单位)(toString方法就是调用此方法)
    1. public boolean exists(): 此File表示的文件或者目录是否存在
    1. public boolean isDirector(): 此File表示的是否为目录
    1. public boolean isFile(): 此File表示的是否是文件

isDirector 和 isFile 方法使用的前提是必须File表示的文件路径是存在的,否则都返回false,如果路径存在,两个方法返回值正好相反

public class Demo01File {
    public static void main(String[] args) {
        String p = File.pathSeparator;
        // System.out.println(p); // linux是 : , window是 ;
        String s = File.separator;
        // System.out.println(s); // linux 是 / , window 是 \
        File f = new File("/Users/jiatengda/Desktop/basic-code/a.txt");
        System.out.println(f); // /Users/jiatengda/Desktop/basic-code/a.txt
        File f2 = new File("C" , "b.md");
        System.out.println(f2); // C/b.md
        System.out.println(f.getAbsoluteFile());///Users/jiatengda/Desktop/basic-code/a.txt
        System.out.println(f.getPath()); // /Users/jiatengda/Desktop/basic-code/a.txt
        System.out.println(f.toString()); // /Users/jiatengda/Desktop/basic-code/a.txt
        System.out.println(f.getName()); //a.txt
        System.out.println(f.length()); // 0 无此文件也是0
    }
}

IO流

  • I(input): 输入(读取)
  • O(output): 输出(写入)
  • 流: 数据(字符,字节) => 1 字符 = 2 字节 = 8二进制位

字节流

  • InputStream: 字节输入流
  • OutputStream : 字节输出流

一切皆为字节

  • 电脑中存储的任意文件都是以二进制形式保存,传输时一样如此,字节流可以传输任意文件数据,底层传输的始终是二进制数据.

java.io.OutputStream : 此抽象类是所有表示输出字节流的超类

共性方法

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

java.io.FileOutputStream extends OutputStream : 文件字节输出流

  • 作用: 把内存中的数据写入到硬盘的文件中
  • 写入数据的原理(内存 -> 硬盘):
    • java程序->JVM(java虚拟机)->OS(操作系统)->OS调用写数据的方法->把数据写入到文件中

文件字节输出流使用步骤

public class Demo04File {
    public static void main(String[] args) throws IOException {
        // 1.创建一个FileOutputStream对象,构造方法中传递写入数据的目的地
        FileOutputStream fos = new FileOutputStream("a.txt");
        // 2.调用FileOutputStream对象中的write方法,把数据写入到文件中
        fos.write(97);
        // 3.释放资源(流的使用会占用一定内存,使用完毕要关闭掉,提高程序效率)
        fos.close();
    }
}

InputStreamFile 输入流

  • 此抽象类表示字节输入流的所有类的超类

共性方法

  • int read(): 从输入流中读取下一个字节

  • int read(byte[] b) : 从输入流中读取一定量的字节,并将其存在缓冲区b中

  • void close() : 关闭此输入流并释放相关的所有资源

    实现类 java.io.FileInputStream extends InputStream

    • 文件输入流,读取文件(把硬盘中的数据,读取到内存中使用)

    读取数据原理:java程序 -> jvm -> os -> os读取数据的方法 -> 读取文件

    字节输入流的使用步骤:

    • 使用字节流读取中文字符时的问题:会产生乱码的问题 => 使用字符流解决
      public class Demo05FileInput {
      public static void main(String[] args) throws IOException {
       // 1. 创建FileInputStream对象,构造方法中绑定要读取的数据源
       FileInputStream fis = new FileInputStream("a.txt");
       // 2. 使用FileInputStream对象中的方法read读取文件
       // int read() 读取一个字节并返回,读到最后返回-1
       int len = 0; // 记录读取到的字节
       while ((len = fis.read() )!=-1){
           // 条件判断
           // 1. fis.read()读取一个字节
           // 2. len = fis.read(): 读取到的字节赋值给len
           // 3. 与-1进行判断
           System.out.println((char) len);
       }
       //3. 释放资源
       fis.close();
      }
      }

一次读取多个字节

  • int read(byte[] b) : 从输入流中读取一定量的字节,并将其存在缓冲区b中

参数byte[]的作用

  • 起到缓冲作用,存储每次读取到的多个字节,
  • 数组的长度一般把其定义为1024(1kb)或者1024的整数倍
  • 返回值int是每次读取有效字节的个数
public class Demo06FileInput {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("a.txt");
        byte[] bytes = new byte[1024]; // 存储读取到的多个字节
        int len = 0;

        while ((len = fis.read(bytes)) !=-1){
            System.out.println(new String(bytes,0,len));
        }
        fis.close();
    }
}

复制文件案例

package cn.jiatengda.day09.demo08;
// 文件复制

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

/**
*

    1. 创建字节输入流对象,构造方法中绑定要读取的数据源
    1. 创建字节输出流对象,构造方法中绑定要写入的目的地
    1. 输入流对象read,输出流write
    1. 释放资源
  • /

public class Demo07File {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream(“/Users/jiatengda/Desktop/LiQuan/孟炜浩简历.docx”);
FileOutputStream fos = new FileOutputStream(“/Users/jiatengda/Desktop/Project/1.docx”);
byte[] bytes = new byte[1024];
int len = 0;
while ((len = fis.read(bytes))!= -1){
fos.write(bytes,0,len);
}
// 先关闭写入流,后关闭读取流
fos.close();
fis.close();
}
}


> 字符流
> - Reader: 字符输入流
> - Writer: 字符输出流

> java.io.Reader: 字符输入流,是字符输入流最顶层父类
> - 是一个抽象类,定义了共性的成员方法:
>   - 1. int read() : 读取单个字符并返回
>   - 2. int read(char[] chars) : 读取多个字符,并读入数组
>   - 3. void close() : 关闭流并释放资源

> java.io.FileReader extends InputStreamReader extends Reader:
> -  作用:把硬盘文件中的数据以字符的方式读取到内存中

> 使用步骤
```java
public class Demo01Reader {
    public static void main(String[] args) throws IOException {
        // 1. 创建一个FileReader对象
        FileReader fr = new FileReader("a.txt");
        // 2. 调用read方法读取
//        int len = 0 ;
//        while ((len = fr.read())!=-1){
//            System.out.print((char)len);
//        }
        // 2. 利用缓冲数组多个字符读取
        char[] chars = new char[1024];
        int len = 0;
        while ((len = fr.read(chars))!=-1){

            /**
             * String(char[] value) : 把字符数组转化为字符串
             * String(char[] value , int offset , int length) : 将指定位置和长度的字符数组转换为字符串
             */
            System.out.println(new String(chars,0,len));
        }
        // 3. 释放资源
        fr.close();
    }
}

java.io.Writer: 抽象类,字符输出流最顶层的超类

  • 共性成员方法:
    • void write(int c) :
    • void writer(char[] cbuf) 写入字符数组
    • abstract void writer(char[] cbuf , int off , int len ) 写入数组的一部分,
    • write (String str) 写入字符串
    • write (String str , int off , int len) 写入字符串一部分
    • void flush() 刷新该流的缓冲
    • void close() 关闭此流,但是要先刷新它

java.io.FileWriter extends OutputStreamWriter extends Writer : 文件字符输出流,把内存中的数据写入到文件中

使用步骤

public class Demo01Writer {
    public static void main(String[] args) throws IOException {
        //  1. 创建一个FileWriter对象
        FileWriter fw = new FileWriter("a.txt");
        // 2. 调用write方法写入字符
        fw.write(97);
        // 3. 使用FileWriter中的方法flush , 把内存缓冲区中的内容,刷新到文件中
        fw.flush();
        fw.write(98);
        // 4. 释放资源(会先把内存区中的数据刷新到文件中 )
        fw.close();
    }
}

flush 和 close的区别

  • flush :刷新缓冲区,流可以继续使用
  • close : 刷新缓冲区,然后通知系统释放资源,流对象不能继续使用

续写和换行

  • FileWriter(String filename ,boolean append)
  • FileWriter(File file ,boolean append)
  • 换行 macOS: \r linux: \n window: \r \n

缓冲区buffered

缓冲流: 基本流是一个一个的读,缓冲流会增加一个缓冲区,把字节/字符存到数组中,然后在返回

子节缓冲输出流: 字节输出流的方法可用

  • 构造方法
    • BufferedOutputStream(OutputStream os)
    • BufferedOutputStream(OutputStream os , int size)

使用步骤

  • 字节缓冲输入流类似
    public class Demo01Buffered {
      public static void main(String[] args) throws IOException {
          // 1.创建字节输出流(FileOutputStream)对象,构造方法中绑定要输出的目的地
          FileOutputStream fos = new FileOutputStream("c.txt");
          // 2.创建BufferedInputStream对象,构造方法传递FileOutputStream对象,提高效率
          BufferedOutputStream bos = new BufferedOutputStream(fos);
          // 3.使用BufferedInputStream对象中的方法write,把数据写入到内部缓冲区中
          bos.write("把数据写入到缓冲区中".getBytes());
          //4.使用BufferedInputStream对象中的方法flush,把内部缓冲区的数据,刷新到文件中
          bos.flush(); // 可不写
          // 5.释放资源
          bos.close();
      }
    }

字符缓冲区

  • BufferedWriter extends Writer
    • 特有成员方法: void newLine():写入一个行分隔符,根据系统写换行符
  • BufferedReader extends Reader
    • 特有成员方法String readline() : 读取一行文本。行的终止符号 \r \n \r\n
      • 返回值 : 返回一行,如果达到末尾,返回null
public class Demo01BufferedWriter {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));
        for (int i = 0; i < 10; i++) {
            bw.write("贾腾达");
            bw.newLine();
        }
        bw.flush();
        bw.close();
    }
}

编码(转化流)

ascii 编码: 美国编码表
gbxxx: 中文编码表,一般中文两个字节表示
unicode : 万国码,utf-8最为常见。一般中文三个字节表示,

编码不同引出的问题

IDE一般是utf8编码,但是读取系统文件是默认gbk编码,或出现乱码问题

转换流解决编码问题

转换流可以指定编码表

  • InputStreamReader
  • OutputStreamWriter

转换流原理

转换流的使用

    package cn.jiatengda.day09.demo10;


import java.io.*;

/**
 * OutputStreamWriter extends Writer
 *  作用: 字符流通向字节流的桥梁,把字符转换为字节,把能看懂的转换为看不懂的
 *  拥有父类的共性方法
 *
 *  构造方法:
 *      OutputStreamWriter(OutputStream out) : 使用默认字节编码
 *      OutputStreamWriter(OutputStream out , String charsetName) 使用指定字节编码
 *      参数:
 *          OutputStream out : 字节输出流,把转换的字节写入指定位置
 *          String charsetName : 指定编码表名称,不区分大小写,不指定默认使用utf-8
 *   使用步骤:
 *      1. 创建OutputStreamWriter对象,构造方法中传入字节输出流和指定的编码表名称
 *      2. 使用OutputStreamWriter对象中的方法write,把字符转换为字节存储在缓冲区中(编码)
 *      3. 使用OutputStreamWriter对象中的flush方法,把内存缓冲去中的字节刷新到文件中
 *      4. 释放资源
 *
 *  ### InputStreamReader extends Reader
 *   作用: 字节流向字符的桥梁,把字节转换为字符,把看不懂的转换为能看懂的
 *   拥有父类的共性方法
 *
 *   构造方法:
 *   InputStreamReader(InputStream)
 *   InputStreamReader(InputStream,String charsetName)
 *
 *   使用步骤:
 *      1. 创建InputStreamReader对象,构造方法中传入字节输入流和指定的编码表名称
 *      2. 使用InputStreamReader对象中的read方法,读取文件
 *      3. 释放资源
 *   注意:
 *      1. 构造方法中指定的编码表名称和文件的编码必须相同,否则会乱码
 *
 */

public class Demo01InputFR {

    public static void main(String[] args) throws IOException {
        write_utf_8();
        read_utf_8();
    }
    // 读取utf-8的文件
    private static void read_utf_8() throws IOException {
        InputStreamReader isr = new InputStreamReader(new FileInputStream("e.txt"),"utf-8");
        int len = 0;
        while ((len = isr.read())!=-1){
            System.out.println((char)len);
        }
        isr.close();
    }

    // 使用转换流OutputStreamWriter写utf-8格式的文件
    private static void write_utf_8() throws IOException {
        //  1. 创建OutputStreamWriter对象,构造方法中传入字节输入流和指定的编码表名称
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("e.txt"),"utf-8");
        // 2. 使用OutputStreamWriter对象中的方法write,把字符转换为字节存储在缓冲区中(编码)
        osw.write("你好啊,IDEA");
        osw.flush();
        osw.close();
    }
}

序列化和反序列化

对象以流的方式,写入到文件中保存,叫写对象,也叫对象的序列化。

  • ObjectOutputStream: 对象序列化流 => writeObject()
    • 特有成员方法: void writeObject(object obj) : 把指定对象写入ObjectOutputStream
  • ObjectInputStream: 对象反序列化流 => readObject()
    • 特有成员方法: Object readObject() 从ObjectInoutStream读取对象
    • 使用前提
        1. 类必须实现Serializable接口
        1. 必须存在对应的class文件

public class Demo01ObjStream {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
//        //1. 创建ObjectOutputStream对象,参数传递字节输出流
//        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.txt"));
//        // 2. 使用ObjectOutputStream对象方法writeObject,把对象写入文件中
//        oos.writeObject(new Person("贾腾达",18)); // NotSerializableException
//        // 3. 释放资源
//        oos.close();
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.txt"));
        Object obj =  ois.readObject();
        ois.close();
        System.out.println(obj);
        Person p = (Person) obj ;
        System.out.println(p.getAge() + p.getName());
    }
}

Person 类

package cn.jiatengda.day09.demo10;

import java.io.Serializable;

/**
 * Serializable接口,也叫标记性接口
 *  要进行序列化和反序列化的类必须实现此接口,会给类添加一个标记
 *  当我们进行序列化和反序列化的时候,就会检测这个类上是否有这个标记,如果有就可以序列化或者反序列化,否则就会跑出NotSerializable异常
 *  比如去市场卖肉,肉上有一个蓝色的章,上面有检测合格,有这个才可以放心购买。
 */

public class Person implements Serializable {

    private String name ;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    public Person() {}
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

transient关键字: 瞬态关键字

  • 被transient关键字修饰的成员变量不能被序列化
  • 当不想成员变量被序列化可以用此关键字修饰
  • 没有static的含义,而且不能被序列化

static关键字: 静态关键字

  • 优先于非静态加载到内存中(优先于对象进入到内存中)
  • 被static修饰的成员变量是不能被序列化的,序列化的都是对象

异常: 找不到class文件的原理

  • 可以给可序列化类声明serialVersionUID的字段,
  • 字段固定格式 修饰符 static final long serialVersionUID = xxx;

打印流

java.io.PrintStream extends OutputStream: 打印流

  • 作用: 为其他流增加了功能,使他们能够方便的打印各种数据值表示形式

特点

    1. 只负责数据的输出,不负责数据的独处
    1. 和其他流不一样 ,永远不会抛出IOException
    1. 有特有的方法,print,println,参数可以是任意类型值

构造方法

  • PrintStream(File file) : 输出的目的地是一个 文件

  • PrintStream(OutputStream out) : 输出的目的地是一个字节输出流

  • PrintStream(String filename) : 输出的目的地是一个文件路径

    public class Demo01StreamConsole {
    public static void main(String[] args) throws FileNotFoundException {
    PrintStream ps = new PrintStream("f.txt");
    ps.write(97);//a
    ps.println(97);//97
    ps.println("a");//a
    ps.println("你好");//你好
    ps.println(true);//true
    ps.close();
    // 修改输出目的地
    System.setOut(ps);
    }
    }

Stram流 && 常用函数接口

常用函数接口

  • Supplier接口: Supplier : T get() , 生产接口
  • Consumer接口: Consumer : void accept(T t) 消费接口
  • Predicate接口: Predicate : 对某种类型的数据进行判断,结果返回布尔值
    • 唯一方法: boolean test(T t)
  • Function接口: Function<T,R>: 根据一个类型的数据得到另外一个类型的数据
    • 唯一抽象方法: R apply(T t)
    • 默认方法: andThen(): 进行组合操作

public class Demo02Func {
    public static void main(String[] args) {
//        boolean bol = checkString("abcd",(String str)->str.length() > 5);
//        System.out.println(bol);
        List<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("张三丰");
        list.add("张天");
        list.add("赵地");
        list.stream().filter(name -> name.startsWith("张")) // 参数为Predicate接口
                     .filter(name -> name.length()==3)
                     .forEach(name -> System.out.println(name)); // 参数为Consumer接口
    }

    private static boolean checkString(String str , Predicate<String> pre) {
        return pre.test(str);
    }
}

Stram流

常用方法:

  • void forEach(Consumer<? super T> action)
  • 作用: 用来遍历流中数据
  • 是一个终结方法,调用完了后不能在调用流中的其他方法
  • Stream filter(Predicate<? super T> predicate)
  • 作用: 过滤流中的数据并返回过滤后的数据
  • R Stream map(Function <? super T , ? extends R> mapper)
  • 作用: 可以将当前T类型数据转换为R类型数据
  • long count()
  • 作用: 统计流中的元素个数
  • 是一个终结方法,不能再继续调用流中的其他方法
  • Stream limit(long maxSize); (从0截取到maxSize)
  • 作用: 对当前流进行截取,如果流长度大于参数,就截取,否则不进行任何操作
  • 是一个延迟方法,只对流中的数据进行截取,返回新的流,可以继续调取流的方法
  • Stream skip(long n); (从n截取到末尾)
  • 作用: 跳过n个流中元素,如果n大于流的长度,则返回一个空的流
  • static Stream concat(Stream<? extends T> a , Stream<? extends T>b)
  • 作用: 将两个流合并成一个流
  • 注意:
  • Stream流是管道流, 只能被消费一次,使用完之后就会关闭,不能再次使用
public class Demo01Streanm {

    public static void main(String[] args) {

        // 把集合转换成Stream流
        List<String> list =  new ArrayList<>();
        Stream<String> stream1 = list.stream();

        Set<String> set = new HashSet<>();
        Stream<String> stream2 = set.stream();

        Map<String,String> map = new HashMap<>();
        Set<String> keySet = map.keySet();
        Stream<String> stream3 = keySet.stream();

        Collection<String> values = map.values();
        Stream<String> stream4 = values.stream();

        Set<Map.Entry<String, String>> entries = map.entrySet();
        Stream<Map.Entry<String, String>> stream5 = entries.stream();

        // 把数组转换为流
        Stream<Integer> stream6 = Stream.of(1,2,3,4,5,6,7,8,9,0);
        Integer[] arr = {1,2,3,4,5,6};
        Stream<Integer> stream7 = Stream.of(arr);
        stream7.forEach(i -> System.out.println(i));
    }
}

文章作者: Jia
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Jia !
  目录