Java I/O流

I/O流

  • I/O流
  • IO流体系
    • 字节流体系
      • FileOutPutStream(字节输出流)
      • FileInPutStream(字节输入流)
      • 练习:文件拷贝
    • Java中编码与解码的方法
    • 字符流
      • FileReader
      • FileWriter
  • 综合练习
    • 缓冲流体系
      • 字节缓冲流
      • 字符缓冲流
  • 综合练习2
    • 转换流
    • 序列化流(对象操作输出流)/反序列化流(对象操作输入流)
    • 打印流
    • 解压缩流/压缩流
  • 常用工具包(Commons-io)
  • 常用工具包(hutool)
  • 综合练习3
    • 制造假数据(网络爬虫)
    • 随机点名器
    • 登录注册

I/O流

1、什么是IO流?
存储和读取数据的解决方案
I:input O:output
流:像水流一样传输数据
2、IO流的作用?
用于读写数据(本地文件,网络)
3、IO流按照流向可以分为哪两种流?
输出流:程序–>文件
输入流: 文件–>程序
4、IO按照操作文件的类型可以分类哪两种流?
字节流:可以操作所有类型的文件
字符流:只能操作纯文本文件
5、什么是纯文本文件?
用Windows系统自带的记事本打开并且能读懂的文件
txt文件,md文件,xml文件,lrc文件等

IO流体系

1、IO流体系
在这里插入图片描述

字节流体系

在这里插入图片描述

FileOutPutStream(字节输出流)

用法:操作本地文件的字节输出流,可以把程序中的数据写到本地文件中。

字节输出流的细节:
1、创建字节输出流对象

细节1:参数是字符串表示的路径或者是File对象都是可以的。
细节2:如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的。
细节3:如果文件已经存在,则会清空文件
2、写数据
细节:write方法的参数是整数,但是实际上写到本地文件中的是整数在ASCII上对应的字符
3、释放资源
每次使用完流之后都要释放资源
书写步骤:
1、创建字节输出流对象
2、写数据
3、释放资源

import java.io.FileOutputStream;
import java.io.IOException;
public class ByteStreamDemo1 {
    public static void main(String[] args) throws IOException {
        /*
        实现需求:写出一段文字到本地文件中。(暂时不写中文)
         */
        //1、创建对象
        //写出 输出流 OutPutStream
        //本地文件 File
        FileOutputStream fos = new FileOutputStream("D:\\Test\\untitled4\\a.txt");
        //2、写出数据
        fos.write(97);
        //3、释放资源
        fos.close();
    }
}
  • FileOutPutStream写数据的三种方式
    在这里插入图片描述
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteStreamDemo2 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("D:\\Test\\untitled4\\a.txt");
        //2、写出数据
//        fos.write(97);//a
//        fos.write(98);//b

        byte[] arr = {97,98,99,100,101};
        //fos.write(arr);//abcde

        /*
        参数1:数组
        参数2:起始索引 0
        参数3:个数
         */
        fos.write(arr,1,2);//bc
        //3、释放资源
        fos.close();
    }
}
  • 换行写和续写
    换行写:再次写出一个换行符
    Windows:\r\n
    Linux:\n
    Mac:\r
    细节:Windows操作系统中也可以只写\r或\n
    续写
    如果想要续写,打开续写开关即可
    开关位置:创建对象的第二个参数
    默认false:表示关闭续写,此时创建对象会清空文件
    手动传递true:表示打开续写,此时创建对象不会清空文件
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteStreamDemo3 {
    public static void main(String[] args) throws IOException {
        //1、创建对象
        FileOutputStream fos = new FileOutputStream
                ("D:\\Test\\untitled4\\a.txt",true);
        //2、写出数据
        String str = "abcdef";
        byte[] bytes1 = str.getBytes();
        fos.write(bytes1);
        //再次写出一个换行符就可以了
        String wrap = "\r\n";
        byte[] bytes2 = wrap.getBytes();
        fos.write(bytes2);

        String str2 = "666";
        byte[] bytes3 = str2.getBytes();
        fos.write(bytes3);
        //释放资源
        fos.close();
    }
}

FileInPutStream(字节输入流)

用法:操作本地文件的字节输入流,可以把本地文件中的数据读取到程序中来。
字节输入流的细节:
1、创建字节输入流对象
细节1:如果文件不存在,就直接报错
2、写数据
细节1:一次读一个文件,读出来的是数据在ASCII上对应的数字
细节2:读到文件末尾了,read方法返回-1.
3、释放资源
细节:每次使用完流之后都要释放资源

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteStreamDemo4 {
    public static void main(String[] args) throws IOException {
        /*
        实现需求:读取文件中的数据。(暂时不写中文)
         */
        FileInputStream fis = new FileInputStream("D:\\Test\\untitled4\\a.txt");
        //2、读取数据
        int i = fis.read();
        System.out.println(i);//97
        System.out.println((char) i);//a

        int i2 = fis.read();
        System.out.println(i2);//-1
        //3、释放资源
        fis.close();
    }
}
  • 字节输入流循环读取
import java.io.FileInputStream;
import java.io.IOException;
public class ByteStreamDemo5 {
    public static void main(String[] args) throws IOException {
        //1、创建对象
        FileInputStream fis = new FileInputStream("D:\\Test\\untitled4\\a.txt");
        int b;
        //循环读取
        //read表示读取数据,而且数读取一个数据就移动一次指针,
        // 因此需要第三方变量
        while ((b = fis.read()) != -1){
            System.out.print((char) b);
        }
        //3、释放资源
        fis.close();
    }
}
  • FileInputStream一次读多个字节
    在这里插入图片描述
    注意:一次读一个字节数组的数据,每次读取会尽可能把数组装满
import java.io.FileInputStream;
import java.io.IOException;
public class ByteStreamDemo6 {
    public static void main(String[] args) throws IOException {
        //1、创建对象
        FileInputStream fis = new FileInputStream("D:\\Test\\untitled4\\a.txt");
        //2、读取数据
        byte[] bytes = new byte[2];
        //一次读取多个字节数据,具体读多少,跟数组的长度有关
        //返回值:本次读取到了多少个字节数据
        int len1 = fis.read(bytes);
        System.out.println(len1);//2
        String str1 = new String(bytes,0,len1);
        System.out.println(str1);//ab
        //3、释放资源
        fis.close();
    }
}

练习:文件拷贝

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test1 {
    public static void main(String[] args) throws IOException {
        long start = System.currentTimeMillis();
        //1、创建对象
        FileInputStream fis = new FileInputStream("D:\\Test2\\d.txt");
        FileOutputStream fos = new FileOutputStream("D:\\Test\\untitled4\\copy.txt");
        //2、拷贝
        //核心思想:边读边写
        int len;
        byte[] bytes = new byte[1024];
        while ((len = fis.read()) != -1){
            fos.write(bytes,0,len);
        }
        //释放资源
        //规则:先开的最后关闭
        fos.close();
        fis.close();
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }
}

Java中编码与解码的方法

在这里插入图片描述
在这里插入图片描述

import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class ByteStreamDemo7 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        //1、编码
        String str = "ai你哟";
        byte[] bytes1 = str.getBytes();
        System.out.println(Arrays.toString(bytes1));

        byte[] bytes2 = str.getBytes("GBK");
        System.out.println(Arrays.toString(bytes2));

        //2、解码
        String str2 = new String(bytes1);
        System.out.println(str2);

        String str3 = new String(bytes2,"GBK");
        System.out.println(str3);
    }
}

字符流

在这里插入图片描述

  • 字符流的底层其实就是字节流
    字符流 = 字节流 + 字符集
    特点:
    输入流:一次读一个字节,遇到中文时,一次读多个字节
    输出流:底层会把数据按照指定的编码方式进行编码,变成字节再写到文件中
    使用场景:
    对于纯文本文件进行读写操作

FileReader

1、创建字符输入流对象
在这里插入图片描述
细节1:如果文件不存在,就直接报错
2、读取数据
在这里插入图片描述
细节1:按字节进行读取,遇到中文,一次读多个字节,读取后解码,返回一个整数
细节2:读到文件末尾了,read方法返回-1。
3、释放资源

空参的read方法

import java.io.FileReader;
import java.io.IOException;
public class CharStreamDemo1 {
    public static void main(String[] args) throws IOException {
        //1、创建对象并关联本地文件
        FileReader fr = new FileReader("D:\\Test\\untitled4\\a.txt");
        //2、读取数据 read()
        //字符流的底层也是字节流,默认也是一个字节一个字节的读取的。
        // 如果遇到中文就会一次读取多个,GBK一次读两个字节,UTF-8一次读三个字节
        /*
        read()细节:
        1、read():默认也是一个字节一个字节的读取的,如果遇到中文就会一次读取多个
        2、在读取之后,方法的底层还会进行解码并转成十进制。
        最终把这个十进制作为返回值
        这个十进制的数据也表示在字符集上的数字
        英文:文件里面二进制数据 0110 0001
             read方法进行读取,解码并转成十进制97
        中文:文件里面的二进制数据 11100110 10110001 10001001
             read方法进行读取,解码并转成十进制27721
        要看到中文,需要进行强制类型转换
         */
        int ch;
        while (((ch = fr.read())) != -1){
            System.out.print((char) ch);
        }
        fr.close();
    }
}

带参的read方法

import java.io.FileReader;
import java.io.IOException;
public class CharStreamDemo2 {
    public static void main(String[] args) throws IOException {
        //1、创建对象
        FileReader fr = new FileReader("D:\\Test\\untitled4\\a.txt");
        //2、读取数据
        char[] chars = new char[2];
        int len;
        //read(chars): 读取数据,解码,强转三步合并了,把强转之后的字符放到数组当中
        //空参的read + 强转类型转换
        while ((len = fr.read(chars)) != -1){
            //把数组中的数据变成字符串再进行打印
            System.out.print(new String(chars,0,len));
        }
        //3、释放资源
        fr.close();
    }
}

FileWriter

构造方法:
在这里插入图片描述
成员方法:
在这里插入图片描述
FileWriter书写细节:

  1. 创建字符输出流对象
    细节1:参数是字符串表示的路径或者File对象都是可以的
    细节2:如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的
    细节3:如果文件已经存在,则会清空文件,如果不想清空文件可以打开续写开关
  2. 写数据
    细节:如果write方法的参数是整数,但是实际上写到本地文件中的是整数在字符集上对应的字符
  3. 释放资源
    细节:每次使用完流之后都要释放资源
import java.io.FileWriter;
import java.io.IOException;
public class CharStreamDemo3 {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter
                ("D:\\Test\\untitled4\\a.txt",true);

        //fw.write(25105);//我
        //fw.write("你好啊!");//你好啊!
        //fw.write("你好啊!",0,2);//你好
        char[] chars = {'a','b','c','我'};
        //fw.write(chars);abc我
        fw.write(chars,0,2);//ab

        fw.close();
    }
}

综合练习

1、拷贝一个文件夹,考虑子文件夹

import java.io.*;
public class Test2 {
    public static void main(String[] args) throws IOException {
        //1、创建对象表示数据源
        File src = new File("D:\\Test2\\ccc");
        //2、创建对象表示目的地
        File dest = new File("D:\\Test2\\aaa");
        //3、调用方法开始拷贝
        copydir(src,dest);
    }

    /*
    作用:拷贝文件
    参数一:数据源
    参数二:目的地
     */
    private static void copydir(File src,File dest) throws IOException {
        dest.mkdirs();
        //1、进入数据源
        File[] files = src.listFiles();
        //2、遍历数组
        for (File file : files) {
            if(file.isFile()){
                //3、判断文件,拷贝
                FileInputStream fis = new FileInputStream(file);
                FileOutputStream fos = new FileOutputStream(new File(dest,file.getName()));
                byte[] bytes = new byte[1024];
                int len;
                while ((len = fis.read(bytes)) != -1){
                    fos.write(bytes,0,len);
                }
                fos.close();
                fis.close();
            }else {
                //4、判断文件夹,递归
                copydir(file,new File(dest,file.getName()));
            }
        }
    }
}

2、文件加密
为了保证文件的安全性,就需要对原始文件进行加密存储,再使用的时候再对其进行解密处理。
加密原理:对原始文件中的每一个字节数据进行更改,然后将更改以后的数据存储到新的文件中。
解密原理:读取加密之后的文件,按照加密的规则反向操作,变成原始文件。

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test3 {
    public static void main(String[] args) throws IOException {
        //1、创建对象关联原始文件
        FileInputStream fis = new FileInputStream("D:\\Test2\\a.txt");
        //2、创建对象关联加密文件
        FileOutputStream fos = new FileOutputStream("D:\\Test2\\b.txt");
        //3、加密处理
        int b;
        while ((b = fis.read()) != -1){
            fos.write(b ^ 2);
        }
        //4、释放资源
        fos.close();
        fis.close();
    }
}

3、修改文件中的数据
文本文件中有以下的数据:
2-1-9-4-7-8
将文件中的数据进行排序,变成以下数据:
1-2-4-7-8-9

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
public class Test4 {
    //细节1:文件中的数据不要换行
    //细节2:不带bom头
    public static void main(String[] args) throws IOException {
        //1、读取数据
        FileReader fr = new FileReader("D:\\Test\\untitled4\\a.txt");
        StringBuilder sb = new StringBuilder();
        int len;
        while ((len = fr.read()) != -1){
            sb.append((char) len);
        }
        fr.close();
        System.out.println(sb);
        //2、排序
        Integer[] arr = Arrays.stream(sb.toString()
                        .split("-"))
                .map(Integer::parseInt)
                .sorted()
                .toArray(Integer[]::new);
//        String str = sb.toString();
//        String[] arrStr = str.split("-");
//
//        ArrayList<Integer> list = new ArrayList<>();
//        for (String s : arrStr) {
//            int i = Integer.parseInt(s);
//            list.add(i);
//        }
//        Collections.sort(list);
//        System.out.println(list);
        //写出
        FileWriter fw = new FileWriter("D:\\Test\\untitled4\\a.txt");
        String s = Arrays.toString(arr).replace(", ","-");
        String result = s.substring(1, s.length() - 1);
        fw.write(result);
        fw.close();
//        FileWriter fw = new FileWriter("D:\\Test\\untitled4\\a.txt");
//        for (int i = 0; i < list.size(); i++) {
//            if(i == list.size() - 1){
//                fw.write(list.get(i) + "");
//            }else {
//                fw.write(list.get(i) + "-");
//            }
//        }
//        fw.close();
    }
}

缓冲流体系

在这里插入图片描述

字节缓冲流

在这里插入图片描述
在这里插入图片描述
需求:利用字节缓冲流拷贝文件

import java.io.*;
public class BufferedStreamDemo1 {
    public static void main(String[] args) throws IOException {
        //1、创建缓冲流对象
        BufferedInputStream bis = new BufferedInputStream
                (new FileInputStream("D:\\Test\\untitled4\\a.txt"));
        BufferedOutputStream bos = new BufferedOutputStream
                (new FileOutputStream("D:\\Test\\untitled4\\copy2.txt"));
        //2、循环读取并写到目的地(一次读写多个字节)
        byte[] bytes = new byte[1024];
        int len;
        while ((len = bis.read(bytes)) != -1){
            bos.write(bytes,0,len);
        }
//        int b;
//        while ((b = bis.read()) != -1){
//            bos.write(b);
//        }
        //3、释放资源
        bos.close();
        bis.close();
    }
}

字符缓冲流

在这里插入图片描述
在这里插入图片描述

  • 字符缓冲流特有方法
    在这里插入图片描述
    在这里插入图片描述
  • 字符缓冲输入流
import java.io.*;
public class BufferedStreamDemo2 {
    public static void main(String[] args) throws IOException {
        //1、创建字符缓冲输入流对象
      BufferedReader br = new BufferedReader
              (new FileReader("D:\\Test\\untitled4\\a.txt"));
        //2、读取数据
        String line;
        while (((line = br.readLine()) != null)){
            System.out.println(line);
        }
        //3、释放资源
        br.close();
    }
}
  • 字符缓冲输出流
import java.io.*;
public class BufferedStreamDemo3 {
    public static void main(String[] args) throws IOException {
        //1、创建字符缓冲输出流对象(开启续写)
        BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt",true));
        //2、写入数据
        bw.write("张三");
        bw.newLine();//换行
        bw.write("李四");
        //3、释放资源
        bw.close();
    }
}

综合练习2

1、修改文本顺序
需求:把《出师表》的文章顺序进行恢复到一个新文件中
方式1:

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class Test5 {
    public static void main(String[] args) throws IOException {
        //1、读取数据
        BufferedReader br = new BufferedReader
                (new FileReader("D:\\Test\\untitled4\\csb.txt"));
        String line;
        ArrayList<String> list = new ArrayList<>();
        while ((line = br.readLine())!= null){
            list.add(line);
        }
        br.close();
        //2、排序
        //排序规则:按照每一行前面的序号进行排序
        Collections.sort(list, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                //获取o1和o2的序号
                int i1 = Integer.parseInt(o1.split("\\.")[0]);
                int i2 = Integer.parseInt(o2.split("\\.")[0]);
                return i1 - i2;
            }
        });
        //3、写出
        BufferedWriter bw = new BufferedWriter
                (new FileWriter("D:\\Test\\untitled4\\result.txt"));
        for (String str : list) {
            bw.write(str);
            bw.newLine();
        }
        bw.close();
    }
}

方式2:

import java.io.*;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class Test5_2 {
    public static void main(String[] args) throws IOException {
        //1、读取数据
        BufferedReader br = new BufferedReader
                (new FileReader("D:\\Test\\untitled4\\csb.txt"));
        String line;
        TreeMap<Integer,String> tm  = new TreeMap<>();
        while ((line = br.readLine()) != null){
            String[] arr = line.split("\\.");
            //0:序号   1:内容
            tm.put(Integer.parseInt(arr[0]),arr[1]);
        }
        br.close();
        //2、写出数据
        BufferedWriter bw = new BufferedWriter
                (new FileWriter("D:\\Test\\untitled4\\result2.txt"));
        Set<Map.Entry<Integer,String>> entries = tm.entrySet();
        for (Map.Entry<Integer, String> entry : entries) {
            String value = entry.getValue();
            bw.write(value);
            bw.newLine();
        }
        bw.close();
    }
}

2、软件运行次数
实现一个验证程序运行次数的小程序,要求如下:
1、当程序运行超过3次时给出提示:本软件只能免费使用3次,欢迎您注册会员后继续使用~
2、程序运行演示如下:
第一次运行控制台输出:欢迎使用本软件,第1次使用免费~
第二次运行控制台输出:欢迎使用本软件,第2次使用免费~
第三次运行控制台输出:欢迎使用本软件,第3次使用免费~
第四次以及之后运行控制台输出:本软件只能免费使用3次,欢迎您注册会员后继续使用~

import java.io.*;
public class Test6 {
    public static void main(String[] args) throws IOException {
        //1、把文件中的数字读取到内存中
        //原则:IO:随用随创建,什么时候不用,什么时候关闭
        BufferedReader br = new BufferedReader
                (new FileReader("D:\\Test\\untitled4\\count.txt"));
        String line = br.readLine();
        br.close();
        int count = Integer.parseInt(line);
        //表示当前软件又运行了一次
        count++;
        //2、判断
        if(count <= 3){
            System.out.println("欢迎使用本软件,第" + count + "次使用免费~");
        }else {
            System.out.println("本软件只能免费使用3次,欢迎您注册会员后继续使用~");
        }
        //3、把当前自增之后的count写出到文件当中
        BufferedWriter bw = new BufferedWriter
                (new FileWriter("D:\\Test\\untitled4\\count.txt"));
        bw.write(count + "");
        bw.close();
    }
}

转换流

  • 转换流是字符流和字节流之间的桥梁
  • 作用:字节流想要字符流中的方法

1、利用转换流按照指定的字符编码读取(了解)

import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
public class ConvertStreamDemo1 {
    public static void main(String[] args) throws IOException {
        //JDK11的替代方案
        FileReader fr = new FileReader
                ("D:\\Test\\untitled4\\gbkfile.txt", Charset.forName("GBK"));
        //2、读取数据
        int ch;
        while ((ch = fr.read()) != -1){
            System.out.println((char)ch);
        }
        //3、释放资源
        fr.close();

//        //1、创建对象并指定字符编码
//        InputStreamReader isr = new InputStreamReader
//                (new FileInputStream("D:\\Test\\untitled4\\gbkfile.txt"),"GBK");
//        //2、读取数据
//        int ch;
//        while ((ch = isr.read()) != -1){
//            System.out.println((char)ch);
//        }
//        //3、释放资源
//        isr.close();
    }
}

2、利用转换流按照指定字符编码写出

import java.io.*;
import java.nio.charset.Charset;
public class ConvertStreamDemo2 {
    public static void main(String[] args) throws IOException {
        //JDK11的替代方案
        FileWriter fw = new FileWriter
                ("D:\\Test\\untitled4\\c.txt", Charset.forName("GBK"));
        //2、写出数据
        fw.write("你好");
//        //3、释放资源
        fw.close();
//       //1、创建转换流对象
//        OutputStreamWriter osw = new OutputStreamWriter
//                (new FileOutputStream("D:\\Test\\untitled4\\b.txt"),"GBK");
//        //2、写出数据
//        osw.write("你好");
//        //3、释放资源
//        osw.close();
    }
}

3、将本地文件中的GBK文件,转成UTF-8

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.Charset;
public class ConvertStreamDemo3 {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader
                ("D:\\Test\\untitled4\\b.txt",Charset.forName("GBK"));
        FileWriter fw = new FileWriter
                ("D:\\Test\\untitled4\\d.txt",Charset.forName("UTF-8"));
        int b;
        while ((b = fr.read()) != -1){
            fw.write(b);
        }
        fw.close();
        fr.close();
    }
}

4、利用字节流读取文件中的数据,每次读一行,而且不能乱码

import java.io.*;
public class ConvertStreamDemo4 {
    public static void main(String[] args) throws IOException {
//        FileInputStream fis = new FileInputStream("D:\\Test\\untitled4\\d.txt");
//        InputStreamReader isr = new InputStreamReader(fis);
//        BufferedReader br = new BufferedReader(isr);
        BufferedReader br = new BufferedReader
                (new InputStreamReader(
                        new FileInputStream("D:\\Test\\untitled4\\d.txt")));
        String line;
        while ((line = br.readLine()) != null){
            System.out.println(line);
        }
        br.close();
    }
}

序列化流(对象操作输出流)/反序列化流(对象操作输入流)

  • 序列化流
    作用:可以把Java中的对象写到本地文件中
    在这里插入图片描述
    细节:需要让Javabean类实现Serializable接口。Serializable接口里面没有抽象方法,是一个标记型接口,一旦实现了这个接口,那么就表示当前的类可以被序列化。
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class ObjectStreamDemo1 {
    public static void main(String[] args) throws IOException {
        //1、创建对象
        Student stu = new Student("zhangsan",23);
        //2、创建序列化流的对象
        ObjectOutputStream oos = new ObjectOutputStream
                (new FileOutputStream("D:\\Test\\untitled4\\a.txt"));
        //3、写出数据
        oos.writeObject(stu);
        //4、释放资源
        oos.close();
    }
}
  • 反序列化流
    作用:可以把序列化到本地文件中的对象,读取到程序中来
    在这里插入图片描述
import java.io.*;
public class ObjectStreamDemo2 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //1、创建反序列化流的对象
        ObjectInputStream ois = new ObjectInputStream
                (new FileInputStream("D:\\Test\\untitled4\\a.txt"));
        //2、读取数据
        Object o = (Student)ois.readObject();
        //3、打印对象
        System.out.println(o);
        //4、释放资源
        ois.close();
    }
}
  • 细节:
    1、需要在JavaBean类中加上版本号
    如: private static final long serialVersionUID = 1L;
    2、transient:瞬态关键字
    作用:加在变量名前面,不会把当前属性序列化到本地文件当中
    如:private transient String address;

  • 练习:将多个自定义对象序列化到文件中,但是由于对象的个数不确定,反序列化流该如何读取呢?

序列化流:

import java.io.*;
import java.util.ArrayList;
public class Test7 {
    public static void main(String[] args) throws IOException {
        //1、序列化多个对象
        Student s1 = new Student("zhangsan",23,"北京");
        Student s2 = new Student("lisi",24,"上海");
        Student s3 = new Student("wangwu",25,"广州");

        ArrayList<Student> list = new ArrayList<>();
        list.add(s1);
        list.add(s2);
        list.add(s3);
        ObjectOutputStream oos = new ObjectOutputStream
                (new FileOutputStream("D:\\Test\\untitled4\\a.txt"));
        oos.writeObject(list);
        oos.close();
    }
}

反序列化流:

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
public class Test8 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //1、创建反序列化流的对象
        ObjectInputStream ois = new ObjectInputStream
                (new FileInputStream("D:\\Test\\untitled4\\a.txt"));
        //2、读取数据
        ArrayList<Student> list = (ArrayList<Student>) ois.readObject();

        for (Student student : list) {
            System.out.println(student);
        }
        //3、释放资源
        ois.close();
    }
}

打印流

  • 分类:打印流一般是指:PrintStream,PrintWriter两个类

  • 特点1:打印流只操作文件目的地,不操作数据源

  • 特点2:特有的写出方法可以实现,数据原样写出

  • 特点3:特有的写出方法,可以实现自动刷新,自动换行
    打印一次数据 = 写出 + 换行 + 刷新

  • 字节打印流
    在这里插入图片描述
    注意:字节流底层没有缓冲区,开不开自动刷新都一样
    在这里插入图片描述

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
public class PrintStreamDemo1 {
    public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
        //1、创建字节打印流的对象
        PrintStream ps = new PrintStream
                (new FileOutputStream("D:\\Test\\untitled4\\a.txt")
                        ,true, Charset.forName("UTF-8"));
        //2、写出数据
        ps.println(97);//97
        ps.print(true);//true
        ps.println();
        ps.printf("%s","你好");//你好
        //3、释放资源
        ps.close();
    }
}
  • 字符打印流
    在这里插入图片描述
    注意:字符流底层有缓冲区,想要自动刷新需要开启。
    在这里插入图片描述
import java.io.*;
public class PrintStreamDemo2 {
    public static void main(String[] args) throws IOException {
        //1、创建字符打印流对象
        PrintWriter pw = new PrintWriter
                (new FileWriter("D:\\Test\\untitled4\\a.txt")
                        ,true);
        //2、写出数据
        pw.println(97);
        pw.print("true");
        pw.println();
        pw.printf("%s","你好");
        //3、释放资源
        pw.close();
    }
}
  • 打印流的应用场景
import java.io.PrintStream;
public class PrintStreamDemo3 {
    public static void main(String[] args){
        //获取打印流的对象,此打印流在虚拟机启动的时候,由虚拟机创建,默认指向控制台
        //特殊的打印流,系统中的标准输出流,是不能关闭,在系统中是唯一的
        PrintStream ps = System.out;
        //调用打印流中的方法println
        //写出数据,自动换行,自动刷新
        ps.println("123");
        //ps.close();//不能关闭,否则后面的语句将不能输出
        ps.println("你好");
        System.out.println("456");
    }
}

解压缩流/压缩流

解压本质:把每一个ZipEntry按照层级拷贝到本地另一个文件夹中

  • 解压缩流
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class ZipStreamDemo1 {
    public static void main(String[] args) throws IOException {
        //1、创建一个File表示要解压的压缩包
        File src = new File("D:\\Test2\\aaa.zip");
        //2、创建一个File表示解压的目的地
        File dest = new File("D:\\");
        //调用方法
        unzip(src, dest);
    }

    //定义一个方法用来解压
    public static void unzip(File src, File dest) throws IOException {
        //解压的本质:把压缩包里面的每一个文件或者文件夹读取出来,按照层级拷贝到目的地当中
        //创建一个解压缩流用来读取压缩包中的数据
        ZipInputStream zip = new ZipInputStream(new FileInputStream(src));
        //要先获取压缩包里面的每一个zipentry对象
        //表示当前在压缩包中获取到的文件或者文件夹
        ZipEntry entry;
        while ((entry = zip.getNextEntry()) != null) {
            System.out.println(entry);
            if (entry.isDirectory()) {
                //文件夹:需要在目的地的dest处创建一个同样的文件夹
                File file = new File(dest,entry.toString());
                file.mkdirs();
            } else {
                //文件:需要读取到压缩包中的文件,并把他存放到目的地dest文件夹中(按照层级目录进行存放)
                FileOutputStream fos = new FileOutputStream(new File(dest,entry.toString()));
                int b;
                while ((b = zip.read()) != -1){
                    //写到目的地
                    fos.write(b);
                }
                fos.close();
                //表示在压缩包中的一个文件处理完毕了
                zip.closeEntry();
            }
        }
        zip.close();
    }
}
  • 压缩流
    压缩本质:把每一个(文件/文件夹)看成ZipEntry对象放到压缩包中

压缩单个文件

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipStreamDemo2 {
    public static void main(String[] args) throws IOException {
        //1、创建File对象表示要压缩的文件
        File src = new File("D:\\Test2\\a.txt");
        //2、创建File对象表示压缩包的位置
        File dest = new File("D:\\Test2\\");
        //3、调用方法用来压缩
        tozip(src,dest);
    }

    /*
    作用:压缩
    参数一:表示要压缩的文件
    参数二:表示压缩包的位置
     */
    public static void tozip(File src, File dest) throws IOException {
        //1、创建压缩流关联压缩包
        ZipOutputStream zos = new ZipOutputStream
                (new FileOutputStream(new File(dest,"a.zip")));
        //2、创建ZipEntry对象,表示压缩包里面的每一个文件和文件夹
        ZipEntry entry = new ZipEntry("a.txt");
        //3、把ZipEntry对象放到压缩包当中
        zos.putNextEntry(entry);
        //4、把src文件中的数据写到压缩包当中
        FileInputStream fis = new FileInputStream(src);
        int b;
        while ((b = fis.read()) != -1){
            zos.write(b);
        }
        zos.closeEntry();
        zos.close();
    }
}

压缩文件夹

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipStreamDemo3 {
    public static void main(String[] args) throws IOException {
        //1、创建File对象表示要压缩的文件夹
        File src = new File("D:\\Test2\\bbb");
        //2、创建File对象表示压缩包放在哪里(压缩包的父级路径)
        File destParent = src.getParentFile();
        //3、创建File对象表示压缩包的路径
        File dest = new File(destParent,src.getName() + ".zip");
        //4、创建压缩流关联的压缩包
        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(dest));
        //5、获取src里面的每一个文件,变成ZipEntry对象,放入到压缩包当中
        toZip(src,zos,src.getName());
        //6、释放资源
        zos.close();
    }
    /*
    作用:获取src里面的每一个文件,变成ZipEntry对象,放入到压缩包当中
    参数一:数据源
    参数二:压缩流
    参数三:压缩包内部的路径
     */
    public static void toZip(File src,ZipOutputStream zos,String name) throws IOException {
        //1、进入src文件夹
        File[] files = src.listFiles();
        //2、遍历数组
        for (File file : files) {
            if(file.isFile()){
                //3、判断-文件,变成ZipEntry对象,放入压缩包当中
                ZipEntry entry = new ZipEntry(name + "\\" + file.getName());
                zos.putNextEntry(entry);
                //读取文件中的数据,写到压缩包
                FileInputStream fis = new FileInputStream(file);
                int b;
                while ((b = fis.read()) != -1){
                    zos.write(b);
                }
                fis.close();
                zos.closeEntry();
            }else {
                //4、判断-文件夹,递归
                toZip(file,zos,name + "\\" + file.getName());
            }
        }
    }
}

常用工具包(Commons-io)

Commons-io是apache开源基金组织提供的一组有关IO操作的开源工具包。

  • 作用:提高IO流的开发效率。
    使用步骤
    1、在项目中创建一个文件夹:lib
    2、将jar包复制粘贴到lib文件夹
    3、右键点击jar包,选择Add as Library -> 点击OK
    4、在类中导包使用
    下载该工具包网址
    在这里插入图片描述
    在这里插入图片描述
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
public class CommonsIODemo1 {
    public static void main(String[] args) throws IOException {
        //复制文件
//        File src = new File("D:\\Test\\untitled4\\a.txt");
//        File dest = new File("D:\\Test\\untitled4\\copy.txt");
//        FileUtils.copyFile(src,dest);
        //复制文件夹
//        File src = new File("D:\\Test2\\aaa");
//        File dest = new File("D:\\Test2\\bbb");
//        FileUtils.copyDirectoryToDirectory(src,dest);
        //清空文件夹
        File src = new File("D:\\Test2\\bbb");
        FileUtils.cleanDirectory(src);
    }
}

常用工具包(hutool)

hutool jar包下载网址
在这里插入图片描述

import cn.hutool.core.io.FileUtil;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class HutoolDemo1 {
    public static void main(String[] args) {
        /*
        //file:根据参数创建一个file对象
        File file = FileUtil.file("D:\\Test2\\","aaa","bbb","a.txt");
        System.out.println(file);//D:\Test2\aaa\bbb\a.txt
        //touch:根据参数创建文件
        File touch = FileUtil.touch(file);
        System.out.println(touch);
        //writeLines:把集合中的数据写出到文件中,覆盖模式
        ArrayList<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("aaa");
        list.add("aaa");
        File file1 = FileUtil.writeLines(list,"D:\\Test2\\a.txt","UTF-8");
        System.out.println(file1);
        //appendLines:把集合中的数据写出到文件中,续写模式
        ArrayList<String> list1 = new ArrayList<>();
        list1.add("bbb");
        list1.add("bbb");
        list1.add("bbb");
        File file2 = FileUtil.appendLines(list,"D:\\Test2\\a.txt","UTF-8");
        System.out.println(file2);
        */
        //readLines:指定字符编码,把文件中的数据,读到集合中
        List<String> list = FileUtil.readLines("D:\\Test2\\a.txt", "UTF-8");
        System.out.println(list);
    }
}

综合练习3

制造假数据(网络爬虫)

需求:在网络上爬取数据,生成随机的姓名,年龄,并写入文件中

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test9 {
    public static void main(String[] args) throws IOException {
        //1、定义变量记录网址
        String familyNameNet = "https://hanyu.baidu.com/shici/detail?" +
                "pid=0b2f26d4c0ddb3ee693fdb1137ee1b0d&from=kg0";
        String boyNameNet = "http://www.haoming8.cn/baobao/10881.html";
        String girlNameNet = "http://www.haoming8.cn/baobao/7641.html";
        //2、爬取数据,把网址上所有的数据拼接成一个字符串
        String familyNameNetStr = webCrawler(familyNameNet);
        String boyNameNetStr = webCrawler(boyNameNet);
        String girlNameNetStr = webCrawler(girlNameNet);

        //3、通过正则表达式,把其中符合要求的数据获取出来
        ArrayList<String> familyNameTempList = getData(familyNameNetStr,"(.{4})(,|。)",1);
        ArrayList<String> boyNameTempList = getData(boyNameNetStr, "([\\u4E00-\\u9FA5]{2})(、|。)", 1);
        ArrayList<String> girlNameTempList = getData(girlNameNetStr, "(.. ){4}..", 0);
//        System.out.println(boyNameTempList);
//        System.out.println(girlNameTempList);
        //4、处理数据
        //familyNameTempList(姓氏)
        //处理方案:把每一个姓氏拆开并添加到一个新集合当中
        ArrayList<String> familyNameList = new ArrayList<>();
        for (String str1 : familyNameTempList) {
            for (int i = 0; i < str1.length(); i++) {
                char c = str1.charAt(i);
                familyNameList.add(c + "");
            }
        }
        //boyNameTempList(男生的名字)
        //处理方案:去除其中的重复元素
        ArrayList<String> boyNameList = new ArrayList<>();
        for (String str2 : boyNameTempList) {
            if (!boyNameList.contains(str2)) {
                boyNameList.add(str2);
            }
        }
        //girlNameTempList(女生的名字)
        //处理方案:把里面的每一个元素用空格进行切割,得到每一个女生的名字
        ArrayList<String> girlNameList = new ArrayList<>();
            for (String str3 : girlNameTempList) {
                String[] arr = str3.split(" ");
                for (int i = 0; i < arr.length; i++) {
                    girlNameList.add(arr[i]);
                }
            }
        //5、生成数据
        //姓名(唯一)-性别-年龄
        ArrayList<String> list = getInfos(familyNameList, boyNameList,
                girlNameList, 50, 50);
            Collections.shuffle(list);
        //6、写出数据
        BufferedWriter bw = new BufferedWriter(
                new FileWriter("D:\\Test\\untitled4\\name.txt"));
        for (String str : list) {
            bw.write(str);
            bw.newLine();
        }
        bw.close();
    }
        /*
        作用:获取男生和女生的信息:张三-男-23
        形参:
        参数一:装着姓氏的集合
        参数二:装着男生名字的集合
        参数三:装着女生名字的集合
        参数四:男生的个数
        参数五:女生的个数
         */
    public static ArrayList<String> getInfos(ArrayList<String> familyNameList,
                                             ArrayList<String> boyNameList,
                                             ArrayList<String> girlNameList,
                                             int boyCount, int girlCount){
        //1、生成男生不重复的名字
        HashSet<String> boyhs = new HashSet<>();
        while (true){
            if(boyCount == boyhs.size()){
                break;
            }
            //随机
            Collections.shuffle(familyNameList);
            Collections.shuffle(boyNameList);
            boyhs.add(familyNameList.get(0) + boyNameList.get(0));
        }

        HashSet<String> girlshs = new HashSet<>();
        while (true){
            if(girlCount == girlshs.size()){
                break;
            }
            //随机
            Collections.shuffle(familyNameList);
            Collections.shuffle(girlNameList);
            girlshs.add(familyNameList.get(0) + girlNameList.get(0));
        }
        ArrayList<String> list = new ArrayList<>();
        //3、生成男生的信息并添加到集合当中
        Random r = new Random();
        //【18-27】
        for (String boyName : boyhs) {
            //boyName依次表示每一个男生的名字
            int age = r.nextInt(10) + 18;
            list.add(boyName + "-男-" + age);
        }
        //4、生成女生的信息并添加到集合当中
        //【18-25】
        for (String girlName : girlshs) {
            int age = r.nextInt(8) + 18;//(0~7 +18)
            list.add(girlName + "-女-" + age);
        }
        return list;
    }
    /*
    作用:根据正则表达式获取字符串中的数据
    参数一:完整的字符串
    参数二:正则表达式
    返回值:真正想要的数据
     */
    private static ArrayList<String> getData(String str,String regex,int index){
        //1、创建集合存放数据
        ArrayList<String> list = new ArrayList<>();
        //2、按照正则表达式的规则,去获取数据
        Pattern pattern = Pattern.compile(regex);
        //按照pattern的规则,到str当中获取数据
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()){
            list.add(matcher.group(index));
        }
        return list;
    }
    /*
    作用:从网络中爬取数据,把数据拼接成字符串返回
    形参:网址
    返回值:爬取到的所有数据
     */
    public static String webCrawler(String net) throws IOException {
        //1、定义StringBuilder拼接爬取到的数据
        StringBuilder sb = new StringBuilder();
        //2、创建一个URL对象
        URL url = new URL(net);
        //3、链接上这个网址
        //细节:保证网络是畅通的,而且这个网址是可以链接上的。
        URLConnection conn = url.openConnection();
        //4、读取数据
        InputStreamReader isr = new InputStreamReader(conn.getInputStream());
        int ch;
        while ((ch = isr.read()) != -1){
            sb.append((char)ch);
        }
        //5、释放资源
        isr.close();
        //6、把读取到的数据返回
        return sb.toString();
    }
}

随机点名器

TxT文件中事先准备好一些学生信息,每个学生的信息独占一行。
要求:每次被点到的学生,再次被点到的概率在原先的基础上降低一半。
举例:80个学生,点名5次,每次都点到小A,概率变化情况如下:
第一次每人概率:1.25%。
第二次小A概率:0.625%。其他学生概率:1.2579%
第三次小A概率:0.3125%。其他学生概率:1.261867%
第四次小A概率:0.15625%。其他学生概率:1.2638449%
第五次小A概率:0.078125%。其他学生概率:1.26483389%
提示:本题的核心是带权重的随机

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
public class Test10 {
    public static void main(String[] args) throws IOException {
        ArrayList<Student> list = new ArrayList<>();
        BufferedReader br = new BufferedReader
                (new FileReader("D:\\Test\\untitled4\\name.txt"));
        String line;
        while ((line = br.readLine()) != null){
            String[] arr = line.split("-");
            Student stu = new Student(arr[0],arr[1],
                    Integer.parseInt(arr[2]),Double.parseDouble(arr[3]));
            list.add(stu);
        }
        br.close();
        //2、计算权重的总和
        double weight = 0;
        for (Student stu : list) {
            weight += stu.getWeight();
        }
        //3、计算每一个人的实际占比
        double[] arr = new double[list.size()];
        int index = 0;
        for (Student stu : list) {
            arr[index] = stu.getWeight() / weight;
            index++;
        }
        //4、计算每一个人的权重占比范围
        for (int i = 1; i < arr.length; i++) {
            arr[i] = arr[i] + arr[i - 1];
        }
        //5、随机抽取
        //获取0~1.0之间的随机数
        double number = Math.random();
        //判断number在arr中的位置
        //二分查找法
        //方法会返回 -插入点-1
        //获取number这个数据在数组当中插入的位置
        int result = -Arrays.binarySearch(arr,number) - 1;
        Student stu = list.get(result);
        System.out.println(stu);
        //6、修改当前学生的权重
        double w = stu.getWeight() / 2;
        stu.setWeight(w);
        //7、把集合中的数据再次写到文件中
        BufferedWriter bw = new BufferedWriter
                (new FileWriter("D:\\Test\\untitled4\\name.txt"));
        for (Student s : list) {
            bw.write(s.toString());
            bw.newLine();
        }
        bw.close();
    }
}

登录注册

需求:写一个登录小案例
步骤:
1、将正确的用户名和密码手动保存到本地的userinfo.txt文件中
2、保存格式为:username=zhangsan&password=123
3、让用户键盘录入用户名和密码
4、比较用户录入的和正确的用户名密码是否一致
5、如果一致则打印登录成功
6、如果不一致则打印失败

import java.io.*;
import java.util.Scanner;
public class Test11 {
    public static void main(String[] args) throws IOException {
        //1、读取正确的用户名和密码
        BufferedReader br = new BufferedReader
                (new FileReader("D:\\Test\\untitled4\\userinfo.txt"));
        String line = br.readLine();
        br.close();
        String[] userInfo = line.split("&");
        String[] arr1 = userInfo[0].split("=");
        String[] arr2 = userInfo[1].split("=");

        String rightUsername = arr1[1];
        String rightPassword = arr2[1];
        //2、用户键盘录入用户名和密码
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用户名");
        String username = sc.nextLine();
        System.out.println("请输入密码");
        String password = sc.nextLine();
        //3、比较
        if(rightUsername.equals(username) && rightPassword.equals(password)){
            System.out.println("登录成功");
        }else {
            System.out.println("登录失败");
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/7888.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

小白必看,吐血整理Facebook新手指南(一)

Facebook广告是营销人员工具包中最强大的工具。脸书广告可以帮助你实现几个高层次的商业目标&#xff0c;包括提高品牌知名度&#xff0c;产生线索&#xff0c;为你的商业网站带来流量&#xff0c;等等。本指南将帮助你创建你的第一个Facebook广告活动。它还将提供经过验证的技…

全链路追踪系统在技术运营层面的应用

随着微服务和分布式架构的引入&#xff0c;各类应用和基础组件形成了网状的分布式调用关系&#xff0c;这种复杂的调用关系就大大增加了问题定位、瓶颈分析、容量评估以及限流降级等稳定性保障工作的难度。正是这样的背景&#xff0c;催生了全链路追踪的解决方案。 这里的一个…

java版工程项目管理系统 Spring Cloud+Spring Boot+Mybatis+Vue+ElementUI+前后端分离 功能清单

ava版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下&#xff1a; 首页 工作台&#xff1a;待办工作、消息通知、预警信息&#xff0c;点击可进入相应的列表 项目进度图表&#xff1a;选择&#xff08;总体或单个&#xff09;项目显示1…

学习数据结构第3天(线性表的定义和基本操作)

线性表的定义和基本操作前言线性表的定义线性表的基本操作经典试题前言 线性表是算法题命题的重点。这类算法题实现比较容易且代码量较少&#xff0c;但是要求具有最优的性能&#xff08;时间复杂度、空间复杂度&#xff09;&#xff0c;才能获得满分。因此应牢固掌握线性表的…

【牛客刷题专栏】0x18:JZ16 数值的整数次方(C语言编程题)

前言 个人推荐在牛客网刷题(点击可以跳转)&#xff0c;它登陆后会保存刷题记录进度&#xff0c;重新登录时写过的题目代码不会丢失。个人刷题练习系列专栏&#xff1a;个人CSDN牛客刷题专栏。 题目来自&#xff1a;牛客/题库 / 在线编程 / 剑指offer&#xff1a; 目录前言问题…

安全防御 --- APT、密码学

APT 深度包检测技术&#xff1a;将应用层内容展开进行分析&#xff0c;根据不同的设定从而做出不同的安全产品。 深度流检测技术&#xff1a;与APS画像类似。会记录正常流量行为&#xff0c;也会将某些应用的行为画像描述出来。也可将加密流量进行判断&#xff0c;并执行相应措…

程序员必知必会7种UML图(类图、序列图、组件图、部署图、用例图、状态图和活动图)画法盘点

众所周知&#xff0c;软件开发是一个分阶段进行的过程。不同的开发阶段需要使用不同的模型图来描述业务场景和设计思路&#xff0c;在不同的阶段输出不同的设计文档也是必不可少的&#xff0c;例如&#xff0c;在需求分析阶段需要输出领域模型和业务模型&#xff0c;在架构阶段…

2023疫情当头,3个月转行软件测试拿下8k+offer,我心满意足了

从2020年的疫情开始&#xff0c;全世界好像按下了暂停键一般&#xff0c;大量新网民涌入互联网。我们的生活方式也随之改变&#xff0c;失业也如洪流般席卷整个世界&#xff0c;宅家的人数在变多&#xff0c;当然大多数人开始寻求新的工作方式&#xff0c;随之进军互联网的人开…

域名过户操作流程及常见问题

模板添加及模板过户操作流程&#xff1a; 一、添加模板操作流程&#xff1a; 1.在业务管理-域名管理-模板管理中找到“添加模板” 2.选择所有者类型&#xff08;个人或是企业/组织&#xff09;&#xff0c;填写新的域名所有者资料&#xff0c;填写无误后点击“确定”。 目前…

记录分享vscode里面非常好用的两个markdown插件

文章目录Markdown PDFMarkdown All in One效果图Markdown PDF 主要用于将markdown文件转为pdf文件 使用方法 安装此插件编辑区鼠标右键就会出来一个弹框,在弹框里面选择 Markdown All in One 我主要用它来生成文章的目录结构,然后转为pdf文件后,目录结构默认就是pdf文章目录,…

告别至暗时刻,高端与全系列手机市场前景可期

作者|落笔 近年来&#xff0c;智能手机用户换机周期持续拉长&#xff0c;市场出货量逐年走低&#xff0c;IDC数据显示&#xff0c;2022年全年中国智能手机市场出货量约2.86亿台&#xff0c;同比下降13.2%&#xff0c;创有史以来最大降幅&#xff0c;全球智能手机发展已进入成熟…

大厂研发成本大曝光,研发占大头

近日&#xff0c;腾讯发布《2022 年腾讯研发大数据报告》&#xff0c;披露了 2022 年腾讯在研发投入、研发效能、开源协同等方面的重要数据。 《报告》显示&#xff0c;2022 年腾讯内部研发人员占比达到 74%&#xff0c;这意味着&#xff0c;平均每四个腾讯员工中&#xff0c;…

linux 共享内存 shmget

专栏内容&#xff1a;linux下并发编程个人主页&#xff1a;我的主页座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物&#xff0e;目录 前言 概述 原理机制 系统命令 接口说明 代码演示 结尾 前言 本专栏主要分享linu…

【深度解刨C语言】内存管理(详)

文章目录前言一.动态内存1.动态内存的用处2.内存的布局简单证明内存布局栈向下生长的证明堆向上增长的证明3.malloc与free进一步理解总结前言 前提: 内存有基本的认识 内存函数基本的了解 如果你对内存与内存函数太不清楚可以看:动态内存管理 目标: 为什么要用动态内存&…

我体验了首个接入GPT-4的代码编辑器,太炸裂了

最近一款名为Cursor的代码编辑器已经传遍了圈内&#xff0c;受到众多编程爱好者的追捧。 它主打的亮点就是&#xff0c;通过 GPT-4 来辅助你编程&#xff0c;完成 AI 智能生成代码、修改 Bug、生成测试等操作。 确实很吸引人&#xff0c;而且貌似也能大大节省人为的重复工作&…

vue尚品汇商城项目-day04【29.加入购物车操作(难点)】

文章目录29.加入购物车操作&#xff08;难点&#xff09;29.1加入购物车按钮29.2addCartSuce29.3购物车29.3.1 向服务器发送ajax请求&#xff0c;获取购物车数据29.3.2UUID临时游客身份29.3.3动态展示购物车29.4修改购物车产品的数量&#xff08;需要发请求&#xff1a;参数理解…

203. 移除链表元素

1、题目 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,5]示例 2&#xff1a; 输入&…

File 类的用法和 InputStream, OutputStream,System 类的用法

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点!人生格言&#xff1a;当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友一起加油喔&#x1f9be;&am…

Typescript学习笔记(一)

什么是TypeScript? TypeScript 是添加了类型系统的 JavaScript&#xff0c;适用于任何规模的项目。 TypeScript 是一门静态类型、弱类型的语言。 安装TypeScript npm install -g typescript编译 tsc hello.tsTypeScript 只会在编译时对类型进行静态检查&#xff0c;如果发…

iOS 内存管理机制与原理

内存分区 内存一般分为五大区&#xff1a;栈区、堆区、常量区、全局区、代码区。如图 1.栈区 是由编译器自动分配并释放的&#xff0c;主要用来存储局部变量、函数的参数等&#xff0c;是一块连续的内存区域&#xff0c;遵循先进后出&#xff08;FILO&#xff09;原则。一般在…
最新文章