【Linux】基础IO流(上)
文章目录
- 1. 预备知识
- 2. 回忆C接口
- fopen
- fputs
- fprintf
- snprintf
- 追加方式—— a
- 以读方式—— r
- 3.操作系统如何进行读写文件操作
- open
- 操作系统是如何让用户给自己传递标志位的
- 理解标记位的问题
- 新创建文件权限不正确
- 解决 umask的权限
- write
- 默认不会对原始文件清空
- 系统层面追加
- 系统层面 读取
- 总结
1. 预备知识
文件= 内容+属性
对应文件的操作,对内容的操作,对属性的操作
当文件没有被操作的时候,一般在磁盘中
当对文件进行操作的时候,一般在内存中,因为冯诺依曼体系规定
当我们对文件进行操作的时候,文件需要提前加载到内存中,提前加载的是属性
当我们对文件进行操作的时候,文件需要提前加载到内存中,不只有你在load,内存中一定存在大量的不同文件属性
- 打开文件本质就是将需要的属性加载到内存中,OS内部一定会同时存在大量的被打开的文件,操作系统就会通过先描述,在组织的方式管理这些被打开的文件
- 先描述,构建在内存中的文件结构体 struct file{ 文件属性,struct
file*next},表明被打开的文件 每一个被打开的文件,都要在OS内对应 文件对象的struct
结构体,可以将所有的struct结构体通过某种数据结构链接起来,在OS内部,对被打开的文件进行管理,就会转换为对链表的增删查改
结论:文件被打开,OS要为被打开的文件,创建对应的内核数据结构,struct file结构体 ,该结构体包含各种属性,各种链接关系
2. 回忆C接口
fopen
FILE *fopen(const char *path, const char *mode);
第一个参数为 打开文件对应的路径
第二个参数为 打开文件对应的权限
如果打开成功,返回FILE指针,否则返回NULL
创建myfile.c文件
E>#include<stdio.h> #define LOG "log.txt"
E>int main() { FILE*fp= fopen(LOG,"w"); //默认写方式 打开文件,如果文件不存在,就创建它 if(fp==NULL) { perror("fopen");//报错 return 1; } fclose(fp); //关闭文件 return 0; }
fputs
int fputs(const char *s, FILE *stream);
你想要写的字符串,写入特定的流当中,成功返回字符串字符个数,失败返回-1
#include<stdio.h> #define LOG "log.txt"
int main() { FILE*fp= fopen(LOG,"w"); //默认写方式 打开文件,如果文件不存在,就创建它 if(fp==NULL) { perror("fopen");//报错 return 1; } //进行文件操作 const char*msg="bbb\n"; fputs(msg,fp); fclose(fp); //关闭文件 return 0; }
将msg字符串中的数据写入fp流中
fprintf
int fprintf(FILE *stream, const char *format, …);
指定文件流,向文件打印

指定文件流fp,而fp打开的文件为log.txt,所以将msg数据打印到log.txt文件中
因为Linux中一切皆文件,所以也可以传入stdout(标准输出流)中,stdout也对应一个文件,即显示器文件


运行可执行程序,结果显示到显示器了
snprintf
int snprintf(char *str, size_t size, const char *format, …);
通过格式化流的方式,把字符串信息自定义格式化到字符串缓冲区中,并规定大小

将msg中的数据打印到buffer字符串中,同时使用fputs将buffer中的数据写入刚刚打开的文件log.txt中
追加方式—— a
追加,不会清空文件,而是每一次写入都是从文件尾部写入的
修改myfile.c文件内容
#include<stdio.h>
#define LOG "log.txt"
int main()
{ FILE*fp= fopen(LOG,"a"); //默认写方式 打开文件,如果文件不存在,就创建它 if(fp==NULL)
{ perror("fopen");//报错 return 1;
} //进行文件操作
const char*msg="bbb\n"; int cnt=1; while(cnt)
{ fputs(msg,fp); cnt--;
}
fclose(fp); //关闭文件 return 0;
}
多次运行可执行程序,发现可追加

以读方式—— r
char *fgets(char *s, int size, FILE *stream);
从特定的文件流中按行所取对应的文件,将读到的内容放到缓冲区中
修改myfile.c文件内容
#include<stdio.h>
#define LOG "log.txt"
int main()
{ FILE*fp= fopen(LOG,"r"); if(fp==NULL)
{ perror("fopen");//报错 return 1;
} //进行文件操作
while(1)
{ char line[128]; if(fgets(line,sizeof(line),fp)==NULL) break; else { printf("%s",line); }
}
fclose(fp); //关闭文件 return 0;
}
从fp中读取到line中,如果当前读取返回NULL说明读取失败 ,返回break

此时运行可执行程序,即可看到对应文件中的内容
3.操作系统如何进行读写文件操作
open
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
第一个参数代表 文件路径+文件名
第二个参数 代表 文件对应的选项(选项的问题后面会提)
如果打开成功了,就会返回新的文件描述符,如果打开失败,返回 -1
操作系统是如何让用户给自己传递标志位的
1. 我们怎么做
通过写一个 函数 若 int XXX (int flag) ,传递参数flag flag=1/2/3 ,将flag进行赋值
2. 系统怎么做
操作系统存在系统调用接口 int YYY (int flag),flag作为一个整数,有32个比特位,可以用一个比特位表示一个标志位
,一个int 就可以同时传递至少32个标记位
此时的flag 就可以看作数据类型 位图 看待
理解标记位的问题
创建test.c文件
#include<stdio.h>
//分别代表从右向左的每个比特位
#define ONE 0x1
#define TWO 0x2
#define THREE 0x4
#define FOUR 0x8
void print(int flag)
{ if(flag & ONE ) printf("hello 1\n");//充当函数的不同行为 if(flag & TWO) printf("hello 2\n"); if(flag & THREE) printf("hello 3\n"); if (flag & FOUR) printf("hello 4\n"); }
int main()
{ printf("-------------------------------------\n"); print(ONE); //打印one printf("-------------------------------------\n"); print(ONE|TWO); //打印one two printf("-------------------------------------\n"); print (ONE|TWO|THREE);//打印 one two three printf("-------------------------------------\n"); print (ONE|TWO|THREE|FOUR); //打印 one two three four printf("-------------------------------------\n"); return 0;
}
通过整数flag 一次传递多个标志位
0000 0000
将最后的四个比特位通过宏的方式分别记录下来
再与flag 按位与 ,若为真,则说明传递的flag 是 这4个比特位中的其中一个
执行可执行程序,此时分别打印出了 one two three four的运行结果

类比上述 open的第二个参数flag ,存在多个标志位,同通过宏来实现,每一个标志位都代表不同的值
新创建文件权限不正确
- O_CREAT :文件不存在就打开,不存在就创建一个文件
- O_WRONLY: 以写方式打开文件
在myfile.c文件中重新输入代码
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
#include<unistd.h>
#define LOG "log.txt"
int main()
{ int fd=open(LOG, O_WRONLY| O_CREAT);//打开一个文件,若文件不存在则重新创建一个if(fd==-1)//说明打开失败{printf("fd:%d,errno:%d,errstring:%s\n",fd,errno,strerror(errno));//打印出错误信息}else printf("fd :%d\n", fd); close(fd); //关闭文件 return 0;
}
运行可执行程序,发现

假设log.txt文件不存在,通过创建文件并打开文件,发现新文件的权限不正常
因为在Linux中创建一个文件需要有对应的权限的
int open(const char *pathname, int flags, mode_t mode);
所以在文件不存在时,一般采用有三个参数接口的open
mode代表权限
修改myfile.c文件的内容
#include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<stdio.h> #include<unistd.h> #include<errno.h>#define LOG "log.txt" int main() { int fd=open(LOG, O_WRONLY| O_CREAT,0666);//打开一个文件,若文件不存在则重新创建一个 if(fd==-1)//说明打开失败 {
E> printf("fd:%d,errno:%d,errstring:%s\n",fd,errno,strerror(errno));//打印出错误信息 } else printf("fd :%d\n", fd); close(fd); //关闭文件 return 0; }
0666 :拥有者 所属组 other都有读写权限

此时log.txt文件拥有正常的权限
但是输入的是666 ,显示的却是664,即other没有写权限
因为创建一个文件时,默认权限受到umask的影响
解决 umask的权限
使用 man 2 umask
查看
#include <sys/types.h>
#include <sys/stat.h>
mode_t umask(mode_t mask);
可以影响当前进程启动时,属于自己的umask,采取就近原则,因为自己设置离的更近所以使用自己设置的umask
而不是系统的umask
修改myfile.c文件的内容
#include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<stdio.h> #include<unistd.h> #include<errno.h> #define LOG "log.txt" int main() { umask (0);//将权限掩码设置成0 int fd=open(LOG, O_WRONLY| O_CREAT,0666);//打开一个文件,若文件不存在则重新创建一个 if(fd==-1)//说明打开失败 { printf("fd:%d,errno:%d,errstring:%s\n",fd,errno,strerror(errno));//打印出错误信息 } else printf("fd :%d\n", fd); close(fd); //关闭文件 return 0; }
使用umask (0) 将权限掩码设置成0

此时log.txt文件的权限为 666
write
通过 man 2 write
查看文件写入接口
ssize_t write(int fd, const void *buf, size_t count);
fd代表文件描述符
buf代表 缓冲区
count代表 缓冲区大小
write将缓冲区的count大小的数据写入 fd中
返回值代表实际写入多少字节
修改myfile.c文件内容
include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#define LOG "log.txt"
int main()
{ umask (0);//将权限掩码设置成0 int fd=open(LOG, O_WRONLY| O_CREAT,0666);//打开一个文件,若文件不存在则重新创建一个 if(fd==-1)//说明打开失败 { printf("fd:%d,errno:%d,errstring:%s\n",fd,errno,strerror(errno));//打印出错误信息 } else printf("fd :%d\n", fd); const char* msg="hello world"; int cnt=5; while(cnt) { char line[128]; snprintf(line,sizeof(line),"%s,%d\n",msg,cnt);//将msg和cnt写入line缓冲区中 write(fd,line,strlen(line)+1);//将line写入fd中 cnt--; } close(fd); //关闭文件 return 0;
}
若 strlen(line)+1 ,则打开log.txt文件时发现出现乱码,因为数字0在ASCII表中属于不可显示字符
所以为了不出现乱码,所以strlen(line) 不应该+1,因为\0是c语言的规定,不是文件的规定
修改myfile.c文件内容
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#define LOG "log.txt"
int main()
{ umask (0);//将权限掩码设置成0 int fd=open(LOG, O_WRONLY| O_CREAT,0666);//打开一个文件,若文件不存在则重新创建一个 if(fd==-1)//说明打开失败 { printf("fd:%d,errno:%d,errstring:%s\n",fd,errno,strerror(errno));//打印出错误信息 } else printf("fd :%d\n", fd); const char* msg="hello world"; int cnt=5; while(cnt) { char line[128]; snprintf(line,sizeof(line),"%s,%d\n",msg,cnt);//将msg和cnt写入line缓冲区中 write(fd,line,strlen(line));//将line写入fd中 strlen不要+1 cnt--; } close(fd); //关闭文件 return 0;
}
此时strlen不加1
默认不会对原始文件清空
修改myfile.c文件内容,msg和cnt的数据内容
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#define LOG "log.txt"
int main()
{ umask (0);//将权限掩码设置成0 int fd=open(LOG, O_WRONLY| O_CREAT,0666);//打开一个文件,若文件不存在则重新创建一个 if(fd==-1)//说明打开失败 { printf("fd:%d,errno:%d,errstring:%s\n",fd,errno,strerror(errno));//打印出错误信息 } else printf("fd :%d\n", fd); const char* msg="aaaaa"; int cnt=1; while(cnt) { char line[128]; snprintf(line,sizeof(line),"%s,%d\n",msg,cnt);//将msg和cnt写入line缓冲区中 write(fd,line,strlen(line));//将line写入fd中 strlen不要+1 cnt--; } close(fd); //关闭文件 return 0;
}
O_WRONLY | O_CREAT 默认不会对原始文件清空
O_TRUNC : 将文件做清空
修改myfile.c文件内容
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#define LOG "log.txt"
int main()
{ umask (0);//将权限掩码设置成0 int fd=open(LOG, O_WRONLY| O_CREAT| O_TRUNC,0666 );//打开一个文件,若文件不存在则重新创建一个 if(fd==-1)//说明打开失败 { printf("fd:%d,errno:%d,errstring:%s\n",fd,errno,strerror(errno));//打印出错误信息 } else printf("fd :%d\n", fd); const char* msg="aaaaa"; int cnt=1; while(cnt) { char line[128]; snprintf(line,sizeof(line),"%s,%d\n",msg,cnt);//将msg和cnt写入line缓冲区中 write(fd,line,strlen(line));//将line写入fd中 strlen不要+1 cnt--; } close(fd); //关闭文件 return 0;
}

此时再次调用log.txt文件,就会将之前文件中内容清空’
系统层面追加
O_APPEND 追加
O_WRONLY: 以写方式打开文件
O_WRONLY | O_APPEND | O_CREAT 若文件存在就以写的方式追加,若文件不存在则创建
修改myfile.c文件内容
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#define LOG "log.txt"
int main()
{ umask (0);//将权限掩码设置成0 int fd=open(LOG,O_WRONLY | O_CREAT | O_APPEND ,0666 );//打开一个文件,若文件不存在则重新创建一个 if(fd==-1)//说明打开失败 { printf("fd:%d,errno:%d,errstring:%s\n",fd,errno,strerror(errno));//打印出错误信息 } else printf("fd :%d\n", fd); const char* msg="bbb"; int cnt=1; while(cnt) { char line[128]; snprintf(line,sizeof(line),"%s,%d\n",msg,cnt);//将msg和cnt写入line缓冲区中 write(fd,line,strlen(line));//将line写入fd中 strlen不要+1 cnt--; } close(fd); //关闭文件 return 0;
}

此时重复运行可执行程序,打开log.txt文件 ,发现可以追加
系统层面 读取
O_RDONLY : 读取
输入 man 2 read
ssize_t read(int fd, void *buf, size_t count);
从文件描述符fd中将我们想要的数据,按照数据块的方式读取出来
返回值代表多少字节,读取到文件结尾为0,失败为-1
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#define LOG "log.txt"
int main()
{ umask (0);//将权限掩码设置成0 int fd=open(LOG, O_RDONLY );//打开一个文件,若文件不存在则重新创建一个 if(fd==-1)//说明打开失败 { printf("fd:%d,errno:%d,errstring:%s\n",fd,errno,strerror(errno));//打印出错误信息 } else printf("fd :%d\n", fd); char buffer[1024]; ssize_t n= read(fd,buffer,sizeof(buffer)-1);//使用系统接口来进行IO的时候,一定要注意\0的问题 if(n>0)//成功了,实际读到了多少字节 { buffer[n]='\0'; printf("%s\n",buffer); } close(fd); //关闭文件 return 0;
}

运行可执行程序,可以直接读取到数据
总结
操作系统不相信任何用户,所以操作系统给用户提供系统调用
程序员调用库的接口,而库的接口必定要调用系统调用
打开文件的本质是文件相关的内容加载到内存里
把数据触发从磁盘到内存
把数据从自己的程序写入硬盘上,一定会涉及到对硬件的访问
用户不能使用c/c++库绕过操作系统去访问
软硬件各种资源属于操作系统的,操作系统是硬件的管理者
相关文章:

【Linux】基础IO流(上)
文章目录1. 预备知识2. 回忆C接口fopenfputsfprintfsnprintf追加方式—— a以读方式—— r3.操作系统如何进行读写文件操作open操作系统是如何让用户给自己传递标志位的理解标记位的问题新创建文件权限不正确解决 umask的权限write默认不会对原始文件清空系统层面追加系统层面 …...

【C++】类和对象三大特性--多态
文章目录1. 多态的基本概念2. 多态的定义及实现2.1多态的构成条件2.2 虚函数2.3虚函数的重写2.4 虚函数不能重写和检查是否重写 (C11 )2.5 重载、覆盖(重写)、隐藏(重定义)的对比3. 纯虚函数和抽象类3.1 概念3.2 接口继承和实现继承4.多态的实现原理4.1虚…...
【微前端】qiankun + vite + vue3
专栏: 【微前端】什么是微前端【微前端】qiankun【微前端】qiankun vite vue3 一、整体结构 在 qiankun 体系下,一个微前端工程包含一个主应用和多个子应用。本质上,每个工程(主应用)都可以单独开发、运行。 1.1…...
模型部署之TorchScript
一.关于torchscript和jit介绍 1.关于torchscript TorchScript是Pytorch模型(继承自nn.Module)的中间表示,保存后的torchscript模型可以在像C这种高性能的环境中运行 TorchScript是一种从PyTorch代码创建可序列化和可优化模型的方法。任何T…...

修改linux网卡配置文件的文件名
修改linux网卡配置文件的文件名 查看自己系统中网卡配置文件的文件名 #查看网卡的配置文件名,已经网络的状态 ip a查看系统是否可以使用ifconfig命令 #输入命令 ifconfig #出现以下图片表示ifconfig的命令可用。可能出现的错误:ifconfig command no foun…...

年轻人为啥热衷去寺庙?
年轻人的苦,寺庙最清楚。 周末的寺庙挤满了年轻人,北京雍和宫限流了,杭州灵隐寺十八籽的手串限购了,南京鸡鸣寺从地铁站出口就开始排队了...... “上班和上学,你选择哪个?” ”我选择上香“ 工作和学习…...
Java Spring 框架
当今世界,Java Spring 成为了最流行的 Java 开发框架之一。Spring 框架是一个轻量级的、高效的框架,它是 Java 应用程序开发的理想选择。在本文中,我们将深入探讨 Java Spring 框架的特性、优点以及如何使用它来构建高质量的应用程序。 1.Ja…...

基于OpenCV的人脸识别
目录 🥩 前言 🍖 环境使用 🍖 模块使用 🍖 模块介绍 🍖 模块安装问题: 🥩 OpenCV 简介 🍖 安装 OpenCV 模块 🥩 OpenCV 基本使用 🍖 读取图片 🍗 【…...

一文带你看懂电压放大器和功率放大器的区别
很多人对于电压放大器和功率放大器总是分不太清,在实际应用过程中,电压放大器和功率放大器所起到的作用都是相同的。对于功率放大器和电压放大器的区别,今天就让安泰电子来带我们一起看看。功率放大器和电压放大器的主要区别是:功…...

C++虚函数与多态
C虚函数与多态虚函数抽象类纯虚函数虚析构函数多态虚函数的几个问题纯虚函数和ADT虚函数 virtual修饰的成员函数就是虚函数, 1.虚函数对类的内存影响:增加一个指针类型大小(32位和64位) 2.无论有多少个虚函数,只增加一…...

蓝桥杯Web前端练习-----渐变色背景生成器
介绍 相信做过前端开发的小伙伴们对渐变色在 UI 设计中的流行度一定不陌生,网页上也时常可以看到各类复杂的渐变色生成工具。使用原生的 CSS 变量加一些 JS 函数就能做出一个简单的渐变色背景生成器。 现在渐变色生成器只完成了颜色选取的功能,需要大家…...
Python中的微型巨人-Flask
文章目录前言主要内容优点及特性主要使用创建实例定义路由获取请求定制响应渲染Jinja2模板重定向和反向解析抛出HTTP异常总结更多宝藏前言 😎🥳😎🤠😮🤖🙈💭🍳…...
密码学中的承诺
Commitment 概述 密码学承诺是一个涉及两方的二阶段交互协议,双方分别为承诺方和接收方。简述来说,它的功能涵盖不可更改性和确定性。 承诺方发送的消息密文,一旦发出就意味着不会再更改,而接收方收到这个消息可以进行验证结果。…...
redis入门实战一、五种数据结构的基本操作(二)
redis入门实战一、五种数据结构的基本操作【二】 一、String1)、set2)、getset3)、msetnx 给多个元素赋值,原子操作4)、字符串 追加 & 取部分数据5)、数值可以做加减,指定增量大小6)、获取长度7)、 bitmap①、setbit②、bitop 二进制与或运算(效率高)③、bitcou…...
day13 模块和异常捕获总结
day13 模块和异常捕获 一、生成器 (一)、什么是生成器 1)容器(是一种可以创建多个数据的容器),生成器中保存的是创建数据的方法,而不是数据本身。2)特点: a. 打印生成…...

【Linux】进程优先级 环境变量
进程优先级 环境变量 一、进程优先级1、基本概念2、查看以及修改系统进程的优先级3、一些其他的关于进程优先级的指令和函数调用4、与进程优先级有关的一些进程性质二、环境变量1、基本概念2、和环境变量相关的命令3、Linux中的常见环境变量介绍4、环境变量的组织方式以及在C代…...

UE实现建筑分层抽屉展示效果
文章目录 1.实现目标2.实现过程2.1 基础设置2.2 核心函数3.参考资料1.实现目标 使用时间轴对建筑楼层的位置偏移进行控制,实现分层抽屉的动画展示效果。 2.实现过程 建筑抽屉的实现原理比较简单,即对Actor的位置进行偏移,计算并更新其世界位置即可。这里还是基于ArchVizExp…...

【C语言进阶:刨根究底字符串函数】 strstr 函数
本节重点内容: 深入理解strstr函数的使用学会strstr函数的模拟实现⚡strstr strstr的基本使用: #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include<string.h>int main() {char arr1[] "abcdebcdef";char arr2[] &…...

SpringBoot实战(十二)集成Actuator
目录一、简介二、Maven依赖三、使用入门1.HTTP 方式访问端点2.JMX 方式访问端点3.端点信息整理4.端点的启用与禁用5.端点的公开6.保护 HTTP 端点7.配置 CORS 跨域官方文档: https://docs.spring.io/spring-boot/docs/2.4.5/reference/htmlsingle/#production-ready …...

学习系统编程No.7【进程替换】
引言: 北京时间:2023/3/21/7:17,这篇博客本来昨天晚上就能开始写的,但是由于笔试强训的原因,导致时间用在了做题上,通过快2个小时的垂死挣扎,我充分意识到了自己做题能力的缺陷和运用新知识的缺…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...