Java Stream流、 IO学习笔记

6、Stream流

6.1 Stream流的概述

对于ArrayList来说有时候的需求直接使用list的API会很麻烦,而Stream流可以简化其需求

1、数组获取流的方式

int[] arr = {1,2,3}

Stream<Integer> stream1 = Stream.of(1,2,3);
Stream stream3 = (Stream) Arrays.stream(arr);

2、ArrayList集合获取流的方式

ArrayList<String> one = new ArrayList<>();
Stream<String> stream = one.stream();

3、HashMap获取流的方式

//        获取key流
        Stream<String> stream3 = map.keySet().stream();
        
//        获取value流
        Stream<String> stream4 = map.values().stream();
        
//        获取键值对的Stream流
        Stream<Map.Entry<String, String>> stream5 = map.entrySet().stream();	
6.2 Stream流的常用API

其支持链式编程

流的终结方法(使用该方法之后就不能链式编程了):

  1. forEach:逐一遍历
  2. count:统计个数

非终结方法:

  1. filter:过滤元素
  2. limit: 取前几个元素
  3. skip:跳过前几个元素
  4. map: 加工元素
  5. concat:合并流
6.3 Stream流的收集

1、将Stream流收集成Set集合

ArrayList<String> list = new ArrayList();
list.add("a");
// 获取list流
Stream<String> listStream = list.stream();
// 收集流:将list流转成Set集合
Set<String> collect = listStream.collect(Collectors.toSet());

2、 将Stream流转为List集合

List<String> collect1 = listStream.collect(Collectors.toList());

3、将stream转为数组

// 这里的数组类型必须用Object
Object[] objects = listStream.toArray()
    
//  若是想将listStream转换成对于数组类型的流,则需要用“构造器引用申明”转换数组类型
String[] strings = stream.toArray(String[]::new);

6.4 File
6.4.1 创建文件夹对象
// 使用File构造器传入文件的相对路径,或绝对路径
File file = new File(String AbsolutePathName)
File file = new File(String PathName)
6.4.2 File文件常用的API

1、public String getName: 获取目录或文件名称
2、public String getPath: 获取文件或目录的相对路径
3、public String getAbsolute: 获取文件或目录的绝对路径
4、public boolean exists:判断目标文件或目录是否存在
5、public boolean isDirectory 判断目标文件是否是目录
6、public long length 返回文件的长度
7、public String[] list 返回该目录下的所有文件名称组成字符串数组
8、public File[] listFiles 返回一个抽象路径名称的数组
9、public boolean mkdir 在此路径一级目录下创建文件
10、public boolean mkdirs 可以创建一级或多级目录文件
11、public boolean renameTo(File dest) 重命名文件夹 dest - 指定文件的新抽象路径名

6.4.3 关于字符

1 个字节 = 8 位(8个开关)

1、ASCII编码:英文数字都采用1个字节表示 (美国)

2、GBK编码:汉字采用2个字节表示 (中国)

3、Unicode编码(UTF-8):统一采用3个字节表示 美国统一编码(万国码)

6.4.4 FileInputStream(字节流)

1、获取文件输入流

FileInputStream fileInputStream = new FileInputStream(file);

2、读取文件内容

2.1 单个字符分别读取

//        read() 默认读取1个字节 若流读取完,在读取则返回-1
        int code1 = fileInputStream.read();
        System.out.println((char) code1);

2.2 使用while循环读取字符

FileInputStream fileInputStream = new FileInputStream("src\\javaSE\\高级教程\\_11Stream流\\_03文件Stream流\\test.txt");
        int read = fileInputStream.read();
        int len;
        while((len = fileInputStream.read()) != -1){
            System.out.print((char) len);
        }
6.4.5 FileOutputStream(字节流)

1、向文件中写入文本的方法

  • write(int b)

  • write(byte[] b)

  • write(byte[] b, int off, int len) off:写入字节的初始位置 len:写入字节的长度

final FileOutputStream os = new FileOutputStream("src\\javaSE\\高级教程\\_11Stream流\\_03文件Stream流\\test.txt");
        os.write(111);
        os.write("河畔景苑".getBytes());
        os.write("大风车哈哈哈".getBytes(),0,9);
        os.flush();
        os.close();

// test.txt :
// o河畔景苑大风车

6.4.6 FileReader(字符流)

1、一个字符一个字符读取

File file = new File("src\\javaSE\\高级教程\\_11Stream流\\FileStream\\test.txt");
FileReader fr = new FileReader(file);
int read = fr.read();
System.out.println((char) read);

// 循环读取
int ch;
while((ch = fr.read()) != -1){
    System.out.print((char) ch);
}

2、使用字符串数组,实现多个字符读取

File file = new File("src\\javaSE\\高级教程\\_11Stream流\\FileStream\\test.txt");
FileReader fr = new FileReader(file);

char[] chBuffer = new char[3];
int len;
while((len = fr.read(chBuffer)) != -1){
    System.out.println("读取:"+len);
    String s = new String(chBuffer, 0, len);
    System.out.println(s);
}
6.4.6 FileWriter(字符流)

1、向指定文件中写入文本

 File file = new File("src\\javaSE\\高级教程\\_11Stream流\\FileStream\\test.txt");
        FileWriter fw = new FileWriter(file);
//        1、写一个字符出去
        fw.write(123);
        fw.write("我");
        fw.write("\r\n"); // 换行 这样子写,对不同操作系统的兼容性好
//        2、写入字符串
        fw.write("使用");
//        3、写一个字符数组出去
        fw.write("字符数组".toCharArray());
//        4、写字符串的一部分出去
        fw.write("我爱中国", 2,2);
//        5、写字符数组的一部分出去
        fw.write("我爱中国".toCharArray(), 0,2);

        fw.flush();
        fw.close();
6.5 Buffer缓冲流

1、Buffer缓冲流的读写性能要好于 FileInputStream、FileOutputStream、FileReader、FileWriter

原因就是在缓冲流会有一个8kb的缓冲区,而这个缓冲区实在内存里面的,所以这样读取就比直接读写硬盘要快,性能就要好很多

2、Buffer缓冲流的使用与 FileInputStream、FileOutputStream、FileReader、FileWriter的使用几乎差不多,区别就是Buffer缓冲流需要将FileInputStream、FileOutputStream、FileReader、FileWriter普通流包装成Buffer缓冲流

6.5.1 BufferedInputStream(字节缓冲流)
//        1、创建文件输入流
        FileInputStream is = new FileInputStream("src\\javaSE\\高级教程\\_11Stream流\\FileStream\\test.txt");

//        2、将文件输入流包装成缓冲输入流提高输入性能
        BufferedInputStream bis = new BufferedInputStream(is);
        int len;
        byte[] buffer = new byte[is.available()];
        while((len = bis.read(buffer)) != -1){
            String s = new String(buffer, 0, len);
            System.out.print(s);
        }
    }
6.5.2 BufferedOutputStream(字节缓冲流)
//        创建一个文件输出流
        FileOutputStream os = new FileOutputStream("src\\javaSE\\高级教程\\_11Stream流\\FileStream\\test.txt");
//        使用缓存输出流包装文件输出流
        BufferedOutputStream bos = new BufferedOutputStream(os);

//        输出一个整型
        bos.write(100);
        bos.write("我爱我国".getBytes());

        bos.flush();
        bos.close();
    }
6.5.3 BufferedReader(字符缓冲流)

相对于Reader新增的API

1、public String readLine():读取一行数据返回,读取完毕返回null

     try(
                FileReader fr = new FileReader("src\\javaSE\\高级教程\\_11Stream流\\FileStream\\test.txt");
                 BufferedReader bfr = new BufferedReader(fr)
        ){
            int len;
            char[] buffer = new char[3];

         // 普通读取
            while((len  = bfr.read(buffer)) != -1){
                String s = new String(buffer, 0 ,len);
                System.out.print(s);
            }
         
         //            一行一行读取
            String line;
            while((line = bfr.readLine()) != null){
                System.out.println(line);
            }
         
            System.out.println("\n读取完毕!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
6.5.4 BufferedWriter(字符缓冲流)
   try(
            final FileWriter fw = new FileWriter("src\\javaSE\\高级教程\\_11Stream流\\FileStream\\test.txt");
            final BufferedWriter bfw = new BufferedWriter(fw)
    ){
        bfw.write(1000);
        bfw.write("中国".toCharArray());
    }catch(Exception e){
        e.printStackTrace();
    }
}
6.5.5 普通流与Buffer缓冲流性能测试
public class BufferPerformanceTest {
    public static void main(String[] args) {
//        fileOneCharCopy();
        fileCharArrayCopy();
        bufferOneCharCopy();
        bufferCharArrayCopy();
    }
    final static String OLD_FILE_PATH = "D:\\杂七杂八的文件\\淘宝旺旺\\Download\\专升本高数视频\\【2022】【专升本高等数学】【基础全程班】【专升本高数】 - 28.28、第一章  利用极限求曲线渐近线、(第一章完犊子了)(Av969422474,P28).mp4";
    final static String NEW_FILE_PATH = "D:\\杂七杂八的文件\\淘宝旺旺\\Download\\Test\\";

    /**
     * 一个字节一个字节复制
     */
    public static void fileOneCharCopy(){
        long startTime = System.currentTimeMillis();
        try(
                final FileInputStream is = new FileInputStream(OLD_FILE_PATH);
                final FileOutputStream os = new FileOutputStream(NEW_FILE_PATH+"1.mp4")
        ) {

            int ch;
            while((ch = is.read()) != -1){
                try{
                    os.write(ch);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }

        }catch (Exception e){
            e.printStackTrace();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("一个一个字节复制消耗时间:"+(endTime-startTime)/1000.0);
    }

    /**
     * 使用字节数组传输
     */
    public static void fileCharArrayCopy(){
        long startTime = System.currentTimeMillis();
        try(
                final FileInputStream is = new FileInputStream(OLD_FILE_PATH);
                final FileOutputStream os = new FileOutputStream(NEW_FILE_PATH+"2.mp4")
        ) {
            System.out.println("开始复制...");
            int len;
            final byte[] buffer = new byte[1024];
            System.out.println("buffer:"+is.available());
            while((len = is.read(buffer)) != -1){
                try{
//                    System.out.println(new String(buffer));
                    os.write(buffer, 0, len);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }

        }catch (Exception e){
            e.printStackTrace();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("字节数组传输复制消耗时间:"+(endTime-startTime)/1000.0);
    }

    /**
     * 使用Buffer一个一个字节传输
     */
    public static void bufferOneCharCopy(){
        long startTime = System.currentTimeMillis();
        try(
                final FileInputStream is = new FileInputStream(OLD_FILE_PATH);
                final BufferedInputStream bis = new BufferedInputStream(is);

                final FileOutputStream os = new FileOutputStream(NEW_FILE_PATH+"3.mp4");
                final BufferedOutputStream bos = new BufferedOutputStream(os)
        ) {

            int ch;
            while((ch = bis.read()) != -1){
                try{
                    bos.write(ch);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }

        }catch (Exception e){
            e.printStackTrace();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("Buffer一个一个字节复制消耗时间:"+(endTime-startTime)/1000.0);
    }

    /**
     * 使用Buffer字节数组传输
     */
    public static void bufferCharArrayCopy(){
        long startTime = System.currentTimeMillis();
        try(
                final FileInputStream is = new FileInputStream(OLD_FILE_PATH);
                final BufferedInputStream bis = new BufferedInputStream(is);

                final FileOutputStream os = new FileOutputStream(NEW_FILE_PATH+"4.mp4");
                final BufferedOutputStream bos = new BufferedOutputStream(os)
        ) {

            int len;
            final byte[] buffer = new byte[1024];
            while((len = bis.read(buffer)) != -1){
                try{
                    bos.write(buffer, 0, len);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }

        }catch (Exception e){
            e.printStackTrace();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("Buffer字节数组传输复制消耗时间:"+(endTime-startTime)/1000.0);
    }


}
// 【结果】:
// 一个字节一个字节复制及其慢,就没跑
// 字节数组传输复制消耗时间:0.649
// Buffer一个一个字节复制消耗时间:1.812
// Buffer字节数组传输复制消耗时间:0.141 【性能挺好】
6.6 字符转换流
6.6.1 InputStreamReader

字符输入转换流,可以在读取时,按照程序员指定的编码格式进行读取文件,这样代码与文件格式不一致时就不会出现乱码的问题了

具体代码如下:

final File file = new File("src\\javaSE\\高级教程\\_11Stream流\\_03文件Stream流\\test.txt");
        final FileInputStream is = new FileInputStream(file);
        final InputStreamReader isr = new InputStreamReader(is, "GBK");

        int ch;
        final char[] buffer = new char[3];

        while((ch = isr.read(buffer)) != -1){
            System.out.print(buffer);
        }
6.6.2 OutputStreamWriter

字符输出转换流,在写入时,可以按照指定的编码格式将字符写入文件

具体代码如下:

final FileOutputStream os = new FileOutputStream("src\\javaSE\\高级教程\\_11Stream流\\_03文件Stream流\\test.txt");
        final OutputStreamWriter osw = new OutputStreamWriter(os, "GBK");

        osw.write("字符输出转换流");
        osw.close();

6.7 打印流

打印流可以方便且高效的打印各种数据。

6.7.1 PrintStream

打印流可以支持打印所有基本类型数据

final PrintStream ps = new PrintStream("src\\javaSE\\高级教程\\_11Stream流\\_03文件Stream流\\打印流\\print.txt");
        ps.println(11);
        ps.println(110);
        ps.println("aa我爱中国");
        ps.println(33.3);
        ps.println(false);
        ps.println('徐');
        ps.println("aa".getBytes());
        ps.close();
6.7.2 打印流重定向

我们通常在写程序的时候,有控制台,日志都是可以在控制台看见的,但是在服务器上是没有控制台的,所以我们在输出日志之前,将打印流重定向,就可以将打印的内容,记录在指定的文件内

final PrintStream ps = new PrintStream("src\\javaSE\\高级教程\\_11Stream流\\_03文件Stream流\\打印流\\print.txt");
        System.out.println("=====Demo01=====");
        System.out.println("=====Demo02=====");
// 打印流重定向 PrintStreamRedirection
        System.setOut(ps);
        System.out.println("=====Demo03=====");
        System.out.println("=====Demo04=====");
        System.out.println("=====Demo05=====");
        System.out.println("=====Demo06=====");
        System.out.println("=====Demo07=====");

6.8 序列化
6.8.1 对象序列化

对象序列化,该对象必须实现Serializable接口才能被序列化进文件,否则会报NotSerializableException异常

package javaSE.高级教程._11Stream流._03文件Stream流.对象序列化;

import java.io.Serializable;

public class Student implement Serializable {
    private String name;
    private String age;
    private String sex;
// 省略有参无参构造器、getter喝setter
// ...
}

// 准备序列化的对象
final Student student = new Student("李文杰", "22", "男");
// 建立文件输出流
        final FileOutputStream os = new FileOutputStream("src\\javaSE\\高级教程\\_11Stream流\\_03文件Stream流\\对象序列化\\serialize.dat");
// 建立对象序列化输出流 
        final ObjectOutputStream oos = new ObjectOutputStream(os);
// 写入
        oos.writeObject(student);
        oos.close();
        System.out.println("对象序列化成功!");

1、加入序列化版本号,来控制不同的序列化方式。但是在反序列化时,对象的序列号版本与序列化时的版本一致。否则会报错InvalidClassException异常错误

public class Student implement Serializable {
// 加入序列化版本号
    private static final long serialVersionUID = 1L;
    private String name;
    private String age;
    private String sex;
// 省略有参无参构造器、getter喝setter
// ...
}

2、如果不想将某个属性序列化,则可以使用transient修饰该私有变量

private transient String age;
6.8.2 对象反序列化

将对象的序列化文件读出来,此时对象内的序列化版本号必须与之前序列化的版本号一致。

/**
         * 对象反序列化
         */

        final FileInputStream is = new FileInputStream("src\\javaSE\\高级教程\\_11Stream流\\_03文件Stream流\\对象序列化\\serialize.dat");

        final ObjectInputStream ois = new ObjectInputStream(is);

//        默认使用Object类型,可以强转成Student类型
        final Student student = (Student) ois.readObject();

        System.out.println(student);

        System.out.println("反序列化成功!");
6.9 properties属性集文件
6.9.1 将属性写入属性集文件
public static void main(String[] args) throws Exception {

        // 1、创建一个属性集对象,Properties对象
        final Properties properties = new Properties();
        properties.setProperty("username", "lina");

        // 2、创建一个字节输出流
        final FileOutputStream os = new FileOutputStream("src\\javaSE\\高级教程\\_11Stream流\\_03文件Stream流\\properties属性文件\\user.properties");

    // 3、保存properties属性集文件 参数一: 字节输出流对象,参数二:说明
        properties.store(os, "保存properties属性");

//        properties会自动关闭字节输出流
    }
6.9.2 读取properties属性文件
public static void main(String[] args) throws Exception{
//        1、创建一个属性集对象
        final Properties properties = new Properties();
//        2、创建一个字节输出流 加载-> user.properties属性文件的数据 到-> 属性集对象properties中去
        properties.load(new FileInputStream("src\\javaSE\\高级教程\\_11Stream流\\_03文件Stream流\\properties属性文件\\user.properties"));

        System.out.println(properties.getProperty("username"));

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值