IO体系

news/2024/9/21 7:49:57/文章来源:https://www.cnblogs.com/sprinining/p/18334841

IO,即in和out,也就是输入和输出,指应用程序和外部设备之间的数据传递,常见的外部设备包括文件、管道、网络连接。

Java 中是通过流处理IO 的,那么什么是流?

流(Stream),是一个抽象的概念,是指一连串的数据(字符或字节),是以先进先出的方式发送信息的通道。

当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流。这时候你就可以想象数据好像在这其中“流”动一样。

一般来说关于流的特性有下面几点:

  • 先进先出:最先写入输出流的数据最先被输入流读取到。
  • 顺序存取:可以一个接一个地往流中写入一串字节,读出时也将按写入顺序读取一串字节,不能随机访问中间的数据。(RandomAccessFile除外)
  • 只读或只写:每个流只能是输入流或输出流的一种,不能同时具备两个功能,输入流只能进行读操作,对输出流只能进行写操作。在一个数据传输通道中,如果既要写入数据,又要读取数据,则要分别提供两个流。

按传输方式划分


虽然 IO 类很多,但核心的就是 4 个抽象类:InputStream、OutputStream、Reader、Writer。

虽然 IO 类的方法也很多,但核心的也就 2 个:read 和 write。

InputStream 类

  • int read():读取数据
  • int read(byte b[], int off, int len):从第 off 位置开始读,读取 len 长度的字节,然后放入数组 b 中
  • long skip(long n):跳过指定个数的字节
  • int available():返回可读的字节数
  • void close():关闭流,释放资源

OutputStream 类

  • void write(int b): 写入一个字节,虽然参数是一个 int 类型,但只有低 8 位才会写入,高 24 位会舍弃(这块后面再讲)
  • void write(byte b[], int off, int len): 将数组 b 中的从 off 位置开始,长度为 len 的字节写入
  • void flush(): 强制刷新,将缓冲区的数据写入
  • void close():关闭流

Reader 类

  • int read():读取单个字符
  • int read(char cbuf[], int off, int len):从第 off 位置开始读,读取 len 长度的字符,然后放入数组 b 中
  • long skip(long n):跳过指定个数的字符
  • int ready():是否可以读了
  • void close():关闭流,释放资源

Writer 类

  • void write(int c): 写入一个字符
  • void write( char cbuf[], int off, int len): 将数组 cbuf 中的从 off 位置开始,长度为 len 的字符写入
  • void flush(): 强制刷新,将缓冲区的数据写入
  • void close():关闭流

字节流和字符流的区别:

  • 字节流一般用来处理图像、视频、音频、PPT、Word等类型的文件。字符流一般用于处理纯文本类型的文件,如TXT文件等,但不能处理图像视频等非文本文件。用一句话说就是:字节流可以处理一切文件,而字符流只能处理纯文本文件。
  • 字节流本身没有缓冲区,缓冲字节流相对于字节流,效率提升非常高。而字符流本身就带有缓冲区,缓冲字符流相对于字符流效率提升就不是那么大了。

以写文件为例,我们查看字符流 Writer 的源码,发现确实有利用到缓冲区:

// 声明一个 char 类型的数组,用于写入输出流
private char[] writeBuffer;// 定义 writeBuffer 数组的大小,必须 >= 1
private static final int WRITE_BUFFER_SIZE = 1024;// 写入给定字符串中的一部分到输出流中
public void write(String str, int off, int len) throws IOException {// 使用 synchronized 关键字同步代码块,确保线程安全synchronized (lock) {char cbuf[];// 如果 len <= WRITE_BUFFER_SIZE,则使用 writeBuffer 数组进行写入if (len <= WRITE_BUFFER_SIZE) {// 如果 writeBuffer 为 null,则创建一个大小为 WRITE_BUFFER_SIZE 的新 char 数组if (writeBuffer == null) {writeBuffer = new char[WRITE_BUFFER_SIZE];}cbuf = writeBuffer;} else {    // 如果 len > WRITE_BUFFER_SIZE,则不永久分配非常大的缓冲区// 创建一个大小为 len 的新 char 数组cbuf = new char[len];}// 将 str 中的一部分(从 off 开始,长度为 len)拷贝到 cbuf 数组中str.getChars(off, (off + len), cbuf, 0);// 将 cbuf 数组中的数据写入输出流中write(cbuf, 0, len);}
}

再以文件的字符流和字节流来做一下对比,代码差别很小。

// 字节流
try (FileInputStream fis = new FileInputStream("input.txt");FileOutputStream fos = new FileOutputStream("output.txt")) {byte[] buffer = new byte[1024];int len;while ((len = fis.read(buffer)) != -1) {fos.write(buffer, 0, len);}
} catch (IOException e) {e.printStackTrace();
}// 字符流
try (FileReader fr = new FileReader("input.txt");FileWriter fw = new FileWriter("output.txt")) {char[] buffer = new char[1024];int len;while ((len = fr.read(buffer)) != -1) {fw.write(buffer, 0, len);}
} catch (IOException e) {e.printStackTrace();
}

按操作对象划分


文件

文件流也就是直接操作文件的流,可以细分为字节流(FileInputStream 和 FileOuputStream)和字符流(FileReader 和 FileWriter)。

FileInputStream 的例子:

// 声明一个 int 类型的变量 b,用于存储读取到的字节
int b;
// 创建一个 FileInputStream 对象,用于读取文件 fis.txt 中的数据
FileInputStream fis1 = new FileInputStream("fis.txt");// 循环读取文件中的数据
while ((b = fis1.read()) != -1) {// 将读取到的字节转换为对应的 ASCII 字符,并输出到控制台System.out.println((char)b);
}// 关闭 FileInputStream 对象,释放资源
fis1.close();

FileOutputStream 的例子:

// 创建一个 FileOutputStream 对象,用于写入数据到文件 fos.txt 中
FileOutputStream fos = new FileOutputStream("fos.txt");// 向文件中写入数据,这里写入的是字符串 "haha" 对应的字节数组
fos.write("haha".getBytes());// 关闭 FileOutputStream 对象,释放资源
fos.close();

FileReader 的例子:

// 声明一个 int 类型的变量 b,用于存储读取到的字符
int b = 0;// 创建一个 FileReader 对象,用于读取文件 read.txt 中的数据
FileReader fileReader = new FileReader("read.txt");// 循环读取文件中的数据
while ((b = fileReader.read()) != -1) {// 将读取到的字符强制转换为 char 类型,并输出到控制台System.out.println((char)b);
}// 关闭 FileReader 对象,释放资源
fileReader.close();

FileWriter 的例子:

// 创建一个 FileWriter 对象,用于写入数据到文件 fw.txt 中
FileWriter fileWriter = new FileWriter("fw.txt");// 将字符串 "xx" 转换为字符数组
char[] chars = "xx".toCharArray();// 向文件中写入数据,这里写入的是 chars 数组中的所有字符
fileWriter.write(chars, 0, chars.length);// 关闭 FileWriter 对象,释放资源
fileWriter.close();

文件流还可以用于创建、删除、重命名文件等操作。FileOutputStream 和 FileWriter 构造函数的第二个参数可以指定是否追加数据到文件末尾。

// 创建文件
File file = new File("test.txt");
if (file.createNewFile()) {System.out.println("文件创建成功");
} else {System.out.println("文件已存在");
}// 删除文件
if (file.delete()) {System.out.println("文件删除成功");
} else {System.out.println("文件删除失败");
}// 重命名文件
File oldFile = new File("old.txt");
File newFile = new File("new.txt");
if (oldFile.renameTo(newFile)) {System.out.println("文件重命名成功");
} else {System.out.println("文件重命名失败");
}

数组(内存)

通常来说,针对文件的读写操作,使用文件流配合缓冲流就够用了,但为了提升效率,频繁地读写文件并不是太好,那么就出现了数组流,有时候也称为内存流。

ByteArrayInputStream 的例子:

// 创建一个 ByteArrayInputStream 对象,用于从字节数组中读取数据
InputStream is = new BufferedInputStream(new ByteArrayInputStream("xx".getBytes(StandardCharsets.UTF_8)));// 定义一个字节数组用于存储读取到的数据
byte[] flush = new byte[1024];// 定义一个变量用于存储每次读取到的字节数
int len = 0;// 循环读取字节数组中的数据,并输出到控制台
while (-1 != (len = is.read(flush))) {// 将读取到的字节转换为对应的字符串,并输出到控制台System.out.println(new String(flush, 0, len));
}// 关闭输入流,释放资源
is.close();

ByteArrayOutputStream 的例子:

// 创建一个 ByteArrayOutputStream 对象,用于写入数据到内存缓冲区中
ByteArrayOutputStream bos = new ByteArrayOutputStream();// 定义一个字节数组用于存储要写入内存缓冲区中的数据
byte[] info = "xx".getBytes();// 向内存缓冲区中写入数据,这里写入的是 info 数组中的所有字节
bos.write(info, 0, info.length);// 将内存缓冲区中的数据转换为字节数组
byte[] dest = bos.toByteArray();// 关闭 ByteArrayOutputStream 对象,释放资源
bos.close();

数组流可以用于在内存中读写数据,比如将数据存储在字节数组中进行压缩、加密、序列化等操作。它的优点是不需要创建临时文件,可以提高程序的效率。但是,数组流也有缺点,它只能存储有限的数据量,如果存储的数据量过大,会导致内存溢出。

管道

Java 中的管道和 Unix/Linux 中的管道不同,在 Unix/Linux 中,不同的进程之间可以通过管道来通信,但 Java 中,通信的双方必须在同一个进程中,也就是在同一个 JVM 中,管道为线程之间的通信提供了通信能力。

一个线程通过 PipedOutputStream 写入的数据可以被另外一个线程通过相关联的 PipedInputStream 读取出来。

// 创建一个 PipedOutputStream 对象和一个 PipedInputStream 对象
final PipedOutputStream pipedOutputStream = new PipedOutputStream();
final PipedInputStream pipedInputStream = new PipedInputStream(pipedOutputStream);// 创建一个线程,向 PipedOutputStream 中写入数据
Thread thread1 = new Thread(new Runnable() {@Overridepublic void run() {try {// 将字符串 "xx" 转换为字节数组,并写入到 PipedOutputStream 中pipedOutputStream.write("xx".getBytes(StandardCharsets.UTF_8));// 关闭 PipedOutputStream,释放资源pipedOutputStream.close();} catch (IOException e) {e.printStackTrace();}}
});// 创建一个线程,从 PipedInputStream 中读取数据并输出到控制台
Thread thread2 = new Thread(new Runnable() {@Overridepublic void run() {try {// 定义一个字节数组用于存储读取到的数据byte[] flush = new byte[1024];// 定义一个变量用于存储每次读取到的字节数int len = 0;// 循环读取字节数组中的数据,并输出到控制台while (-1 != (len = pipedInputStream.read(flush))) {// 将读取到的字节转换为对应的字符串,并输出到控制台System.out.println(new String(flush, 0, len));}// 关闭 PipedInputStream,释放资源pipedInputStream.close();} catch (IOException e) {e.printStackTrace();}}
});// 启动线程1和线程2
thread1.start();
thread2.start();

使用管道流可以实现不同线程之间的数据传输,可以用于线程间的通信、数据的传递等。但是,管道流也有一些局限性,比如只能在同一个 JVM 中的线程之间使用,不能跨越不同的 JVM 进程。

基本数据类型

基本数据类型输入输出流是一个字节流,该流不仅可以读写字节和字符,还可以读写基本数据类型。

DataInputStream 提供了一系列可以读基本数据类型的方法:

// 创建一个 DataInputStream 对象,用于从文件中读取数据
DataInputStream dis = new DataInputStream(new FileInputStream("das.txt"));// 读取一个字节,将其转换为 byte 类型
byte b = dis.readByte();// 读取两个字节,将其转换为 short 类型
short s = dis.readShort();// 读取四个字节,将其转换为 int 类型
int i = dis.readInt();// 读取八个字节,将其转换为 long 类型
long l = dis.readLong();// 读取四个字节,将其转换为 float 类型
float f = dis.readFloat();// 读取八个字节,将其转换为 double 类型
double d = dis.readDouble();// 读取一个字节,将其转换为 boolean 类型
boolean bb = dis.readBoolean();// 读取两个字节,将其转换为 char 类型
char ch = dis.readChar();// 关闭 DataInputStream,释放资源
dis.close();

DataOutputStream 提供了一系列可以写基本数据类型的方法:

// 创建一个 DataOutputStream 对象,用于将数据写入到文件中
DataOutputStream das = new DataOutputStream(new FileOutputStream("das.txt"));// 将一个 byte 类型的数据写入到文件中
das.writeByte(10);// 将一个 short 类型的数据写入到文件中
das.writeShort(100);// 将一个 int 类型的数据写入到文件中
das.writeInt(1000);// 将一个 long 类型的数据写入到文件中
das.writeLong(10000L);// 将一个 float 类型的数据写入到文件中
das.writeFloat(12.34F);// 将一个 double 类型的数据写入到文件中
das.writeDouble(12.56);// 将一个 boolean 类型的数据写入到文件中
das.writeBoolean(true);// 将一个 char 类型的数据写入到文件中
das.writeChar('A');// 关闭 DataOutputStream,释放资源
das.close();

除了 DataInputStream 和 DataOutputStream,Java IO 还提供了其他一些读写基本数据类型和字符串的流类,包括 ObjectInputStream 和 ObjectOutputStream(用于读写对象)。

public static void main(String[] args) {try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.dat"))) {Person p = new Person("xx", 20);oos.writeObject(p);} catch (IOException e) {e.printStackTrace();}try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.dat"))) {Person p = (Person) ois.readObject();System.out.println(p);} catch (IOException | ClassNotFoundException e) {e.printStackTrace();}
}

以上代码创建了一个 Person 对象,将其写入文件中,然后从文件中读取该对象,并打印在控制台上。

缓冲

为了减少程序和硬盘的交互,提升程序的效率,就引入了缓冲流,也就是类名前缀带有 Buffer 的那些,比如说 BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter。

缓冲流在内存中设置了一个缓冲区,只有缓冲区存储了足够多的带操作的数据后,才会和内存或者硬盘进行交互。简单来说,就是一次多读/写点,少读/写几次,这样程序的性能就会提高。

以下是一个使用 BufferedInputStream 读取文件的示例代码:

// 创建一个 BufferedInputStream 对象,用于从文件中读取数据
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("data.txt"));// 创建一个字节数组,作为缓存区
byte[] buffer = new byte[1024];// 读取文件中的数据,并将其存储到缓存区中
int bytesRead;
while ((bytesRead = bis.read(buffer)) != -1) {// 对缓存区中的数据进行处理// 这里只是简单地将读取到的字节数组转换为字符串并打印出来System.out.println(new String(buffer, 0, bytesRead));
}// 关闭 BufferedInputStream,释放资源
bis.close();

上述代码中,首先创建了一个 BufferedInputStream 对象,用于从文件中读取数据。然后创建了一个字节数组作为缓存区,每次读取数据时将数据存储到缓存区中。读取数据的过程是通过 while 循环实现的,每次读取数据后对缓存区中的数据进行处理。最后关闭 BufferedInputStream,释放资源。

以下是一个使用 BufferedOutputStream 写入文件的示例代码:

// 创建一个 BufferedOutputStream 对象,用于将数据写入到文件中
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("data.txt"));// 创建一个字节数组,作为缓存区
byte[] buffer = new byte[1024];// 将数据写入到文件中
String data = "xx";
buffer = data.getBytes();
bos.write(buffer);// 刷新缓存区,将缓存区中的数据写入到文件中
bos.flush();// 关闭 BufferedOutputStream,释放资源
bos.close();

上述代码中,首先创建了一个 BufferedOutputStream 对象,用于将数据写入到文件中。然后创建了一个字节数组作为缓存区,将数据写入到缓存区中。写入数据的过程是通过 write() 方法实现的,将字节数组作为参数传递给 write() 方法即可。

最后,通过 flush() 方法将缓存区中的数据写入到文件中。在写入数据时,由于使用了 BufferedOutputStream,数据会先被写入到缓存区中,只有在缓存区被填满或者调用了 flush() 方法时才会将缓存区中的数据写入到文件中。

以下是一个使用 BufferedReader 读取文件的示例代码:

// 创建一个 BufferedReader 对象,用于从文件中读取数据
BufferedReader br = new BufferedReader(new FileReader("data.txt"));// 读取文件中的数据,并将其存储到字符串中
String line;
while ((line = br.readLine()) != null) {// 对读取到的数据进行处理// 这里只是简单地将读取到的每一行字符串打印出来System.out.println(line);
}// 关闭 BufferedReader,释放资源
br.close();

上述代码中,首先创建了一个 BufferedReader 对象,用于从文件中读取数据。然后使用 readLine() 方法读取文件中的数据,每次读取一行数据并将其存储到一个字符串中。读取数据的过程是通过 while 循环实现的。

以下是一个使用 BufferedWriter 写入文件的示例代码:

// 创建一个 BufferedWriter 对象,用于将数据写入到文件中
BufferedWriter bw = new BufferedWriter(new FileWriter("data.txt"));// 将数据写入到文件中
String data = "xx";
bw.write(data);// 刷新缓存区,将缓存区中的数据写入到文件中
bw.flush();// 关闭 BufferedWriter,释放资源
bw.close();

上述代码中,首先创建了一个 BufferedWriter 对象,用于将数据写入到文件中。然后使用 write() 方法将数据写入到缓存区中,写入数据的过程和使用 FileWriter 类似。需要注意的是,使用 BufferedWriter 写入数据时,数据会先被写入到缓存区中,只有在缓存区被填满或者调用了 flush() 方法时才会将缓存区中的数据写入到文件中。

最后,通过 flush() 方法将缓存区中的数据写入到文件中,并通过 close() 方法关闭 BufferedWriter,释放资源。

使用缓冲流可以提高读写效率,减少了频繁的读写磁盘或网络的次数,从而提高了程序的性能。但是,在使用缓冲流时需要注意缓冲区的大小和清空缓冲区的时机,以避免数据丢失或不完整的问题。

打印

Java 的打印流是一组用于打印输出数据的类,包括 PrintStream 和 PrintWriter 两个类。

System.out 其实返回的就是一个 PrintStream 对象,可以用来打印各式各样的对象。

PrintStream 最终输出的是字节数据,而 PrintWriter 则是扩展了 Writer 接口,所以它的 print()/println() 方法最终输出的是字符数据。使用上几乎和 PrintStream 一模一样。

StringWriter buffer = new StringWriter();
try (PrintWriter pw = new PrintWriter(buffer)) {pw.println("xx");
}
System.out.println(buffer.toString());

序列化

序列化本质上是将一个 Java 对象转成字节数组,然后可以将其保存到文件中,或者通过网络传输到远程。

// 创建一个 ByteArrayOutputStream 对象 buffer,用于存储数据
ByteArrayOutputStream buffer = new ByteArrayOutputStream();// 使用 try-with-resources 语句创建一个 ObjectOutputStream 对象 output,并将其与 buffer 关联
try (ObjectOutputStream output = new ObjectOutputStream(buffer)) {// 使用 writeUTF() 方法将字符串 "xx" 写入到缓冲区中output.writeUTF("xx");
}// 使用 toByteArray() 方法将缓冲区中的数据转换成字节数组,并输出到控制台
System.out.println(Arrays.toString(buffer.toByteArray()));

与其对应的,有序列化,就有反序列化,也就是再将字节数组转成 Java 对象的过程。

try (ObjectInputStream input = new ObjectInputStream(new FileInputStream(new File("Person.txt")))) {String s = input.readUTF();
}

这段代码主要使用了 Java 的 ByteArrayOutputStream 和 ObjectOutputStream 类,将字符串 "xx" 写入到一个字节数组缓冲区中,并将缓冲区中的数据转换成字节数组输出到控制台。

具体的执行过程如下:

  • 创建一个 ByteArrayOutputStream 对象 buffer,用于存储数据。
  • 使用 try-with-resources 语句创建一个 ObjectOutputStream 对象 output,并将其与 buffer 关联。
  • 使用 writeUTF() 方法将字符串 "xx" 写入到缓冲区中。
  • 当 try-with-resources 语句执行完毕时,会自动调用 output 的 close() 方法关闭输出流,释放资源。
  • 使用 toByteArray() 方法将缓冲区中的数据转换成字节数组。
  • 使用 Arrays.toString() 方法将字节数组转换成字符串,并输出到控制台。

转换

InputStreamReader 是从字节流到字符流的桥连接,它使用指定的字符集读取字节并将它们解码为字符。

// 创建一个 InputStreamReader 对象 isr,使用 FileInputStream 对象读取文件 demo.txt 的内容并将其转换为字符流
InputStreamReader isr = new InputStreamReader(new FileInputStream("demo.txt"));// 创建一个字符数组 cha,用于存储读取的字符数据,其中 1024 表示数组的长度
char[] cha = new char[1024];// 使用 read() 方法读取 isr 中的数据,并将读取的字符数据存储到 cha 数组中,返回值 len 表示读取的字符数
int len = isr.read(cha);// 将 cha 数组中从下标 0 开始、长度为 len 的部分转换成字符串,并输出到控制台
System.out.println(new String(cha, 0, len));// 关闭 InputStreamReader 对象 isr,释放资源
isr.close();

这段代码主要使用了 Java 的 InputStreamReader 和 FileInputStream 类,从文件 demo.txt 中读取数据并将其转换为字符流,然后将读取的字符数据存储到一个字符数组中,并输出转换成字符串后的结果到控制台。

OutputStreamWriter 将一个字符流的输出对象变为字节流的输出对象,是字符流通向字节流的桥梁。

// 创建一个 File 对象 f,表示文件 test.txt
File f = new File("test.txt");// 创建一个 OutputStreamWriter 对象 out,使用 FileOutputStream 对象将数据写入到文件 f 中,并将字节流转换成字符流
Writer out = new OutputStreamWriter(new FileOutputStream(f));// 使用 write() 方法将字符串 "xx" 写入到文件 f 中
out.write("xx");// 关闭 Writer 对象 out,释放资源
out.close();

使用转换流可以方便地在字节流和字符流之间进行转换。在进行文本文件读写时,通常使用字符流进行操作,而在进行网络传输或与设备进行通信时,通常使用字节流进行操作。

另外,在使用转换流时需要注意字符编码的问题。如果不指定字符编码,则使用默认的字符编码,可能会出现乱码问题。因此,建议在使用转换流时,始终指定正确的字符编码,以避免出现乱码问题。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java JDK8新增时间类

生成的都是不可变对象,改动内容会存入新对象,原对象不变

C#使用Spire.Doc打印时候出现红字Evaluation Warning: The document was created with Spire.Doc for .NET.

问题 1.使用Spire.Doc 功能输出word 时,文件头部出现 解决方案 2.使用免费版的包 FreeSpire.Docdotnet add package FreeSpire.Doc

记一次 信息服务平台 “维权”

记录一次找寻网站售后客服的“小苦难”记录一次 爱合租 网站找寻客服的小艰辛太长不看: 最后借助于 风鸟 查询企业名, 从而联系上了相关人员 背景 涉及平台是一个软件服务"发车"平台, 简单来说就是为其用户提供各家软件会员合订的一个平台 我自己在上面当了一段时间的…

Kubernetes externalIPs 类型服务

背景:在k8s中用到的比较到多的是ClusterIP和NodePort类型的service,externalIPs则很少使用。我们现在了解一下其用法和它的一些优缺点。 官方定义: 如果有路由到一个或多个集群节点的外部 IP,则可以在这些 IP 上公开 Kubernetes 服务。在服务端口上使用外部 IP(作为目标 I…

智慧校园:定义未来教育的蓝图

智慧校园管理平台,是集信息技术与教育教学深度融合的产物,它以大数据、云计算、物联网、人工智能等前沿技术为核心,构建了一个高度信息化、智能化的校园生态系统。这一平台不仅仅是技术的堆砌,更是教育理念与管理模式的全面升级,旨在打造安全、高效、个性化的学习环境,促…

Jmeter简单接口测试

说明:Jmeter和对应jdk的下载及安装说明,在笔者的其他文章里面可以找到,这里不再赘述,笔者使用的是Jmeter5.3和jdk1.8 1.在开始讲之前,先讲一下如何看接口信息,一般情况下,开发会有接口文档,如果没有的话,可以在谷歌浏览器按F12抓包,看接口的信息,包括服务器地址,端…

前端部署工具

前端部署工具 用electron写了一个通用的前端部署工具,支持SSH的理论上都可以使用该工具,使用nodejs实现模拟登陆以及上传文件到服务器并解压 链接: https://pan.baidu.com/s/1rGnAO4X_xfv90UecuAMFkA?pwd=2mte 提取码: 2mte本文来自博客园,作者:小万子呀,转载请注明原文链…

Go--创建以当前时间命名的excel文件

下载依赖包go get -u github.com/xuri/excelize/v2 代码package mainimport ("fmt""github.com/xuri/excelize/v2""time" )func main() {// 获取当前时间now := time.Now()filename := fmt.Sprintf("%s.xlsx", now.Format("2006…

今日迷惑行为大赏

多测的意义何在?是好兄弟就 一起不换行我本地真的过编了1 我本地真的过编了2本地-LOCAL确实能过编,但你交上去呢

hostapd 配置文件示例

b模式:2.4G 20MHz# 接口和驱动程序设置 interface=wlan0 driver=nl80211 ctrl_interface=/var/run/hostapd​# 基本网络设置 ssid=TestAP hw_mode=b channel=11​# WPA身份验证设置 wpa=2 wpa_key_mgmt=WPA-PSK wpa_passphrase=12345678​# 加密算法设置 wpa_pairwise=CCMP rs…

SQL实战从在职到离职(1) 如何处理连续查询

书接上回,最近离职在家了实在无聊,除了看看考研的书,打打dnf手游,也就只能写写代码,结果昨晚挂在某平台的一个技术出售有人下单了,大概业务是需要帮忙辅导一些面试需要用到的SQL。 回想了下,在该平台接单SQL也超过3w元了,考察的也就是那几大类,我准备开一个新的专题,…

三,搭建环境:事务控制

三,搭建环境:事务控制 @目录三,搭建环境:事务控制声明式事务配置注解写法查询操作增删改操作声明式事务配置 在 demo-module01-web 的模块下的,spring-persist.xml 配置文件中开启基于注解的声明式事务支持<!-- 配置事务管理器 --><bean id="transactionMan…