当前位置: 首页 > news >正文

Linux dd 命令详解:工作原理与实用指南(C/C++代码实现)

这段代码是一个模仿 Linux dd 命令的工具,它用于在不同文件之间复制数据。dd 是一个非常强大的命令行工具,可以用于数据备份、转换和复制。下面我将详细解释这段代码的原理、实现方式以及如何运行和测试。

Linux dd 命令的工作原理

dd 命令是 Unix 和 Linux 系统中非常强大的文件复制和转换工具。它通过指定块大小(block size)来读取和写入数据,实现高效的文件或设备复制。dd 命令不仅能够处理普通文件,还能直接操作设备文件,这使得它在系统备份、恢复和数据克隆等任务中非常有用。

  1. 基本语法dd if=输入文件 of=输出文件 [选项]

    • if:指定输入文件名或设备名。
    • of:指定输出文件名或设备名。
    • [选项]:各种可选参数,用于控制复制行为。
  2. 常用选项

    • bs:设置读写的块大小。例如:bs=4M
    • count:复制的块数。例如:count=1
    • conv:指定数据转换选项,如 conv=sync 确保同步模式。
    • status=progress:显示详细的进度信息。
  3. 工作流程

    • 打开源和目标文件/设备:dd 命令会先尝试打开指定的输入和输出文件或设备。
    • 按块读取和写入:根据指定的块大小(bs),dd 从输入文件或设备读取数据,并写入到输出文件或设备中。
    • 数据处理:在读写过程中,dd 可以根据指定的转换选项对数据进行处理,如大小写转换、字节顺序转换等。
    • 重复操作:上述过程会根据指定的块数(count)反复进行,直到完成所有数据的复制或转换。

命令行使用

dd 的基本命令行格式如下:

dd if=<input_file> of=<output_file> [其他参数]
  • if:指定输入文件。
  • of:指定输出文件。

以下是一些常用的参数示例:

  • bs:设置块大小,例如 bs=1024
  • count:设置复制的块数,例如 count=10
  • skip:设置跳过的块数,例如 skip=5
  • seek:设置输出文件中跳过的块数,例如 seek=5

示例

复制一个文件的前 10MB 到另一个文件:

dd if=/dev/zero of=example.img bs=1M count=10

将一个磁盘分区备份到另一个磁盘分区:

dd if=/dev/sda of=/dev/sdb

基本文件复制:

dd if=inputfile of of=outputfile bs=64K count=1

将 inputfile 复制到 outputfile,每次读取和写入 64KB 的数据块,只复制一个块。

备份和还原硬盘:

dd if=/dev/sda of=/path/to/backup.img bs=4M 
dd if=/path/to/backup.img of=/dev/sdb bs=4M 

将整个硬盘 /dev/sda 备份到 backup.img 文件中,然后将 backup.img 还原到 /dev/sdb。

创建镜像文件:

dd if=/dev/zero of=imagefile.img bs=1G count=10

创建一个名为 imagefile.img 的 10GB 镜像文件,内容全为零。

制作启动盘:

dd if=boot.img of=/dev/sdb bs=4M 

将 boot.img 写入到 USB 设备 /dev/sdb,制作可启动的 USB 盘。

擦除硬盘数据:

dd if=/dev/urandom of of=/dev/sda bs=4M 

使用随机数据覆盖整个硬盘,确保数据无法恢复。

日常定位分析

dd 命令在系统恢复、数据恢复和磁盘克隆等场景中非常有用。例如,当你需要从一个损坏的文件系统中恢复数据时,可以使用 dd 来复制文件系统的一部分到另一个健康的磁盘上,然后对复制的数据进行分析和恢复。

三、dd 命令在实际工作中的定位与分析

dd 命令因其强大的功能和灵活性,在系统管理和运维工作中有着广泛的应用场景。以下是几个典型的应用场景及其分析:

  1. 系统备份与恢复

    • 场景:定期备份服务器上的硬盘或分区,以防数据丢失或系统故障。
    • 分析:通过 dd 命令,可以创建整个硬盘或分区的镜像文件,方便存储和快速恢复。此外,还可以使用压缩工具(如 gzip)进一步减小镜像文件的大小。
  2. 数据克隆和迁移

    • 场景:在更换硬盘或迁移数据时,需要将旧硬盘上的数据完整复制到新硬盘。
    • 分析:dd 命令可以直接操作设备文件,无需经过文件系统,从而提高数据复制的效率和可靠性。这对于大规模数据迁移尤其有用。
  3. 制作启动盘和恢复盘

    • 场景:需要制作可启动的 USB 盘或 CD/DVD,用于系统安装或故障排查。
    • 分析:dd 命令可以将 ISO 镜像文件直接写入到 USB 或光盘设备,操作简单且高效。这在紧急情况下尤为重要,如系统崩溃后的恢复工作。
  4. 安全删除数据

    • 场景:需要彻底删除敏感数据,确保无法通过恢复工具找回。
    • 分析:通过用随机数据覆盖硬盘,可以有效防止数据被恢复。这种方法比单纯的文件删除更为安全,适用于处理包含敏感信息的硬盘。
  5. 性能测试

    • 场景:测试磁盘的读写速度,评估存储设备的性能。
    • 分析:dd 命令可以生成大规模的测试数据,并通过计时等方式测量磁盘的读写速度。这对于存储设备的选型和性能优化具有重要参考价值。

Linux dd 命令详解:工作原理与实用指南(C/C++代码实现)

size_t free_mem()
{uint64_t n = 0;char buf[1024], found = 0;FILE *f = fopen("/proc/meminfo", "r");if (!f)return 1024*1024;memset(buf, 0, sizeof(buf));for (;!feof(f);) {fgets(buf, sizeof(buf), f);if (strstr(buf, "MemFree:")) {found = 1;break;}}fclose(f);if (!found)return 1024*1024;n = strtoul(buf + 9, NULL, 10);if (!n)return 1024*1024;/* kB? */if (strchr(buf + 9, 'k'))n <<= 10;else if (strchr(buf + 9, 'M'))n <<= 20;return n/2;
}...#ifdef ANDROIDint copy_splice(struct dd_config *);int copy_splice_cores(struct dd_config *ddc)
{return copy_splice(ddc);
}#else
int copy_splice_cores(struct dd_config *ddc)
{int ifd, ofd, p[2] = {-1, -1};ssize_t r = 0, cpu_size = 0;size_t n = 0, min_bs = 4096;cpu_set_t *cpu_set = NULL;if (prepare_copy(ddc, &ifd, &ofd) < 0)return -1;if ((cpu_set = CPU_ALLOC(2)) == NULL) {close(ifd); close(ofd);return -1;}cpu_size = CPU_ALLOC_SIZE(2);CPU_ZERO_S(cpu_size, cpu_set);if (pipe(p) < 0) {ddc->saved_errno = errno;close(ifd); close(ofd);close(p[0]); close(p[1]);return -1;}#ifdef F_SETPIPE_SZfor (n = 29; n >= 20; --n) {if (fcntl(p[0], F_SETPIPE_SZ, 1<<n) != -1)break;}
#endifn = ddc->bs;if (fork() == 0) {/* bind to CPU#0 */CPU_SET_S(ddc->cores - 1, cpu_size, cpu_set);sched_setaffinity(0, cpu_size, cpu_set);close(p[0]);for (;ddc->b_in != ddc->count && !sigint;) {if (n > ddc->count - ddc->b_in)n = ddc->count - ddc->b_in;r = splice(ifd, NULL, p[1], NULL, n, SPLICE_F_MORE|SPLICE_F_NONBLOCK);if (r == 0)break;if (r < 0) {if (errno != EAGAIN)break;/* If running out of pipe buffer, decrease bs */r = 0;n = min_bs;}ddc->b_in += r;}exit(0);}/* bind to CPU#1 */CPU_SET_S(ddc->cores - 2, cpu_size, cpu_set);sched_setaffinity(0, cpu_size, cpu_set);for (;ddc->b_out != ddc->count;) {r = splice(p[0], NULL, ofd, NULL, n, SPLICE_F_MORE);if (r <= 0) {ddc->saved_errno = errno;break;}ddc->b_out += r;++ddc->rec_out;}ddc->rec_in = ddc->rec_out;close(ifd);close(ofd);close(p[0]);close(p[1]);wait(NULL);if (r < 0)return -1;return 0;
}
#endifint copy_splice(struct dd_config *ddc)
{
...if (prepare_copy(ddc, &ifd, &ofd) < 0)return -1;if (pipe(p) < 0) {ddc->saved_errno = errno;close(ifd); close(ofd);close(p[0]); close(p[1]);return -1;}#ifdef F_SETPIPE_SZfor (n = 29; n >= 20; --n) {if (fcntl(p[0], F_SETPIPE_SZ, 1<<n) != -1)break;}
#endifn = ddc->bs;for (;ddc->b_out != ddc->count && !sigint;) {if (n > ddc->count - ddc->b_out)n = ddc->count - ddc->b_out;r = splice(ifd, NULL, p[1], NULL, n, SPLICE_F_MORE);if (r <= 0) {ddc->saved_errno = errno;break;}++ddc->rec_in;r = splice(p[0], NULL, ofd, NULL, r, SPLICE_F_MORE);if (r <= 0) {ddc->saved_errno = errno;break;}ddc->b_out += r;++ddc->rec_out;}close(ifd);close(ofd);close(p[0]);close(p[1]);if (r < 0)return -1;return 0;
}int copy_mmap(struct dd_config *ddc)
{
...if (prepare_copy(ddc, &ifd, &ofd) < 0)return -1;if (ddc->fsize != (off_t)-1) {if (ftruncate(ofd, ddc->fsize) < 0) {ddc->saved_errno = errno;close(ifd);close(ofd);return -1;}}for (;ddc->b_out != ddc->count && !sigint;) {n = ddc->mmap;bs = ddc->bs;if (n > ddc->count - ddc->b_out)n = ddc->count - ddc->b_out;if (bs > n)bs = n;if (ddc->fsize == (off_t)-1) {if (ftruncate(ofd, ddc->b_out + n) < 0) {ddc->saved_errno = errno;break;}}addr = mmap(NULL, n, PROT_WRITE, MAP_SHARED, ofd, ddc->b_out + ddc->skip);if (addr == MAP_FAILED) {ddc->saved_errno = errno;break;}for (i = 0; i < n; i += r) {if (i + bs > n)bs = n - i;r = read(ifd, addr + i, bs);if (r <= 0) {ddc->saved_errno = errno;munmap(addr, n);break;}ddc->b_out += r;++ddc->rec_in;}...}if (ddc->fsize != ddc->b_out)ftruncate(ofd, ddc->b_out);close(ifd);close(ofd);if (r < 0 || addr == MAP_FAILED)return -1;return 0;
}int copy_sendfile(struct dd_config *ddc)
{
...off = ddc->skip;n = ddc->bs;for (;ddc->b_out < ddc->count && !sigint;) {if (n > ddc->count - ddc->b_out)n = ddc->count - ddc->b_out;r = sendfile(ofd, ifd, &off, n);if (r < 0) {ddc->saved_errno = errno;ret = -1;break;}++ddc->rec_in; ++ddc->rec_out;ddc->b_in += r;ddc->b_out += r;}close(ifd);close(ofd);return ret;
}int copy(struct dd_config *ddc)
{
...if (ddc->cores)r = copy_splice_cores(ddc);else if (ddc->mmap)r = copy_mmap(ddc);else if (ddc->sf)r = copy_sendfile(ddc);elser = copy_splice(ddc);ddc->t_end = time(NULL);/* 避免div为零 */if (ddc->t_start == ddc->t_end)++ddc->t_end;return r;
}void print_stat(const struct dd_config *ddc)
{
...#ifdef ANDROIDfprintf(stderr, "%llu records in\n%llu records out\n%llu bytes (%llu MB) copied, %lu s, %f MB/s [%f mB/s]\n",ddc->rec_in, ddc->rec_out, ddc->b_out, ddc->b_out/(1<<20),ddc->t_end - ddc->t_start,((double)(ddc->b_out/(1<<20)))/(ddc->t_end - ddc->t_start),((double)(ddc->b_out/(1000*1000)))/(ddc->t_end - ddc->t_start));
#elsefprintf(stderr, "%lu records in\n%lu records out\n%lu bytes (%lu MB) copied, %lu s, %f MB/s [%f mB/s]\n",ddc->rec_in, ddc->rec_out, ddc->b_out, ddc->b_out/(1<<20),ddc->t_end - ddc->t_start,((double)(ddc->b_out/(1<<20)))/(ddc->t_end - ddc->t_start),((double)(ddc->b_out/(1000*1000)))/(ddc->t_end - ddc->t_start));
#endif}void sig_int(int x)
{fprintf(stderr, "SIGINT! Aborting ...\n");sigint = 1;return;
}int main(int argc, char **argv)
{
...config.bs = 1<<16;config.in = "/dev/stdin";config.out = "/dev/stdout";/* 模拟“dd”参数解析 */for (i = 1; i < argc; ++i) {if (strcmp(argv[i], "-h") == 0 ||strcmp(argv[i], "--help") == 0)usage(argv[0]);memset(buf, 0, sizeof(buf));if (sscanf(argv[i], "if=%1023c", buf) == 1)config.in = strdup(buf);else if (sscanf(argv[i], "of=%1023c", buf) == 1)config.out = strdup(buf);else if (sscanf(argv[i], "skip=%1023c", buf) == 1)config.skip = strtoul(buf, NULL, 10);else if (sscanf(argv[i], "seek=%1023c", buf) == 1)config.seek = strtoul(buf, NULL, 10);else if (sscanf(argv[i], "count=%1023c", buf) == 1)config.count = strtoul(buf, NULL, 10);else if (sscanf(argv[i], "mmap=%1023c", buf) == 1) {if (!config.cores) {/* Size in MB */config.mmap = strtoul(buf, NULL, 10);config.mmap <<= 20;}} else if (sscanf(argv[i], "cores=%1023c", buf) == 1) {config.cores = strtoul(buf, NULL, 10);if (config.cores < 2)config.cores = 2;config.mmap = 0;} else if (strcmp(argv[i], "send") == 0) {config.sf = 1;} else if (strcmp(argv[i], "direct") == 0) {config.direct = 1;} else if (sscanf(argv[i], "bs=%1023c", buf) == 1) {config.bs = strtoul(buf, NULL, 10);} else if (strcmp(argv[i], "bs") == 0) {config.bs = 0;} else if (strcmp(argv[i], "quiet") == 0) {config.quiet = 1;} else if (strcmp(argv[i], "nosync") == 0) {config.nosync = 1;}}...return 0;
}

If you need the complete source code, please add the WeChat number (c17865354792)

编译完成后,你可以使用以下命令行参数来测试它:

./linux_dd if=<input_file> of=<output_file> [其他参数]

例如,你可以使用以下命令来复制一个文件:

./linux_dd if=/dev/stdin of=/dev/stdout bs=1024 count=1024

这个命令会从标准输入读取数据,并将数据写入到标准输出,每次复制 1024 字节,总共复制 1024 次。

代码中提供了多种复制策略:

  1. splice(2):使用 Linux 的 splice 系统调用来在管道和文件之间传输数据,这种方式可以有效地利用内核缓冲区,减少数据复制过程中的上下文切换。

  2. mmap(2):通过内存映射的方式直接在内存中操作文件数据,这种方式适用于大块数据的复制。

  3. sendfile(2):在内核层面直接将数据从一个文件描述符传输到另一个,减少了数据在用户空间的拷贝。

  4. 多核处理:代码还支持将数据复制任务分配到多个 CPU 核心上,以提高复制效率。

补充内容

  1. 安全性:在使用 dd 时,一定要小心指定正确的输入和输出文件,错误的命令可能会导致数据丢失。
  2. 效率:选择合适的块大小可以显著影响 dd 的性能。通常,较大的块大小可以提高复制速度。
  3. 错误处理dd 命令在执行过程中可能会遇到错误,了解如何解读错误信息对于解决问题至关重要。
  4. 日志记录dd 命令执行时可以重定向输出到日志文件,以便于事后分析。
  5. 进度监控:可以通过 status=progress 参数来监控 dd 命令的执行进度。

结语

dd 命令是一个功能强大的工具,它在 Linux 系统中扮演着重要的角色。了解其工作原理和使用方法,可以帮助你更有效地管理和操作数据。在使用时,务必谨慎,以避免不必要的数据损失。

Welcome to follow WeChat official account【程序猿编码

相关文章:

Linux dd 命令详解:工作原理与实用指南(C/C++代码实现)

这段代码是一个模仿 Linux dd 命令的工具&#xff0c;它用于在不同文件之间复制数据。dd 是一个非常强大的命令行工具&#xff0c;可以用于数据备份、转换和复制。下面我将详细解释这段代码的原理、实现方式以及如何运行和测试。 Linux dd 命令的工作原理 dd 命令是 Unix 和 …...

Golang学习历程【第一篇 入门】

Golang学习历程【第一篇 入门Hello World】 1. 学习文档2. Window 本地安装Go2.1 安装2.2 验证 3. 开发环境——VsCode3.1 VsCode 安装3.2 安装插件3.2.1 language 语言汉化插件安装3.2.2 Go插件安装 4. Hello World 入门4.1 建工程4.2 创建项目文件4.3 编写Hello World程序4.4…...

青少年编程与数学 02-004 Go语言Web编程 01课题、Web应用程序

青少年编程与数学 02-004 Go语言Web编程 01课题、Web应用程序 课题摘要:一、Web应用程序二、Web服务器&#xff08;一&#xff09;什么是Web服务器&#xff08;二&#xff09;Web服务器配置1. 选择服务器软件2. 安装服务器软件3. 配置服务器4. 安全设置5. 部署网站内容6. 测试服…...

【mysql】如何解决主从架构从库延迟问题

目录 1. 说明2.优化主库的写入性能3. 优化网络性能4. 增强从库的硬件性能5. 调整从库的配置6. 主从架构优化7. 监控和调优8.使用 GTID 和 Group Replication 1. 说明 1.在 MySQL 数据库中&#xff0c;从库延迟&#xff08;replication lag&#xff09;是指主库和从库之间的数据…...

前端学习-获取DOM对象(二十一)

目录 前言 目标 提问 学习路径 根据CSS选择器来获取DOM元素 其他获取DOM元素的方法 根据CSS选择器来获取DOM元素 选择匹配的第一个元素 语法 示例 参数 返回值 选择匹配的多个元素语法 参数 字符串返回值 示例 补充 其它获取DOM元素方法 根据id获取一个元素 …...

PCL点云库入门——PCL库中Eigen数学工具库的基本使用(持续更新)

0、前言 PCL点云库中的算法都基于Eigen数学工具库来实现的&#xff0c;因此&#xff0c;掌握Eigen库对于深入理解和应用PCL点云库至关重要。Eigen库不仅提供了高效的矩阵和向量运算&#xff0c;还支持复杂的线性代数、几何变换等操作&#xff0c;为PCL点云处理提供了强大的数学…...

CLion Inlay Hints - 取消 CLion 灰色的参数和类型提示

CLion Inlay Hints - 取消 CLion 灰色的参数和类型提示 1. Parameter hints for C/C1.1. Toggle parameter hints globally 2. Type hints for C/C2.1. Toggle type hints&#xfeff; globally 3. Toggle inlay hints globallyReferences https://www.jetbrains.com/help/clio…...

2025山东科技大学考研专业课复习资料一览

[冲刺]2025年山东科技大学020200应用经济学《814经济学之西方经济学[宏观部分]》考研学霸狂刷870题[简答论述计算题]1小时前[强化]2025年山东科技大学085600材料与化工《817物理化学》考研强化检测5套卷22小时前[冲刺]2025年山东科技大学030100法学《704综合一[法理学、国际法学…...

vue3 v-model实例之二,tab标签页的实现

<template><div><Tab v-model"activeTab" :list"tabs" /><div><p>当前激活的 Tab 索引: {{ activeTab }}</p></div></div> </template><script setup> import { ref } from vue; import Tab …...

东方通TongWeb7.0.4.9M4部署SuperMap iServer 11.2.1

一、软件版本 操作系统: CentOS Linux release 7.5.1804 (Core)JDK:11.0.18东方通&#xff1a;TongWeb7.0.4.9M4SuperMap iServer&#xff1a;11.2.1 JDK和TongWeb软件分享&#xff1a; 链接: https://pan.baidu.com/s/1HGDTPnPID0PEOMbg3FjTVQ?pwdbh8v 提取码: bh8v 东方通软…...

QT绘制同心扇形

void ChartForm::paintEvent(QPaintEvent *) {QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);// 设置抗锯齿painter.save();// 设置无边框&#xff08;不需要设置QPen&#xff0c;因为默认是不绘制边框的&#xff09;QPen pen(Qt::NoPen);// QPen pen…...

2012年西部数学奥林匹克试题(几何)

2012/G1 △ A B C \triangle ABC △ABC 内有一点 P P P, P P P 在 A B AB AB, A C AC AC 上的投影分别为 E E E, F F F, 射线 B P BP BP, C P CP CP 分别交 △ A B C \triangle ABC △ABC 的外接圆于点 M M M, N N N. r r r 为 △ A B C \triangle ABC △ABC 的内…...

8位移位寄存器的verilog语言

module shift_register (output reg [7:0] Q, // 8位移位寄存器输出input D, // 输入数据input rst, // 复位信号input clk // 时钟信号 );always (posedge clk) beginif (!rst)Q < 8b00000000; // 复位时将Q清零elseQ < {Q[6:0], D}; // 否则…...

【苍穹外卖】学习心得体会-随笔

前言 写了很久&#xff0c;终于可以完整运行项目了&#xff0c;记录下这几天的心得体会回顾一下知识点 第一天、Git 分布式版本控制工具 一、Git概述 定义&#xff1a;是分布式版本控制工具&#xff0c;用于管理软件开发中的源代码文件&#xff0c;像Java类、xml文件、html…...

MySQL学习之表的增删改

MySQL学习之表的增删改 语法总结&#xff1a; INSERT INTO 表名 (字段名1, 字段名2, ...) VALUES (值1, 值2, ...); //指定字段添加数据 INSERT INTO 表名 VALUES (值1, 值2, ...); //给全部字段添加数据 INSERT INTO 表名 VALUES (值1, 值2, ...), (值1, 值2, ...), (值1, …...

电脑excel词典(xllex.dll)文件丢失是或损坏是什么原因?“xllex.dll文件缺失“要怎么解决?

Excel词典&#xff08;xllex.dll&#xff09;文件丢失或损坏&#xff1f;别担心&#xff0c;这里有解决之道&#xff01; 在日常的电脑使用和办公软件操作中&#xff0c;我们偶尔会碰到一些让人头疼的问题&#xff0c;比如Excel突然提示“Excel词典&#xff08;xllex.dll&…...

【CSS in Depth 2 精译_084】第 14 章:CSS 蒙版、形状与剪切概述 + 14.1:CSS 滤镜

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第四部分 视觉增强技术 ✔️【第 14 章 蒙版、形状与剪切】 ✔️ 14.1 滤镜 ✔️ 14.1.1 滤镜的类型 ✔️14.1.2 背景滤镜 ✔️ 14.2 蒙版 文章目录 第 14 章 蒙版、形状与剪切 Masks, shapes, and…...

gorm源码解析(四):事务,预编译

文章目录 前言事务自己控制事务用 Transaction方法包装事务 预编译事务结合预编译总结 前言 前几篇文章介绍gorm的整体设计&#xff0c;增删改查的具体实现流程。本文将聚焦与事务和预编译部分 事务 自己控制事务 用gorm框架&#xff0c;可以自己控制事务的Begin&#xff0…...

前端优雅(装逼)写法(updating····)

1.>>右位移运算符取整数 它将一个数字的二进制位向右移动指定的位数&#xff0c;并在左侧填充符号位&#xff08;即负数用1填充&#xff0c;正数用0填充&#xff09;。 比如 2.99934 >> 0&#xff1a;取整结果是2&#xff0c;此处取整并非四舍五入 2.99934 会先…...

黑马Java面试教程_P7_常见集合_P4_HashMap

系列博客目录 文章目录 系列博客目录4. HashMap相关面试题4.4 面试题-HashMap的put方法的具体流程 频54.4.1 hashMap常见属性4.4.2 源码分析 HashMap的构造函数面试文稿&#xff1a; 4.5 讲一讲HashMap的扩容机制 难3频4面试文稿&#xff1a; 4.6 面试题-hashMap的寻址算法 难4…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

uniapp 小程序 学习(一)

利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 &#xff1a;开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置&#xff0c;将微信开发者工具放入到Hbuilder中&#xff0c; 打开后出现 如下 bug 解…...