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

【Android】问deepseek存储访问

这些天deepseek爆火,我们来问问android问题看看,如果问android中的应用怎么访问外部存储,回答的很清楚,但是如果问的深入一些,比如Android中是怎么控制让应用不能读取其他应用的外部存储文件的,回答的比较抽象,只是给出了大概的分析方向。但还是可以从中受到启发。

android中的应用怎么访问外部存储

好的,用户问的是“android中的应用怎么访问外部存储”。看起来他们可能已经对Android存储访问有一些了解,但需要更详细的步骤或最新版本的适配方法。首先,我需要回忆一下Android的存储权限变化,特别是从Android 10引入的作用域存储(Scoped Storage)带来的影响。用户可能已经知道早期版本中使用Environment.getExternalStorageDirectory()的方法,但现在需要适配新版本。

接下来,用户可能想知道如何正确地在不同版本中访问外部存储,包括如何请求权限、使用MediaStore访问媒体文件,以及如何处理非媒体文件。他们可能遇到了在Android 10及以上版本中无法直接通过文件路径访问的问题,所以需要指导如何使用Storage Access Framework(SAF)或者申请MANAGE_EXTERNAL_STORAGE权限。

另外,用户可能对如何兼容旧版本和新版本感到困惑,比如使用requestLegacyExternalStorage标记。需要解释这个标记的作用和适用条件,以及何时应该放弃使用它,转而遵循作用域存储的规范。

还需要考虑用户是否有特殊需求,比如访问所有文件,这时候需要提到MANAGE_EXTERNAL_STORAGE权限,但也要提醒他们Google Play对使用此权限的限制,避免滥用。此外,用户可能关心如何安全地处理文件描述符,避免资源泄漏,尤其是在跨进程传递文件描述符时。

最后,用户可能需要示例代码来具体实现各个步骤,包括动态权限请求、使用MediaStore查询文件、通过SAF选择文件等。要确保示例代码简洁明了,覆盖不同场景,同时指出注意事项和常见问题,比如权限拒绝处理、文件路径访问限制等。

在 Android 中访问外部存储(如 SD 卡或共享存储空间)需要遵循系统的权限规则和存储访问策略,尤其是从 Android 10(API 29) 开始引入的 作用域存储(Scoped Storage)。以下是详细的访问方法及适配不同 Android 版本的步骤:


1. 动态请求存储权限

根据 Android 版本请求对应的存储权限:

权限声明(AndroidManifest.xml)

xml

<!-- Android 13+ 媒体文件分类型权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /><!-- Android 10-12 通用媒体权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><!-- 全文件访问权限(需用户手动授权) -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
动态请求权限代码

kotlin

private fun checkStoragePermission() {val requiredPermissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {// Android 13+ 分类型媒体权限arrayOf(Manifest.permission.READ_MEDIA_IMAGES,Manifest.permission.READ_MEDIA_VIDEO)} else {arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE)}if (requiredPermissions.all { permission ->ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED}) {loadExternalFiles()} else {ActivityCompat.requestPermissions(this, requiredPermissions, REQUEST_CODE_STORAGE)}
}override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {super.onRequestPermissionsResult(requestCode, permissions, grantResults)if (requestCode == REQUEST_CODE_STORAGE && grantResults.all { it == PackageManager.PERMISSION_GRANTED }) {loadExternalFiles()}
}

2. 访问应用的私有目录

每个应用在外部存储中拥有独立的私有目录,路径为 Android/data/<包名>/ 或 Android/obb/<包名>/

代码示例

kotlin

复制

// 获取私有目录(如 Downloads、Pictures 等子目录)
val privateDir = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)// 创建或访问文件
val file = File(privateDir, "test.txt")
file.writeText("Hello World!")// 卸载应用时,系统会自动删除此目录

3. 访问公共媒体文件(图片、视频、音频)

使用 MediaStore API 访问公共媒体文件,这是 Android 10+ 的推荐方式。

查询图片文件示例

kotlin

复制

val projection = arrayOf(MediaStore.Images.Media._ID,MediaStore.Images.Media.DISPLAY_NAME,MediaStore.Images.Media.DATE_ADDED
)val sortOrder = "${MediaStore.Images.Media.DATE_ADDED} DESC"contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,projection,null,null,sortOrder
)?.use { cursor ->while (cursor.moveToNext()) {val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID))val uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id)// 通过 Uri 读取文件val inputStream = contentResolver.openInputStream(uri)// 处理文件流...}
}

4. 访问非媒体文件(文档、下载目录等)

使用 Storage Access Framework (SAF) 让用户主动选择文件或目录。

代码示例

kotlin

复制

// 打开文档选择器
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {addCategory(Intent.CATEGORY_OPENABLE)type = "*/*" // 允许选择任意类型文件
}
startActivityForResult(intent, REQUEST_CODE_OPEN_DOCUMENT)// 处理返回的 Uri
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {if (requestCode == REQUEST_CODE_OPEN_DOCUMENT && resultCode == RESULT_OK) {data?.data?.let { uri ->// 通过 Uri 读取文件contentResolver.openInputStream(uri)?.use { stream ->// 读取文件内容...}}}
}

5. 访问所有文件(需特殊权限)

从 Android 11(API 30) 开始,需申请 MANAGE_EXTERNAL_STORAGE 权限并跳转系统设置。

代码示例

kotlin

复制

// 检查是否已授权
if (Environment.isExternalStorageManager()) {// 已授权,可访问所有文件val files = File("/sdcard").listFiles()
} else {// 跳转到系统设置页val intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)startActivity(intent)
}

6. 兼容旧版本(Android 9 及以下)

若需临时禁用作用域存储,可在 AndroidManifest.xml 中添加 requestLegacyExternalStorage

xml

复制

<applicationandroid:requestLegacyExternalStorage="true"...>
</application>

运行 HTML

注意

  • 仅当 targetSdkVersion < 30 时有效。

  • Google Play 可能对使用此标记的应用进行审核。


关键限制

  1. 禁止直接路径访问
    Android 10+ 禁止通过 File 类直接访问非媒体文件(如 /sdcard/Download/file.txt)。

  2. 其他应用私有目录不可见
    /sdcard/Android/data/<其他应用包名> 对其他应用完全隔离。


总结

场景方法
应用私有文件getExternalFilesDir()
公共媒体文件MediaStore API + 动态权限
非媒体文件Storage Access Framework (SAF)
全文件访问MANAGE_EXTERNAL_STORAGE 权限(需用户手动授权)
旧版本兼容requestLegacyExternalStorage(仅限 targetSdkVersion < 30

开发者应优先使用 MediaStore 和 SAF,避免依赖绝对路径,以确保应用兼容未来 Android 版本。

问:

Android中是怎么控制让应用不能读取其他应用的外部存储文件的

嗯,用户之前问过几次关于Android应用如何访问外部存储的问题,现在他们又问Android是如何控制应用不能读取其他应用的外部存储文件的。看起来用户对Android的存储权限机制和隔离措施很感兴趣,可能是开发者或者安全研究人员,想深入了解系统底层的安全机制。

首先,我需要回顾之前的对话历史,用户已经了解了作用域存储、权限模型、文件路径隔离等内容。用户现在可能想知道更具体的技术实现,比如系统是如何在底层限制应用访问其他应用的数据的。

接下来,我需要考虑如何详细解释这些控制机制。可能需要从Linux文件权限、进程隔离、SELinux策略、虚拟文件系统等方面展开。同时,用户可能对具体的技术细节感兴趣,比如UID/GID如何分配,文件描述符的传递机制,以及Binder在跨进程通信中的作用。

用户之前的问题中提到了HIDL和文件描述符的传递,这可能意味着他们对底层IPC机制有一定了解。所以在回答时,可以适当深入这些方面,但也要保持清晰易懂,避免过于晦涩。

另外,用户可能想知道这些机制在不同Android版本中的差异,比如Android 10之后的作用域存储如何强化了这些限制。需要分版本说明,特别是Android 10和11的变化。

还要注意用户可能的误区,比如认为拥有存储权限就可以访问所有文件,但实际上作用域存储限制了这一点。需要澄清权限和路径访问的关系,以及系统如何通过组合权限检查和文件系统隔离来实现控制。

最后,确保回答结构清晰,分点说明,用技术术语但不过于复杂,同时举例子帮助理解。比如,通过示例说明应用A尝试访问应用B的私有目录时,系统如何拦截并阻止。

在 Android 中,系统通过 多层级的安全机制 实现应用之间外部存储文件的隔离,确保一个应用无法随意读取其他应用的外部存储文件。这些机制结合了 Linux 文件系统权限、沙盒隔离、权限模型和虚拟化技术,以下是具体实现原理:


1. Linux 文件系统权限

Android 基于 Linux 内核,继承其文件系统的权限控制:

  • UID/GID 隔离

    • 每个应用在安装时会被分配一个唯一的 用户 ID(UID) 和 组 ID(GID)

    • 应用私有目录(如 /sdcard/Android/data/<包名>)的权限默认设置为 0700(仅允许所属 UID 读写)。

    • 其他应用因 UID 不同,无法直接通过文件路径访问这些目录。

  • 权限位控制

    • 公共目录(如 /sdcard/DCIM)的权限通常为 0777(所有用户可读写),但通过 作用域存储 限制应用的实际访问能力。


2. 作用域存储(Scoped Storage,Android 10+)

从 Android 10 开始引入,进一步限制应用对外部存储的访问:

  • 虚拟文件系统(FUSE)

    • Android 使用 FUSE(用户态文件系统) 或 Samsung RFS 对 /sdcard 路径进行虚拟化。

    • 应用看到的 /sdcard 是一个虚拟视图,仅包含:

      • 自身私有目录(Android/data/<包名>)。

      • 通过 MediaStore 授权的公共媒体文件(图片、视频、音频)。

      • 用户通过 Storage Access Framework (SAF) 主动授权的文件。

  • 路径过滤

    • 当应用尝试访问 /sdcard/Android/data/<其他应用包名> 时,虚拟文件系统直接返回 文件不存在(ENOENT)

    • 即使应用拥有 READ_EXTERNAL_STORAGE 权限,也无法绕过此限制。


3. 权限模型(Runtime Permissions)

  • 存储权限分级

    • READ_EXTERNAL_STORAGE:允许读取公共媒体文件(Android 13 后细化为 READ_MEDIA_IMAGESREAD_MEDIA_VIDEO 等)。

    • WRITE_EXTERNAL_STORAGE:允许写入公共媒体文件(Android 10 后逐渐废弃)。

    • MANAGE_EXTERNAL_STORAGE:允许访问所有文件(需用户手动授权,Google Play 审核严格)。

  • 动态权限检查

    • 应用在访问公共目录时,系统会在 VFS(虚拟文件系统)层 隐式检查权限状态。

    • 若未授权,即使通过 File 类尝试访问文件,也会返回 权限错误(SecurityException)


4. 进程隔离与 SELinux

  • 沙盒机制

    • 每个应用运行在独立的进程空间,拥有自己的 UID 和 SELinux 上下文

    • SELinux 策略严格限制应用进程只能访问其所属的文件和目录。

  • Binder IPC 限制

    • 跨进程文件访问需通过 Binder 传递文件描述符(ParcelFileDescriptor),系统会在 IPC 过程中检查权限和所有权。


5. 合法访问途径

若应用需共享文件,必须通过以下 显式授权机制

  1. ContentProvider

    • 应用 A 实现 ContentProvider,通过 URI(如 content://com.appA.provider/file1)共享文件。

    • 应用 B 需通过 ContentResolver 查询 URI,并拥有对应的权限(如 android:readPermission)。

  2. FileProvider

    • 生成临时 URI(如 content://com.appA.fileprovider/files/file1),通过 Intent 传递给其他应用。

    • 临时 URI 可设置有效期和权限,接收方应用需通过 ContentResolver 访问。

  3. Storage Access Framework (SAF)

    • 用户通过系统文件选择器(如 Intent.ACTION_OPEN_DOCUMENT)主动授权访问特定文件或目录。


6. 示例:阻止访问的完整流程

假设 应用 A 尝试读取 应用 B 的私有文件 /sdcard/Android/data/com.appB/files/secret.txt

  1. 路径解析

    • 应用 A 调用 new File("/sdcard/Android/data/com.appB/files/secret.txt")

  2. 虚拟文件系统拦截

    • FUSE 发现路径属于其他应用的私有目录,直接返回 文件不存在(即使文件实际存在)。

  3. 权限检查

    • 若应用 A 尝试绕过虚拟路径(如直接操作 /data/media/...),SELinux 会阻止访问。

  4. 进程隔离

    • 即使应用 A 获取了 MANAGE_EXTERNAL_STORAGE 权限,系统仍会限制其访问其他应用的私有目录。


7. 绕过限制的例外情况

  • ROOT 设备

    • 拥有 Root 权限的应用可绕过所有限制(但普通用户设备极少开放 Root)。

  • 系统应用

    • 系统签名应用(如预装文件管理器)可能拥有更高权限,但需通过 Google 认证。


总结

Android 通过以下组合机制实现应用间外部存储的隔离:

机制作用
Linux 文件权限基于 UID/GID 的目录隔离
作用域存储(FUSE)虚拟化文件路径,隐藏其他应用的私有目录
运行时权限模型动态检查存储权限,限制公共目录访问
SELinux 策略强制进程隔离,禁止跨应用文件操作
安全的文件共享 API强制通过 ContentProviderFileProvider 或 SAF 显式授权

开发者应始终使用系统提供的 API(如 MediaStoreSAF)访问文件,避免直接操作路径,以确保兼容性和安全性。

相关文章:

【Android】问deepseek存储访问

这些天deepseek爆火&#xff0c;我们来问问android问题看看&#xff0c;如果问android中的应用怎么访问外部存储&#xff0c;回答的很清楚&#xff0c;但是如果问的深入一些&#xff0c;比如Android中是怎么控制让应用不能读取其他应用的外部存储文件的&#xff0c;回答的比较抽…...

Android记事本App设计开发项目实战教程2025最新版Android Studio

平时上课录了个视频&#xff0c;从新建工程到打包Apk&#xff0c;从头做到尾&#xff0c;没有遗漏任何实现细节&#xff0c;欢迎学过Android基础的同学参加&#xff0c;如果你做过其他终端软件开发&#xff0c;也可以学习&#xff0c;快速上手Android基础开发。 Android记事本课…...

python学习——函数的返回值

在 Python 中&#xff0c;函数的返回值决定了调用该函数后得到的结果。默认情况下&#xff0c;如果函数没有使用 return 语句或没有明确返回一个值&#xff0c;函数将返回 None。为了实现更复杂的逻辑&#xff0c;可以通过 return 语句返回多个值、错误信息或其他数据类型。 返…...

【竞技宝】裂变天地S1:BB0-2PARI淘汰出局

北京时间2月1日,DOTA2裂变天地S1继续进行,昨日共进行三场比赛,第三场比赛迎来败者组第二轮PARI对阵BB。以下是本场比赛的详细战报。 第一局: 首局比赛,BB在天辉方,PARI在夜魇方。阵容方面,BB点出了圣堂、卡尔、玛尔斯、奶绿、亚巴顿,PARI则是拿到小娜迦、凤凰、大圣、玛西、萨…...

数据分析系列--⑨RapidMiner训练集、测试集、验证集划分

一、数据集获取 二、划分数据集 1.导入和加载数据 2.数据集划分 2.1 划分说明 2.2 方法一 2.3 方法二 一、数据集获取 点击下载数据集 此数据集包含538312条数据. 二、划分数据集 1.导入和加载数据 2.数据集划分 2.1 划分说明 2.2 方法一 使用Filter Example Range算子. …...

实践Rust:编写一个猜数字游戏

如果你正在学习Rust&#xff0c;并且想通过一个有趣的小项目来巩固所学知识&#xff0c;那么“猜数字游戏”是一个绝佳的选择&#xff01;这个游戏的逻辑非常简单&#xff1a;程序会随机生成一个数字&#xff0c;玩家需要猜测这个数字是多少&#xff0c;程序会告诉玩家猜大了还…...

JavaFX - 3D 形状

在前面的章节中&#xff0c;我们已经了解了如何在 JavaFX 应用程序中的 XY 平面上绘制 2D 形状。除了这些 2D 形状之外&#xff0c;我们还可以使用 JavaFX 绘制其他几个 3D 形状。 通常&#xff0c;3D 形状是可以在 XYZ 平面上绘制的几何图形。它们由两个或多个维度定义&#…...

阿里新发的大模型Qwen2.5-max如何?

阿里新发布的大模型Qwen2.5-Max是一款性能卓越、技术先进的大型语言模型&#xff0c;其在多个方面展现了突出的表现。以下是基于我搜索到的资料对Qwen2.5-Max的详细评价&#xff1a; 技术特点 超大规模预训练数据&#xff1a;Qwen2.5-Max采用了超过20万亿tokens的超大规模预训…...

文本复制兼容方案最佳实现落地。

文章目录 一、navigator.clipboard.writeText二、方案落地总结 一、navigator.clipboard.writeText navigator.clipboard.writeText 是一个Web API&#xff0c;它允许网页脚本将文本数据写入用户的系统剪贴板。这个API是异步的&#xff0c;并且设计用于提高安全性和用户体验&a…...

x86-64数据传输指令

关于汇编语言一些基础概念的更详细的介绍&#xff0c;可移步MIPS指令集&#xff08;一&#xff09;基本操作_mips指令 sw-CSDN博客 该指令集中一个字2字节。 该架构有16个64位寄存器&#xff0c;名字都以%r开头&#xff0c;每个寄存器的最低位字节&#xff0c;低1~2位字节&…...

LigerUI在MVC模式下的响应原则

LigerUI是基于jQuery的UI框架&#xff0c;故他也是遵守jQuery的开发模式&#xff0c;但是也具有其特色的侦听函数&#xff0c;那么当LigerUI作为View层的时候&#xff0c;他所发送后端的必然是表单的数据&#xff0c;在此我们以俩个div为例&#xff1a; {Layout "~/View…...

java CountDownLatch和CyclicBarrier

专栏系列文章地址&#xff1a;https://blog.csdn.net/qq_26437925/article/details/145290162 本文目标&#xff1a; 理解CountDownLatch和CyclicBarrier的使用&#xff0c;主要是复习Aqs 另外工作中用到CountDownLatch的地方还很多&#xff0c;一般是完成某些事情才能继续某…...

力扣动态规划-17【算法学习day.111】

前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;建议灵神的题单和代码随想录&#xff09;和记录自己的学习过程&#xff0c;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关…...

读书笔记-《你的灯亮着吗?》

这是一本短篇且有趣的书&#xff0c;通过一些小故事讨论了下解决问题时会遇到的困难。 01 为什么难以定义问题 常言道&#xff0c;办法总比问题多&#xff0c;但往往我们在一开始就没有定义好问题&#xff1a; 在学校时&#xff0c;校园教育使得我们会紧紧抓住看起来像是“问题…...

MATLAB实现多种群遗传算法

多种群遗传算法&#xff08;MPGA, Multi-Population Genetic Algorithm&#xff09;是一种改进的遗传算法&#xff0c;它通过将种群分成多个子种群并在不同的子种群之间进行交叉和交换&#xff0c;旨在提高全局搜索能力并避免早期收敛。下面是多种群遗传算法的主要步骤和流程&a…...

tf.Keras (tf-1.15)使用记录3-model.compile方法

model.compile 是 TensorFlow Keras 中用于配置训练模型的方法。在开始训练之前&#xff0c;需要通过这个方法来指定模型的优化器、损失函数和评估指标等。 注意事项: 在开始训练&#xff08;调用 model.fit&#xff09;之前&#xff0c;必须先调用 model.compile()。 1 基本…...

Prometheus 中的 Exporter

在 Prometheus 生态系统中,Exporter 扮演着至关重要的角色,它们负责从不同的服务或系统中收集和暴露度量数据。本文将详细介绍 Exporter 的概念、类型以及如何有效使用它们将 Prometheus 集成到各种系统中进行监控。 什么是 Exporter? Exporter 是一段软件,它从应用程序或…...

网工_HDLC协议

2025.01.25&#xff1a;网工老姜学习笔记 第9节 HDLC协议 9.1 HDLC高级数据链路控制9.2 HDLC帧格式&#xff08;*控制字段&#xff09;9.2.1 信息帧&#xff08;承载用户数据&#xff0c;0开头&#xff09;9.2.2 监督帧&#xff08;帮助信息可靠传输&#xff0c;10开头&#xf…...

leetcode 2563. 统计公平数对的数目

题目如下 数据范围 显然数组长度最大可以到10的5次方n方的复杂度必然超时&#xff0c;阅读题目实际上就是寻找两个位置不同的数满足不等式即可(实际上i j无所谓是哪个 我们只要把位置小的想成i就行)。 按照上面的思路我们只需要排序数组然后从前往后遍历数组然后利用二分查找…...

Debian 10 中 Linux 4.19 内核在 x86_64 架构上对中断嵌套的支持情况

一、中断嵌套的定义与原理 中断嵌套是指在一个中断处理程序(ISR)正在执行的过程中,另一个更高优先级的中断请求到来,系统暂停当前中断处理程序,转而处理新的高优先级中断。处理完高优先级中断后,系统返回到原来的中断处理程序继续执行。这种机制允许系统更高效地响应紧急…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...