【Java】文件读写和输入输出

2023-05-16

写在前面的话:

  1. 版权声明:本文为博主原创文章,转载请注明出处!
  2. 博主是一个小菜鸟,并且非常玻璃心!如果文中有什么问题,请友好地指出来,博主查证后会进行更正,啾咪~~
  3. 每篇文章都是博主现阶段的理解,如果理解的更深入的话,博主会不定时更新文章。
  4. 本文初次更新时间:2021.01.01,最后更新时间:2021.01.05

文章目录

  • 正文开始
    • 1. 文件操作 - File
      • 1.1 基本操作
      • 1.2 创建、删除文件
      • 1.3 创建、删除目录
      • 1.4 其他操作
      • 1.5 文件过滤器
    • 2. RandomAccessFile
      • 2.1 创建 RandomAccessFile 实例
      • 2.2 字节数据读写操作
        • 2.2.1 写一个字节
        • 2.2.2 读一个字节
        • 2.2.3 利用读、写进行复制操作
        • 2.2.4 写一组字节
        • 2.2.5 读一组字节
        • 2.2.6 改进复制文件
      • 2.3 文件指针操作
        • 2.3.1 getFilePointer() 方法
        • 2.3.2 seek() 方法
      • 2.4 基本类型读写
        • 2.4.1 如何写入一个 int 值
        • 2.4.2 各种基本类型读写
      • 2.5 字符串读写
    • 3. 基本 IO 操作
    • 4. 文件数据 IO 操作
  • 参考
  • 相关文章

正文开始

1. 文件操作 - File

File用来表示文件系统中的一个文件或目录。

使用 File 可以:

  1. 访问其表示的文件或目录的属性信息(名字,大小等信息)
  2. 创建或删除文件及目录
  3. 访问一个目录中的子项

重点: File 不能访问文件数据(就是说不能读写文件内容)。

1.1 基本操作

关于File的一些基本操作:

  • String getName()
    获取文件名称
  • long length()
    获取文件长度
  • boolean canRead()
    判断文件是否可读,可读返回true
  • boolean canWrite()
    判断文件是否可写,可写返回true
  • boolean isHidden()
    判断文件是否隐藏,隐藏返回true

示例如下:

package file;

import java.io.File;

/**
 * File 用来表示文件系统中的一个文件或目录
 * @author returnzc
 */
public class FileDemo {
    public static void main(String[] args) {
        //访问当前项目目录下的 demo.txt 文件
        File file = new File("./demo.txt");
        
        //获取名字
        String name = file.getName();
        System.out.println(name);
        
        //获取长度(单位是字节)
        long len = file.length();
        System.out.println(len);
        
        boolean cr = file.canRead();
        boolean cw = file.canWrite();
        System.out.println("可读:" + cr);
        System.out.println("可写:" + cw);
        
        boolean ih = file.isHidden();
        System.out.println("是否隐藏:" + ih);
    }
}

运行结果:

demo.txt
18
可读:true
可写:true
是否隐藏:false

1.2 创建、删除文件

判断文件或目录是否存在:

  • boolean exists()
    判断当前 File 表示的文件或目录是否已经存在,存在返回 true

创建文件:

  • boolean createNewFile() throws IOException
    创建新文件,需要处理异常

创建文件示例:

package file;

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

/**
 * 使用 File 创建一个文件
 * @author returnzc
 *
 */
public class CreateNewFileDemo {
    public static void main(String[] args) throws IOException {
        //访问当前项目目录下的 test.txt 文件
        File file = new File("./test.txt");
        
        if (!file.exists()) {
            /*
             * 创建该文件
             * 需要注意,创建的文件所在的目录必须存在,否则会抛出异常。
             */
            file.createNewFile();
            System.out.println("文件已创建");
        } else {
            System.out.println("文件已存在");
        }
    }
}

删除文件、目录:

  • boolean delete()
    删除文件和目录。删除目录时只能删除空目录,非空目录需要挨个把所有子项都删掉才能删除。

删除文件:

package file;
import java.io.File;
/**
 * 删除一个文件
 * @author returnzc
 *
 */
public class DeleteFileDemo {
    public static void main(String[] args) {
        /*
         * 将当前项目目录下的test.txt文件删除
         * 在相对路径中,"./"是可以忽略不写的,默认就是从当前目录开始的。
         */
        File file = new File("./test.txt");
        if (file.exists()) {
            file.delete();
            System.out.println("文件已删除");
        } else {
            System.out.println("文件不存在");
        }
    }
}

1.3 创建、删除目录

创建目录:

  • boolean mkdir()
    创建目录,要求创建的目录所在的父目录必须存在
  • boolean mkdirs()
    创建多级目录,会将不存在的父目录一同创建出来

创建目录:

package file;
import java.io.File;
/**
 * 创建一个目录
 * @author returnzc
 *
 */
public class MkDirDemo {
    public static void main(String[] args) {
        File dir = new File("demo");
        
        if (!dir.exists()) {
            //创建该目录
            dir.mkdir();
            System.out.println("目录已创建");
        } else {
            System.out.println("目录已存在");
        }
    }
}

创建多级目录:

package file;
import java.io.File;
/**
 * 创建一个多级目录
 * @author returnzc
 *
 */
public class MkDirsDemo {
    public static void main(String[] args) {
        File dir = new File("a/b/c/d/e/f");
        
        if (!dir.exists()) {
            //mkdir()方法要求创建的目录所在的父目录必须存在
            //mkdirs()方法则会将不存在的父目录一同创建出来
            dir.mkdirs();
            System.out.println("创建完毕!");
        } else {
            System.out.println("目录已存在!");
        }
    }
}

删除目录:

package file;
import java.io.File;
/**
 * 删除目录
 * @author returnzc
 *
 */
public class DeleteDirDemo {
    public static void main(String[] args) {
        File dir = new File("a");
        
        if (dir.exists()) {
            //delete方法在删除目录时要求该目录必须是一个空目录
            dir.delete();
            System.out.println("目录已删除");
        } else {
            System.out.println("目录不存在");
        }
    }
}

1.4 其他操作

  • boolean isDirectory()
    判断是否为目录
  • boolean isFile()
    判断是否为文件
  • File[] listFiles()
    列出所有文件

列出指定目录的所有文件:

package file;
import java.io.File;
/**
 * 获取一个目录中的所有子项
 * @author returnzc
 *
 */
public class ListFilesDemo {
    public static void main(String[] args) {
        File dir = new File(".");  //当前目录
        
        if (dir.isDirectory()) {
            File[] subs = dir.listFiles();
            for (int i = 0; i < subs.length; i++) {
                System.out.println(subs[i].getName());
            }
        }
    }
}

运行结果:

6
.classpath
.project
.settings
bin
demo.txt
src

删除文件或目录(递归调用):

package file;
import java.io.File;
/**
 * 完成方法,实现将给定的File对象表示的文件或目录删除
 * @author returnzc
 *
 */
public class DeleteTestDemo {
    public static void main(String[] args) {
        File dir = new File("a");
        delete(dir);
    }

    public static void delete(File f) {
        if (f.isDirectory()) {
            //先将该目录清空
            File[] subs = f.listFiles();
            for (int i = 0; i < subs.length; i++) {
                File sub = subs[i];
                //先删除当前子项
                delete(sub);
            }
        }
        f.delete();
    }
}

1.5 文件过滤器

重载的ListFiles方法允许我们传入一个文件过滤器(作为参数),然后将目录中满足过滤器要求的子项返回。

文件过滤器是一个接口,如果用的话要实现类:

class MyFilter implements FileFilter {
    public boolean accept(File file) {
        String name = file.getName();
        return name.startsWith(".");
    }
}

示例:

package file;

import java.io.File;
import java.io.FileFilter;

/**
 * 重载的 ListFiles 方法,允许我们传入一个文件过滤器
 * 然后将目录中满足过滤器要求的子项返回
 */
public class FileDemo {
    public static void main(String[] args) {
        File dir = new File(".");

        /*
         * FileFilter 文件过滤器
         * 获取当前目录下所有文字以"."开头的子项
         */
        MyFilter filter = new MyFilter();
        File[] subs = dir.listFiles(filter);
        System.out.println(subs.length);
        for (int i = 0; i < subs.length; i++) {
            System.out.println(subs[i].getName());
        }
    }
}

class MyFilter implements FileFilter {
    public boolean accept(File file) {
        String name = file.getName();
        System.out.println("正在过滤:" + name);
        return name.startsWith(".");
    }
}

运行结果:

正在过滤:.classpath
正在过滤:.project
正在过滤:.settings
正在过滤:bin
正在过滤:demo.txt
正在过滤:src
3
.classpath
.project
.settings

可以用匿名内部类:

/*
* FileFilter 文件过滤器
*/
FileFilter filter = new FileFilter() {
    public boolean accept(File file) {
        String name = file.getName();
        System.out.println("正在过滤:" + name);
        return name.startsWith(".");
    }
};

能少写就少写:

File[] subs = dir.listFiles(new FileFilter() {
    public boolean accept(File file) {
        String name = file.getName();
        System.out.println("正在过滤:" + name);
        return name.startsWith(".");
    }
});

JDK8后有lambda表达式

File[] subs = dir.listFiles((file)->{
        String name = file.getName();
        System.out.println("正在过滤:" + name);
        return name.startsWith(".");
    }
});

最终可以简化为:

File[] subs = dir.listFiles(
    (file)->file.getName().startsWith(".")
);

2. RandomAccessFile

上面我们讲到 File 不能访问文件数据,接下来说一个可以读写文件数据的类RandomAccessFile,这个类是基于指针操作的。

这是一个专门用来读写文件数据的 API,RandomAccessFile基于指针对文件数据读写,可以移动指针读写任意位置,所以可以灵活的对文件数据进行编辑工作,即可以对文件随机访问。

2.1 创建 RandomAccessFile 实例

创建 RandomAccessFile 时有两种常见模式:

  • r:只读模式,只能读,如果文件不存在则会抛出异常。
  • rw:读写模式,如果文件不存在,则会自动创建该文件。

关于创建实例,以下两种方法都可以:

//方法 1
RandomAccessFile raf = new RandomAccessFile("raf.dat", "rw");

//方法 2
File file = new File("raf.dat");
RandomAccessFile raf = new RandomAccessFile(file, "rw");

因为有这两种常用的构造方法(还有其他构造方法,不过没有下面两种常用):

//构造方法 1
RandomAccessFile(String name, String mode) throws FileNotFoundException
//构造方法 2
RandomAccessFile(File file, String mode) throws FileNotFoundException

2.2 字节数据读写操作

2.2.1 写一个字节

一个简单的示例:

package raf;

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

/**
 * 创建 RandomAccessFile 时有两种常见模式:
 * r:只读模式
 * rw:读写模式
 * 
 * @author returnzc
 *
 */
public class RandomAccessFileDemo {
    public static void main(String[] args) throws IOException {
        //向当前目录中的文件 raf.dat 中写入一个字节
        RandomAccessFile raf = new RandomAccessFile("raf.dat", "rw");
        
        raf.write(1);
        System.out.println("写出完毕!");
        
        raf.close();
    }
}

其中:

void write(int b) throws IOException

根据当前指针所在位置处向文件中写入1个字节,写入的是给定的 int 值所对应的二进制的低8位

例如:int 是4字节,每8位二进制一个字节,这里只是写入了低8位,具体为,整数1的二进制为 00000000 00000000 00000000 00000001,低8位即为00000001,所以 raf.write(1) 表示写入了 00000001

写操作完毕之后,需要close(),会释放文件的写操作,如果不释放可能会出现“正在读写不能删除”这样子。

上面的示例程序运行完毕后,项目目录下会出现一个 raf.dat 文件,大小为1字节,不过内容没有定义对应的编解码,所以打开看该文件的内容可能是乱码:
在这里插入图片描述
值得注意的是,write()每次创建后都是从头写的,这样就会覆盖之前的数据。并且一个字节无法表示int型的-1(int 型的 -1 为 11111111 11111111 11111111 11111111),只存低 8 位,所以只能写 0-255 之间的数据。

2.2.2 读一个字节

从文件中读取 1 个字节,并以 int 形式返回:

int read() throws IOException

若返回值为-1,则表示读取到了文件末尾。该方法会从文件中读取一个字节(8位),填充到 int 的低 8 位,剩下的高 24 位为 0,每次读取后自动移动文件指针,准备下次读取。

关于写的小示例:

package raf;

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

/**
 * 读取文件数据
 * @author returnzc
 *
 */
public class ReadDemo {
    public static void main(String[] args) throws IOException {
        //从 raf.dat 文件中读取字节
        File file = new File("raf.dat");
        RandomAccessFile raf = new RandomAccessFile(file, "r");
        
        int d = raf.read();
        System.out.println("first: " + d);
        
        d = raf.read();
        System.out.println("second: " + d);
        
        raf.close();
    }
}

运行结果:

first: 1
second: -1

可以看到,第一次读的时候,我们读取了最开始写进去的 1 的低 8 位,第二次读的时候,由于这时已经读到了文件末尾,所以返回值为 -1。

上面我们提到一个字节无法表示int型的-1(int 型的 -1 为 11111111 11111111 11111111 11111111),只存低 8 位,所以只能写 0-255 之间的数据。做一个小测试,如果一定要使用 write() 写入 -1,那么再用 read() 读出来是多少呢?

简单测试一下就知道啦:

package raf;

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

public class RandomAccessFileDemo {
    public static void main(String[] args) throws IOException {
        File file = new File("raf.dat");
        RandomAccessFile raf = new RandomAccessFile(file, "rw");
        
        raf.write(-1);
        System.out.println("写出完毕!");
        
        raf = new RandomAccessFile(file, "r");  //重新打开指针移到文件开始位置
        int d = raf.read();
        System.out.println("读出完毕:" + d);
        
        raf.close();
    }
}

运行结果:

写出完毕!
读出完毕:255

答案是 255。解释一下:int 型的 -1 为 11111111 11111111 11111111 11111111,写的时候只写入了低8位,即写入了 11111111,那么读的时候自然是读出了 00000000 00000000 00000000 11111111,就是 255 啦。

需要注意的是,这里在写入完毕之后,需要重新打开使指针移动到文件开始的位置,如果写完直接读,写完成时指针指向文件末尾,接着读的话返回值就是 -1 了,当然还有其他方法可以移动指针,而不用重新打开,这个等下会讲。

2.2.3 利用读、写进行复制操作

复制很简单,就是一边读一遍写的操作,把读到的数据原封不动地写出来就好了:

package raf;

import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 复制文件
 * @author returnzc
 *
 */
public class RandomAccessFileDemo {
    public static void main(String[] args) throws IOException {
        RandomAccessFile src = new RandomAccessFile("test.pdf", "r");  //原文件
        RandomAccessFile desc = new RandomAccessFile("cp.pdf", "rw");  //复制出来的文件

        //保存每次读取到的字节
        int d = -1;
        while ( (d = src.read()) != -1 ) {
            desc.write(d);
        }

        //复制完毕
        System.out.println("copy done!");
        src.close();
        desc.close();
    }
}

2.2.4 写一组字节

根据当前指针所在位置处,连续写出给定数组中的所有字节:

void write(byte b[]) throws IOException

根据当前指针所在位置处,连续写出给定数组中的部分字节,从 off 处开始,连续写 len 个字节:

void write(byte b[], int off, int len) throws IOException

示例:

package raf;

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

/**
 * 写入一组字节
 * @author returnzc
 *
 */
public class RandomAccessFileDemo {
    public static void main(String[] args) throws IOException {
        File file = new File("raf.dat");
        RandomAccessFile raf = new RandomAccessFile(file, "rw");
        
        byte[] data = new byte[100];
        raf.write(data);
        System.out.println("写出完毕!");
        
        raf.close();
    }
}

可以看到这次写入的文件大小为 100 字节:
在这里插入图片描述

2.2.5 读一组字节

一次性读取给定字节数组总长度的字节量,并存入到该数组中,返回值为实际读取到的字节量,若返回值为 -1,则表示文件末尾:

int read(byte b[]) throws IOException

将给定字节数组从下标 off 处开始的连续 len 个字节一次性写出,返回值为实际读取到的字节量:

int read(byte b[], int off, int len) throws IOException

示例:

package raf;

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

/**
 * 读出一组字节
 * @author returnzc
 *
 */
public class RandomAccessFileDemo {
    public static void main(String[] args) throws IOException {
        RandomAccessFile raf = new RandomAccessFile("raf.dat", "rw");

        int len = -1;
        len = raf.read(data);
        System.out.println("读出完毕: " + len);
        
        raf.close();
    }
}

运行结果:

读出完毕: 100

2.2.6 改进复制文件

上面我们写到利用读写来复制文件,不过当时读取和写入都是 1 字节,速度很慢:

package raf;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 复制文件,字节读写
 * @author returnzc
 *
 */
public class CopyDemo {
    public static void main(String[] args) throws IOException {
        RandomAccessFile src = new RandomAccessFile("服务器.xmind", "r");
        RandomAccessFile desc = new RandomAccessFile("服务器_cp.xmind", "rw");
        long start = System.currentTimeMillis();
        
        int d = -1;    //保存每次读取到的字节
        while ((d = src.read()) != -1) {
            desc.write(d);
        }
        long end = System.currentTimeMillis();
        
        //复制完毕了
        System.out.println("复制完毕!耗时:" + (end - start) + "ms");
        src.close();
        desc.close();
    }
}

运行结果:

复制完毕!耗时:700ms

接下来我们改进一下,读、写都是一组字节:

package raf;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 提高每次读写的数据量,减少实际发生的读写次数,可以提高读写效率。
 * @author returnzc
 *
 */
public class CopyDemo2 {
    public static void main(String[] args) throws IOException {
        RandomAccessFile src = new RandomAccessFile("服务器.xmind", "r");
        RandomAccessFile desc = new RandomAccessFile("服务器_cp.xmind", "rw");
        
        byte[] data = new byte[1024];    //1KB
        int len = -1;    //每次实际读取到的字节量
        
        long start = System.currentTimeMillis();
        
        while((len = src.read(data)) != -1) {
            desc.write(data, 0, len);
        }
        long end = System.currentTimeMillis();
        
        System.out.println("复制完毕!耗时:" + (end - start) + "ms");
        src.close();
        desc.close();
    }
}

运行结果:

复制完毕!耗时:2ms

单字节读写的模式,一般称为随机读写;一组字节读写的模式一般称为块读写。可见使用块读写,复制的效率大大提高。不过需要注意的是,每次读写的大小需要考虑一下硬盘的读写上限哟。

2.3 文件指针操作

RandomAccessFile 的读写操作都是基于指针的,也就是说总是在指针当前所指向的位置进行读写操作。

2.3.1 getFilePointer() 方法

该方法用于获取当前 RandomAccessFile 的指针位置:

long getFilePointer() throws IOException

小示例:

/*
 * long getFilePointer()
 * 获取当前 RandomAccessFile 的指针位置
 */
long pos = raf.getFilePointer();
System.out.println("pos: " + pos);    //pos: 0(类似数组下标,第1个字节的位置)

2.3.2 seek() 方法

该方法用于移动当前 RandomAccessFile 的指针位置:

void seek(long pos) throws IOException

小示例:

raf.seek(0);  //将指针移动到文件开始处(第一个字节的位置)

2.4 基本类型读写

2.4.1 如何写入一个 int 值

上面我们讲到字节读写,那么如何利用单个字节读写来写入一个 int 值呢。

答案是利用位运算(>>>)

假设需要写入的值的二进制为 01111111 11111111 11111111 11111111,那么我们可以先把高8位01111111取出来写入,然后再写次高8位,一直到把低8位都写进去。如下:

假设:max = 01111111 11111111 11111111 11111111
执行:int d = max >>> 24;
此时:d = 00000000 00000000 00000000 01111111

测试一下:

package raf;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * RAF读写基本类型数据,以及RAF基于指针的读写操作
 * 
 * RAF总是在指针指向位置要么读,要么写一个字节,并且无论是读还是写进行
 * 后,指针都会自动向后移动一个字节。
 * @author returnzc
 *
 */
public class RandomAccessFileDemo2 {
    public static void main(String[] args) throws IOException {
        RandomAccessFile raf = new RandomAccessFile("int.dat", "rw");
        
        long pos = raf.getFilePointer();
        System.out.println("pos: " + pos);    //pos: 0
        
        //将一个int最大值写入到文件中
        int max = Integer.MAX_VALUE;
        raf.write(max >>> 24);    //高8位
        System.out.println("*pos: " + raf.getFilePointer());  //pos: 1
        raf.write(max >>> 16);    //次高8
        System.out.println("*pos: " + raf.getFilePointer());  //pos: 2
        raf.write(max >>> 8);     //次低8位
        System.out.println("*pos: " + raf.getFilePointer());  //pos: 3
        raf.write(max);           //最低8位
        System.out.println("*pos: " + raf.getFilePointer());  //pos: 4
        
        System.out.println("写出int值完毕!");
        raf.close();
    }
}

运行结果:

pos: 0
*pos: 1
*pos: 2
*pos: 3
*pos: 4
写出int值完毕!

可以看到生成的文件为 4 字节:
在这里插入图片描述
但是像上面那样写会很麻烦,而这里有一个提供给我们的方法:

void writeInt(int v) throws IOException

该方法可以一次性写4个字节,将给定的 int 值写出。

可以看一下该方法的源码,跟我们刚刚讲的方法是一样滴:

public final void writeInt(int v) throws IOException {
    write((v >>> 24) & 0xFF);
    write((v >>> 16) & 0xFF);
    write((v >>>  8) & 0xFF);
    write((v >>>  0) & 0xFF);
    //written += 4;
}

2.4.2 各种基本类型读写

看名字就懂啦:

void writeBoolean(boolean v)
void writeByte(int v)
void writeShort(int v)
void writeChar(int v)
void writeInt(int v)
void writeLong(long v)
void writeFloat(float v)
void writeDouble(double v)

小示例:

raf.writeInt(123);         //4字节
raf.writeLong(123L);       //8字节
raf.writeDouble(123.123);  //8字节

2.5 字符串读写

byte[] getBytes()
byte[] getBytes(String charsetName) throws UnsupportedEncodingException

3. 基本 IO 操作

4. 文件数据 IO 操作

占个坑,不要急,正在写~~

在这里插入图片描述

参考

相关文章

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Java】文件读写和输入输出 的相关文章

随机推荐

  • rocksdb的原子flush

    如果始终启用 WAL xff0c 则无需使用原子刷新选项 启用 WAL 后 xff0c 单个 WAL 文件用于捕获对所有列族的写入 因此 xff0c 恢复的数据库 xff08 通过在崩溃 恢复路径中重播 WAL 日志 xff09 保证在所有
  • rocksdb的设置选项和基本调整

    除了在 RocksDB 上使用基本操作编写代码外 xff0c 您可能还对如何调整 RocksDB 以实现所需的性能感兴趣 在本页中 xff0c 我们将介绍如何进行初始设置 xff0c 该设置应该足以满足许多用例的需求 RocksDB 有许多
  • rocksdb的wal配置

    wal配置 数据库 xff1a xff1a wal dir DBOptions wal dir设置 RocksDB 存储预写日志文件的目录 xff0c 该目录允许将 WAL 存储在与实际数据不同的目录中 数据库 xff1a xff1a WA
  • Winpcap常用函数解析

    1 int pcap findalldevs pcap if t char 说明 xff1a 用来获得网卡的列表 参数 xff1a 指向pcap if t 类型的列表的指针的指针 char型指针 当打开列表错误时返回错误信息 返回值 为in
  • 终端、虚拟终端、shell、控制台、tty的区别

    终端与控制台的区别 xff1f 最近开始接触Linux xff0c 终端 虚拟终端 shell 控制台 tty等概念让我很混乱 xff0c 有必要认识清楚 今天看到有人问终端和控制台的区别 xff0c 而且这个问题比较有普遍性 xff0c
  • Windows下C++使用thread时无法识别thread和mutex相关库的解决

    问题描述 今天我在Windows下打算尝试C 43 43 多线程编程 xff0c 在CLion上进行编码 CLion的C 43 43 编译器是正常的 xff0c 以前也跑过好几个项目 xff0c 使用其他STL库函数也正常 xff0c 唯独
  • 虚拟机下Linux系统磁盘扩容

    在VM虚拟机中 xff0c 我们经常会选择默认磁盘大小20G xff0c 用着用着才发现20G不够用 xff0c 服务启动不了 xff0c 就很尴尬 xff0c 让我们今天一起来学习下 xff0c 如何在虚拟机给磁盘扩容 一 xff1a 关
  • MATLAB学习笔记——二维和三维绘图

    MATLAB学习笔记 二维和三维绘图 近期练习matlab的二维和三维绘图 xff0c 整理一下 xff0c 以防忘记 文章目录 MATLAB学习笔记 二维和三维绘图一 二维绘图1 plot命令2 fplot 命令3 ezplot 绘图命令
  • pve 相关

    一 pve 创建的虚拟机的配置文件位置 在宿主机的 etc pve qemu server xff0c 这里有创建虚拟机的相关硬件信息 root 64 pve span class token comment cd etc pve qemu
  • mysql在linux下的my.cnf文件在哪里!

    用rpm包安装的MySQL是不会安装 etc my cnf文件的 xff0c 至于为什么没有这个文件而MySQL却也能正常启动和作用 xff0c 在点有两个说法 xff0c 第一种说法 xff0c my cnf只是MySQL启动时的一个参数
  • shell后台并发执行的最佳实践

    一 shell如何在后台执行 1 nohup命令 通常我们都是远程登录linux终端 xff0c 而当我们退出终端时在之前终端运行的程序都会终止 xff0c 有时候先想要退出终端也要程序继续执行这时nohup就登场了 nohup命令 可以将
  • 任意输入10个数,找出最大数和最小数。

    任意输入10个数 找出最大数和最小数 span class token macro property span class token directive keyword include span span class token stri
  • 如何在 Chromebook 上启用开发者模式

    写在前面的话 xff1a 版权声明 xff1a 本文为博主原创文章 xff0c 转载请注明出处 xff01 博主是一个小菜鸟 xff0c 并且非常玻璃心 xff01 如果文中有什么问题 xff0c 请友好地指出来 xff0c 博主查证后会进
  • 【C语言】实现 atoi 函数

    写在前面的话 xff1a 版权声明 xff1a 本文为博主原创文章 xff0c 转载请注明出处 xff01 博主是一个小菜鸟 xff0c 并且非常玻璃心 xff01 如果文中有什么问题 xff0c 请友好地指出来 xff0c 博主查证后会进
  • 【C语言】字符串合集

    写在前面的话 xff1a 版权声明 xff1a 本文为博主原创文章 xff0c 转载请注明出处 xff01 博主是一个小菜鸟 xff0c 并且非常玻璃心 xff01 如果文中有什么问题 xff0c 请友好地指出来 xff0c 博主查证后会进
  • 线程上下文切换和进程上下文切换的区别

    进程切换分两步 1 切换页目录以使用新的地址空间 2 切换内核栈和硬件上下文 对于linux来说 xff0c 线程和进程的最大区别就在于地址空间 对于线程切换 xff0c 第1步是不需要做的 xff0c 第2是进程和线程切换都要做的 所以明
  • 【Ubuntu】解决 Could not get lock /var/lib/dpkg/lock-frontend

    写在前面的话 xff1a 版权声明 xff1a 本文为博主原创文章 xff0c 转载请注明出处 xff01 博主是一个小菜鸟 xff0c 并且非常玻璃心 xff01 如果文中有什么问题 xff0c 请友好地指出来 xff0c 博主查证后会进
  • 【Ubuntu】解决 error: dpkg frontend is locked by another process

    写在前面的话 xff1a 版权声明 xff1a 本文为博主原创文章 xff0c 转载请注明出处 xff01 博主是一个小菜鸟 xff0c 并且非常玻璃心 xff01 如果文中有什么问题 xff0c 请友好地指出来 xff0c 博主查证后会进
  • 【OpenCV】关于Vec3b类型的含义与使用

    写在前面的话 xff1a 版权声明 xff1a 本文为博主原创文章 xff0c 转载请注明出处 xff01 博主是一个小菜鸟 xff0c 并且非常玻璃心 xff01 如果文中有什么问题 xff0c 请友好地指出来 xff0c 博主查证后会进
  • 【Java】文件读写和输入输出

    写在前面的话 xff1a 版权声明 xff1a 本文为博主原创文章 xff0c 转载请注明出处 xff01 博主是一个小菜鸟 xff0c 并且非常玻璃心 xff01 如果文中有什么问题 xff0c 请友好地指出来 xff0c 博主查证后会进