首页 > 编程语言 >java----IO流

java----IO流

时间:2024-10-18 15:46:23浏览次数:3  
标签:java 字节 ---- IO import new public String

IO流概述

IO流:存储和读取数据的解决方案

I:input O:ourput 流:像水流一样传输数据

IO流作用?

用于读写数据(本地文件,网络)

IO流按照流向可以分类为哪两种流?

输出流:程序->文件 

输入流:文件->程序

IO流按照操作文件的类型可以分类哪两种流?

字节流:可以操作所有类型的文件

字符流:只能操作纯文本文件(用winods系统自带的记事本打开并且能读懂的文件)

IO流体系

FileOutputStream

        1.创建字节流对象(相当于在程序和文件建立了一条通道)

        2.写入数据

        3.释放资源(相当于把这条通道拆除)

package IODemo;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class demo1 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos=new FileOutputStream("D:\\develop\\代码\\JAVA代码\\java基础\\java入门\\day04\\day04_code\\src\\IODemo\\a.txt"); //1.创建字节流对象
        fos.write(97);//2.写入数据
        fos.close();//3.释放资源
    }
}

 细节注意:

①创建字节流对象:

        细节1:参数是字符串表示的路径或者是File对象都是可以

        细节2 :如果文件不存在会创建一个新的文件,但是要保证父级路径要存在

        细节3:如果文件已经存在,则会清空文件

我们可以看下源码中两种不同的构造方法[细节1:参数是字符串表示的路径或者是File对象都可以]

1.参数是String

public FileOutputStream(String name) throws FileNotFoundException {
    this(name != null ? new File(name) : null, false);//ctrl+b this跟进发现跳入的是下面的方法,new File(name)也会将其转为File类型
}

2.参数是File:

public FileOutputStream(File file, boolean append)
    throws FileNotFoundException
{
    String name = (file != null ? file.getPath() : null);
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        security.checkWrite(name);
    }
    if (name == null) {
        throw new NullPointerException();
    }
    if (file.isInvalid()) {
        throw new FileNotFoundException("Invalid file path");
    }
    this.fd = new FileDescriptor();
    fd.attach(this);
    this.append = append;
    this.path = name;

    open(name, append);
}

细节2:如果文件不存在会创建一个新的文件,但是要保证父级路径要存在

可以看到b.txt不存在,运行之后:会创建一个b.txt

其次,如果我们把父级路径改为不存在的:可以看到找不到指定路径,控制台报错

细节3:如果文件已经存在,则会清空文件

运行之前b.txt的内容

运行之后b.txt的内容:

可以看到会将其内容清空,然后写入。

②写数据:

        细节:write方法的参数是正数,但是实际上写到本地文件中的是整数的ASCII对应的字符

上面的细节3也可以看到,写入的内容都是以ACSII对应字符的形式。

③释放资源:

        细节:每次使用完流之后都要释放资源

如果不释放资源,你想如果java程序一直占用这个文件,你想对其删除操作,就会显示被占用中。

FileOutpurStream写数据的三种方式:

方法名称说明
void write(int b)一次写一个字节数据
void write(byte []b)       一次写一个字节数组数据
void write(byte[] b,int off,int len)一次写一个字节数组的部分数据

代码演示:

可以看到下面通过把字符串转化为byte数组,然后写入字节数组数据

下面则是利用void write(byte[]b,int off,int len)的方法,off从索引几开始,然后截取长度为len

换行和续写

换行:

package IODemo;

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

public class demo3 {
    public static void main(String[] args) throws IOException {
        /*
                换行符
                windows \r\n
                linux \n
                mac \r
         */
        FileOutputStream fos=new FileOutputStream("D:\\develop\\代码\\JAVA代码\\java基础\\java入门\\day04\\day04_code\\src\\IODemo\\a.txt");
        String s="wohao";
        byte[]bytes=s.getBytes();

        String s1="\r\n";
        byte[]bytes1=s1.getBytes();
        String s2="shuai";
        byte[]byte2=s2.getBytes();
        
        fos.write(bytes);
        fos.write(bytes1);
        fos.write(byte2);
        fos.close();
    }
}

结果输出:

续写:

查看构造方法,打开续写开关就可以续写

public FileOutputStream(String name, boolean append)
    throws FileNotFoundException
{
    this(name != null ? new File(name) : null, append);
}

再次对其运行,可以看到文件内容进行了续写。

FileInputStream

操作本地文件的字节输入流,可以把本地文件中的数据读取到程序中来

        1.创建字节输入流对象

        2.读数据

        3.释放资源

package IODemo;
import java.io.FileInputStream;
import java.io.IOException;

public class demo4 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis=new FileInputStream("D:\\develop\\代码\\JAVA代码\\java基础\\java入门\\day04\\day04_code\\src\\IODemo\\a.txt"); //创建字节流对象
        int read=fis.read();//读取数据
        System.out.println(read);
        fis.close();//释放资源
    }
}

  细节注意:

        ①创建字节输入流对象

               细节1:如果文件不存在,就直接报错 (这里和字节输出流类似,只不过这里文件不存在直接就会报错,不会去创建一个新的文件,大家可以想象一下,如果java把它设成不存在会创建一个新的文件,那么创建的新文件也是空的,所以读取什么呢?)

        ②写数据

                细节1:一次读一个字节,读出来的是数据在ASCII对应的数字

                细节2:读到文件末尾了,read方法返回-1

package IODemo;
import java.io.FileInputStream;
import java.io.IOException;

public class demo4 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis=new FileInputStream("D:\\develop\\代码\\JAVA代码\\java基础\\java入门\\day04\\day04_code\\src\\IODemo\\a.txt");
        int read1=fis.read();
        int read2=fis.read();
        System.out.println(read1);
        System.out.println(read2);
        fis.close();
    }
}


a.txt内容:
w

控制台结果:
119
-1

可以看到,写数据时,每次都是都是从文件里读取一个字节,读取的数据对应的就是ASCII的数组,当没有数据的时候读取的就是-1

        ③释放资源

                细节:每次使用完流之后都要释放资源

 FileInputStream循环读取

package IODemo;
import java.io.FileInputStream;
import java.io.IOException;
public class demo5 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis=new FileInputStream("day04_code\\src\\IODemo\\b.txt");
        int b;
        b=fis.read();//每次read()指针都会移动
        while(b!=-1){ //当读取到文件末尾是就会跳出
            System.out.print((char)b);
            b=fis.read();
        }
    }
}

控制台输出:

wohaoshuaiw

文件拷贝(综合练习)

拷贝过程代码:

运行结果如下:

FileInputStream弊端:

        一次读写一个一个字节

解决方案:

FileInputStream一次读多个字节方法:

方法名称说明
public int read()一次读写一个字节数据
public int read(byte [] buffer)一次读一个自己数组数据

注意:一次读一个字节数组的数据,每次读取会尽可能把数组装满

数组本身会占用内存空间,长度一般为1024整数倍,一般合理设置

package IODemo;

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

public class demo7 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis=new FileInputStream("day04_code\\src\\IODemo\\a.txt");
        byte []bytes=new byte[2];
        int len;
        //一次读取多个字节数据,具体读多少,跟数组长度有关
        //返回值:本次读取到了多少个字节数据
        //a.txt内容是abcde
        len=fis.read(bytes); 
        System.out.println(new String(bytes));//输出结果是ab
        System.out.println(len);//输出结果是2
        len=fis.read(bytes);
        System.out.println(new String(bytes)); //输出结果是cd
        System.out.println(len);//输出结果是2
        len=fis.read(bytes);
        System.out.println(new String(bytes));//输出结果是ed
        System.out.println(len);//输出结果是1
        fis.close();
    }
}

控制台输出:
ab
2
cd
2
ed
1

分析

记事本的内容是abcde,可以看到我们的长度是5,但是我们创建的字节数组是2,也就是说每次读取两个字节,为什么最后一次读取读了一个字节但是输出读取的内容确是ed呢?

从下面两幅图片可以看到:

我们当读取第二次的时候,读取的内容则是cd,字节数组的内容是cd,当我们读取到第三次的时候,指针已经在e的位置了,如果要再进行读取,那么读取的长度为1,但是字节数组的内容现在是cd,读取e只把字节数组索引0的位置进行了替换,所以字节数组的内容为ed,最终读取的内容也是ed。

        那么,面对这种情况我们肯定想让最后一次读取的内容是长度为1,我们该如何解决呢?

可以看到,String类提供了这种构造方法,可以从

参数2可以从数组0索引开始读取

参数3代表读取的长度

public String(byte bytes[]) {
    this(bytes, 0, bytes.length);
}

我们只需要修改代码:

package IODemo;

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

public class demo7 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis=new FileInputStream("day04_code\\src\\IODemo\\a.txt");
        byte []bytes=new byte[2];
        int len;
        //一次读取多个字节数据,具体读多少,跟数组长度有关
        //返回值:本次读取到了多少个字节数据
        //a.txt内容是abcde
        len=fis.read(bytes);
        System.out.println(new String(bytes,0,len));
        System.out.println(len);
        len=fis.read(bytes);
        System.out.println(new String(bytes,0,len));
        System.out.println(len);
        len=fis.read(bytes);
        System.out.println(new String(bytes,0,len));
        System.out.println(len);
        fis.close();
    }
}

控制台运行结果:
ab
2
cd
2
e
1

根据上面的内容进行更改:

public class demo8 {
    public static void main(String[] args) throws IOException {

        FileInputStream fis=new FileInputStream("day04_code/src/IODemo/a.txt");
        FileOutputStream fos=new FileOutputStream("day04_code/src/IODemo/copy2.txt",true);
        byte bytes[]=new byte[2];
        int len;
        while((len=fis.read(bytes))!=-1){
            fos.write(bytes,0,len);
        }
        fos.close();
        fis.close();

    }
}

字节流和字符流的应用场景

字符集详解

记住几个点:

        1.计算机中,任意数据都是以二进制的形式来存储

        2.计算机中最小的存储单元是一个字节

        3.ASCII字符集中,一个英文占一个字节

        4.简体中文版windows,默认使用GBK字符集

        5.GBK字符集完全兼容ASCII字符集

                一个英文占一个字节,二进制第一位是0

                一个中文占两个字节,二进制高位字节第一位是1

UniCode字符集:

        Unicode字符集的UTF-8编码格式:

        一个英文占一个字节,二进制第一位是0,转成十进制是正数

        一个中文占三个字节,二进制第一位是1,第一个字节转成十进制是负数

为什么会有乱码?

        原因1:读取数据未读完整个汉字

        原因2:编码和解码方式不同

如何不产生乱码:

        1.不要用字节流读取文本文件

字符输入流

package IODemo;

import java.io.FileReader;
import java.io.IOException;

//用字符流读取文件
//read()
//字符流的底层也是字节流,默认是一个字节一个字节读取数据
//如果遇到中文就会一次会去读多个,GBK一次读两个字节,UTF-8一次读三个字节
public class demo10 {
    public static void main(String[] args) throws IOException {
        FileReader fr=new FileReader("D:\\develop\\代码\\JAVA代码\\java基础\\java入门\\day04\\day04_code\\src\\IODemo\\c.txt");
        int ch;

//        while ((ch=fr.read())!=-1){//无参的read方法
//            System.out.println((char)ch);
//        }
        char[]chars=new char[2];
        int len;
        while((len=fr.read(chars))!=-1){//有参的read的方法
            System.out.println(new String(chars,0,len));
        }
        fr.close();
    }
}

        2.编码解码时使用同一个码表,同一个编码方式

package IODemo;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

//Idea默认编码方式是utf-8
public class demo9 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        //编码
        String str="ai你呦";
        byte[]bytes1=str.getBytes();//UTF-8编码方式
        System.out.println(Arrays.toString(bytes1));

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

        //解码
        String str2=new String(bytes1);//默认是UTF-8所以解码没有乱码
        System.out.println(str2);

        //如果解码方式和编码不一样
        String str3=new String(bytes1,"GBK");//编码使用utf-8,解码则是GBK出现乱码,因为GBK汉字使用两个字节来表示
        System.out.println(str3);
    }
}

控制台输出:
[97, 105, -28, -67, -96, -27, -111, -90]
[97, 105, -60, -29, -33, -49]
ai你呦
ai浣犲懄

字符输出流

FileWriter构造方法

①创建字符输出流对象

       细节1:参数是字符串表示的路径或者File对象都是可以

       细节2:如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的

       细节3:如果文件已经存在,则会清空文件,如果不想清空可以打开续写开关

②写数据

        细节:如果write方法的参数是整数,但是实际写到本地文件中的是整数在字符集上对应的字符

package IODemo;

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

public class demo11 {
    public static void main(String[] args) throws IOException {
        FileWriter fw=new FileWriter("D:\\develop\\代码\\JAVA代码\\java基础\\java入门\\day04\\day04_code\\src\\IODemo\\a.txt");
        fw.write(25105);
        fw.close();
    }
}

a.txt内容:我

③释放资源

        细节:每次使用完之后都要释放资源

字符流原理解析:

①创建字符输入流对象

        底层:关联文件,并创建缓冲区[减少了文件读取的次数](长度为8192字节数组)

②读取数据:

        底层:

        1.判断缓冲区中是否有数据可以读取

        2.缓冲区没有数据:就从文件中获取数据,装到缓冲区中,每次尽可能装满缓冲区,如果文件中也没有了数据,返回-1

        3.缓冲区有数据:就从缓冲区中读取

        空参的read方法:一次读取有一个字节,遇到中文一次读取多个字节,把字节解码并转成十进制返回

        有参的read方法:把读取字节,解码,强转三步合并,强转之后的字符放到数组中

FileWriter

字节缓冲流

基本方法

方法名称说明
public BufferedInputStream(InputStream is)把基本流包装成高级流,提高读取数据的性能
public BufferedOutputStream(OutputStream os)把基本流包装成高级流,提高写出数据的性能

 原理:底层自带了长度为8192的缓冲区提高性能[减少了文件的读取次数,减少了io操作文件的次数]

特有方法:

字符缓冲输入流特有方法说明
public String readLine()读取一行数据,如果没有数据可读,会返回NULL
字符缓冲输出流特有方法说明
public void newLine()跨平台的换行
package IODemo;

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class demo18 {
    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new FileReader("D:\\develop\\代码\\JAVA代码\\java基础\\java入门\\day04\\day04_code\\src\\IODemo\\csb.txt"));
        BufferedWriter bw=new BufferedWriter(new FileWriter("D:\\develop\\代码\\JAVA代码\\java基础\\java入门\\day04\\day04_code\\src\\IODemo\\newcsb.txt"));
        String str;
        List<String> list=new ArrayList<String>();
        while((str=br.readLine())!=null){ //readLine读取一行数据
            list.add(str);
        }
        Collections.sort(list, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                //o1和o2的序号
                //.是通配符 所以转义字符
                int index1=Integer.parseInt(o1.split("\\.")[0]);
                int index2=Integer.parseInt(o2.split("\\.")[0]);
                return index1-index2;
            }
        });
        for (int i = 0; i < list.size(); i++) {
            bw.write(list.get(i));
            bw.newLine();//跨平台换行
        }

        bw.close();
        br.close();
    }
}

转换流

转换流:是字符流和字节流之间的桥梁

作用:

        .指定字符集读写数据(JDK11之后已淘汰)

        .字节流想要使用字符流中的方法

应用场景:

        比如我们要爬取一个网页上百家姓,我们要把网页上的内容爬取下来,然后再利用这则表达式进行具体的格式化,获取我们想要的数据。网页上的内容有文字还有视频等等,对于非纯文本的内容我们需要用字节流来进行操作,又因为我们是百家姓所以转为字符流更好,也可以解决乱码问题。比如下面的爬取代码:

public static String webCrawler(String net) throws IOException {
    StringBuilder sb=new StringBuilder();

    URL url=new URL(net);
    URLConnection conn=url.openConnection();
    //
    InputStreamReader isr=new InputStreamReader(conn.getInputStream());//字节流转换为字符流
    int ch;
    while((ch=isr.read())!=-1){
        sb.append((char)ch);
    }
    isr.close();
    return sb.toString();
}

序列化流/对象操作输出流

可以把java的对象写到本地文件中

字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息。

反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化。

序列化操作:

        一个对象想要序列化,必须满足两个条件

·该类必须java.io.Serializable接口,该接口是一个标记接口,不实现此接口的类不能进行序列化或反序列化,会抛出NotSerializableException 

·如果类中有属性不需要可序列化,在该属性必须注明是瞬态的,即使用transient关键字修饰

·文件中的版本号要与javabean版本号一致,固定版本号serialVersionUID

public class Student implements Serializable {
    private static final long serialVersionUID = 464104926358852317L;
    //private static final long serialVersionUID=1L;
    private String name;
    private int age;
    //瞬态的 不会被序列化
    private transient String address;
    private int sex;

 下面则是创建进行序列化操作:[对Student对象进行序列化]

package IODemo;
import java.io.*;
public class demo22 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Student stu=new Student("zhangsan",20,"南京",1);
        //创建序列化流对象
        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("D:\\develop\\代码\\JAVA代码\\java基础\\java入门\\day04\\day04_code\\src\\IODemo\\a.txt"));
        oos.writeObject(stu);
        oos.close();
    }
}

 重构对象进行反序列化

package IODemo;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class demo23 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //反序列化流
        ObjectInputStream ois=new ObjectInputStream(new FileInputStream("D:\\develop\\代码\\JAVA代码\\java基础\\java入门\\day04\\day04_code\\src\\IODemo\\a.txt"));
        Student stu1=(Student)ois.readObject();
        System.out.println(stu1);
        System.out.println(stu1.getAddress());
        ois.close();

    }
}

控制台输出:

Student{ name = zhangsan, age = 20, address = null}
null

可以看到 进行序列化之后能够重构对象,因为address被transient修饰,所以没有被序列化成功,重构对象也获取不到

固定版本号: 

 

 如果我们创建了一个javaBean,初始版本号为1,对其进行序列化操作,会产生对应的序列化的代码版本1,但是实际开发中,业务可能会变,当我们修改了javaBean之后,那么javaBean对应的版本号则是2,进行反序列化操作时就会出现版本号不对应出现错误,怕怕出InvalidClassException异常。解决的办法就是:固定版本号

 打印流

不能操作数据源,只能操作目的地(不能读,只能写)

        字节打印流

        字符打印流:字符流底层有缓冲区,想要自动刷新需要开启

public class demo27 {
    public static void main(String[] args) throws IOException {
        PrintWriter pw=new PrintWriter(new FileWriter("D:\\develop\\代码\\JAVA代码\\java基础\\java入门\\day04\\day04_code\\src\\IODemo\\c.txt"),true);
        pw.println("字符打印流");
        System.out.println("1");
        //需要手动刷新 有缓冲区
        //获取打印流对象,此打印流在虚拟机启动时候 由虚拟机创建,默认指向控制台
        //特殊打印流,系统中的标准输出流
        PrintStream ps=System.out;
        ps.print("123");
        ps.close();//平常写的输出语句就是一个打印流
        System.out.println("456");
    }
}

控制台输出:

1
123
Process finished with exit code 0

 压缩流

package IODemo;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class demo28 {
    public static void main(String[] args) throws IOException {
        //压缩流 解压缩流
        //压缩流:文件中数据写进压缩包中 输出流

        //1.创建一个File表示要解压的压缩包
        File src=new File("D:\\develop\\代码\\JAVA代码\\java基础\\java入门\\day04\\day04_code\\src\\IODemo\\tests.zip");
        //2.创建一个File表示要解压的目的地
        File dest=new File("D:\\develop\\代码\\JAVA代码\\java基础\\java入门\\day04\\day04_code\\src\\IODemo\\tests");
        unzip(src,dest);
    }
    public static void unzip(File src,File dest) throws IOException {
        //解压的本质 把压缩包里面的文件或者文件夹读取出来,按照层架拷贝到目的地当中

        ZipInputStream zip=new ZipInputStream(new FileInputStream(src));

        //获取到压缩包里面每一个zip对象
        ZipEntry entry;

        while((entry=zip.getNextEntry())!=null){
            //文件夹:需要在目的地处创建一个同样的文件夹
            //文件:需要读取压缩包中的文件,把他存放到目的地dest文件夹,按层级目录存取

            if(entry.isDirectory()){
                //父级 子集
                File file=new File(dest,entry.toString());
                file.mkdirs();
            }
            else{
                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();
    }
}

 压缩:

package IODemo;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class demo30 {
    public static void main(String[] args) throws IOException {
        //压缩整个文件夹
        //1.确定压缩目的地 压缩来源

        File src=new File("D:\\develop\\代码\\JAVA代码\\java基础\\java入门\\day04\\day04_code\\src\\IODemo\\test");
        File dest=new File("D:\\develop\\代码\\JAVA代码\\java基础\\java入门\\day04\\day04_code\\src\\IODemo\\");
        ZipOutputStream zos=new ZipOutputStream(new FileOutputStream(new File(dest,src.getName()+".zip")));
        toZip(src,zos,src.getName());
        zos.close();
    }
    public static void toZip(File src,ZipOutputStream zos,String name) throws IOException {
        //1.获取压缩流的对象
        //2.压缩的位置
        //3.压缩流内部的位置


        //一层层压缩
        File[] lists=src.listFiles();
        for(File file:lists){
            System.out.println(list);
            //如果是文件夹
            if(list.isDirectory()){
                //创建ZIPEntry对象表示 压缩包里的每一个文件和文件夹
                //递归
                //他这里其实创建一个路径           
                toZip(file,zos,name+"\\"+file.getName());
            }
            else{
                int b;
                ZipEntry zipEntry=new ZipEntry(name+"\\"+file.getName());
                zos.putNextEntry(zipEntry);
                FileInputStream fis=new FileInputStream(file);
                while((b=fis.read())!=-1){
                    zos.write(b);
                }
                fis.close();
                zos.closeEntry();
            }

            //如果是文件
        }


    }

}

常用工具包:

                Commons.io

                hutool

以上内容来自:IO流-01-IO流的概述_哔哩哔哩_bilibili

标签:java,字节,----,IO,import,new,public,String
From: https://blog.csdn.net/qq_44766305/article/details/142492790

相关文章

  • ArkWeb智能防跟踪与广告过滤 - 保护用户隐私
    本文旨在深入探讨华为鸿蒙HarmonyOSNext系统(截止目前API12)的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。简介华为鸿蒙HarmonyOSNext系统的Ar......
  • 基于Springboot在线教育管理系统【附源码+文档】
    ......
  • C++顺序结构(3)、数据类型_____教学
    一、设置域宽setw()输出的内容所占的总宽度成为域宽,有些高级语言中称为场宽。使用setw()前,必须包含头文件iomanip,即#include<iomanip>头文件iomanip,用来声明一些“流操作符”,需要一定格式输入输出时,就需要用到它,比较常用的有设置域宽、设置左右对齐、设置实数的精确度等。set......
  • 惯性导航基础实验
    前言:这是山科测院的某次实验设计,由于当时种种原因导致最后的捷联解算误差很大,故打算利用这次博客进行复盘,也可供日后学弟参考,叠甲(本人水平有限,可能错误很多,欢迎一起探讨!)这部分实验课主要参考严恭敏老师的《捷联惯导算法与组合导航原理》,严老师的网站为:https://www.psins.org......
  • Spring 事物管理与原理
    定义与描述Spring有事物传播属性,用于保证数据的统一提交与统一回滚数据库有事物特性(ACID)与数据隔离级别,用于处理脏读、幻读、不可重复读Spring事物管理,是指系统在多线程情况下,配合数据库事物完成数据的统一提交与统一回滚。网上很多关于事物的描述,都是基于数据库实现的。......
  • ArkWeb页面跳转与跨应用导航 - 高级应用
    本文旨在深入探讨华为鸿蒙HarmonyOSNext系统(截止目前API12)的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。简介页面跳转是Web应用中常见的操作,......
  • 专题(十九)Linux 下的正则表达式
    一、作用与介绍正则表达式通常用于判断语句中,用来检查某一字符串是否满足某一格式正则表达式是由普通字符与元字符组成普通字符:包括大小写字母、数字、标点符号及一些其它符号元字符:是指在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)......
  • 容器运维必备-Docker 常用命令
    前言:在Kubernetes的日常运维中,虽然我们主要依赖kubectl命令来管理容器和集群,但有时候,Docker的一些命令因其直观和便捷性,能够为我们提供极大的帮助。以下是一些Docker的常用命令,它们可以在Kubernetes环境中作为辅助工具使用,以提高我们的工作效率和操作的灵活性以下是Doc......
  • 【UWP】在 UWP 中使用 Windows App SDK
    众所周知,WAS(WindowsAppSDK,俗称WinUI3)在刚开始是支持UWP的,甚至最早只支持UWP,但是微软在正式版发布前删除了对UWP的支持,不过真的删除了吗?初生之鸟在2023年10月发现在VS调试下无视报错继续运行可以正常在UWP加载WAS。随着WAS的开源,WAS阻止在UWP上运行的原因也被......
  • Jenkins+Coverage的代码覆盖率集成实践
    Jenkins+Coverage的代码覆盖率集成实践一、工具介绍Jenkins:Jenkins是一个开源的、基于Java开发的持续集成工具,它可以帮助开发人员自动化构建、测试和部署软件项目。Coverage:Coverage是一个Python代码覆盖率工具,用于测量代码执行过程中哪些代码行被执行到,从而评估测试的有效......