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

Flutter笔记:目录与文件存储以及在Flutter中的使用(下)

Flutter笔记
目录与文件存储以及在Flutter中的使用(下)
文件读写与Flutter中文件管理

作者李俊才 (jcLee95):https://blog.csdn.net/qq_28550263
邮箱 :291148484@163.com
本文地址:https://blog.csdn.net/qq_28550263/article/details/134499297


【简介】本文探讨了Dart和Flutter中的文件系统操作和文件存储。内容覆盖了Dart的文件系统基础,文件路径处理,文件读写操作及其优化(上),以及在Flutter中的文件读写相关注意的事项(下)。

上一节:《 目录与文件存储以及在Flutter中的使用(上)


1. Dart文件读写

本节将介绍 字节流 和 字符流 的基本概念、操作方法以及性能优化。

1.1 字节流(Byte Stream)

字节流是一种低级的输入输出流,它以字节为单位进行读写操作。字节流通常用于处理二进制数据,如图片、音频和视频等。

在Dart中,我们可以使用File类的openRead和openWrite方法来创建字节流。

以下是一些使用字节流进行文件读写的示例:

1.1.1 以字节流读取文件

使用 openRead 方法可以创建一个字节流,用于读取文件的内容。openRead 方法返回一个 Stream<List<int>> 对象,我们可以使用 Stream 的各种方法来处理字节流。

  /// 为此文件的内容创建一个新的独立 [Stream]。////// 如果 [start] 存在,将从字节偏移量 [start] 读取文件。否则从开始(索引0)。////// 如果 [end] 存在,只读取到字节索引 [end] 的字节。否则,直到文件结束。////// 为确保系统资源被释放,必须读取流到完成,或者取消对流的订阅。////// 如果 [File] 是一个 [命名管道](https://en.wikipedia.org/wiki/Named_pipe)/// 那么返回的 [Stream] 将等待管道的写入端关闭后才会发出 "done" 信号。如果在打开时管道没有连接的写入器,/// 那么 [Stream.listen] 将等待写入器打开管道。Stream<List<int>> openRead([int? start, int? end]);

例如:

import 'dart:io';void main() async {var file = File('test.txt');Stream<List<int>> inputStream = file.openRead();await for (var data in inputStream) {// 处理数据...}
}

在这个示例中,我们首先创建了一个字节流,然后使用await for循环来处理字节流中的数据。

1.1.2 以字节流写入文件

使用 openWrite 方法可以创建一个字节流,用于向文件中写入数据。openWrite 方法返回一个 IOSink 对象,我们可以使用IOSinkaddwrite 方法来写入数据。

// abstract interface class IOSink/// 将字节 [data] 添加到目标消费者,忽略 [encoding]。////// [encoding] 不适用于此方法,[data] 列表直接作为流事件传递给目标消费者。////// 当使用 [addStream] 添加流时,不应调用此方法。////// 此操作是非阻塞的。查看 [flush] 或 [done] 以获取此调用生成的任何错误。////// 传递给 `add` 后,不应修改数据列表,因为目标消费者接收列表的原始状态还是修改后的状态未定义。////// [data] 中的单个值如果不在 0 .. 255 的范围内,将被截断到其低8位,就像通过 [int.toUnsigned] 那样,然后再使用。void add(List<int> data);/// 通过调用 [Object.toString] 将 [object] 转换为字符串,并将结果的编码 [add] 到目标消费者。////// 此操作是非阻塞的。查看 [flush] 或 [done] 以获取此调用生成的任何错误。void write(Object? object);

例如:

import 'dart:io';void main() async {var file = File('test.txt');var outputStream = file.openWrite();outputStream.write('Hello, Dart!');await outputStream.close();
}

在这个示例中,我们首先创建了一个字节流,然后使用 write 方法向字节流中写入数据。最后,我们使用 close 方法关闭字节流。

1.2 字符流(Character Stream)

1.2.1 以字节流读取文件

字符流是一种高级的输入输出流,它以字符为单位进行读写操作。字符流通常用于处理文本数据。

Dart 中,我们可以使用 File 类的 readAsStringwriteAsString 方法来进行字符流的读写操作。

  /// 使用给定的 [Encoding] 读取整个文件内容作为字符串。////// 返回一个 `Future<String>`,当文件内容被读取后,该Future将完成并返回字符串。Future<String> readAsString({Encoding encoding = utf8});

例如:

import 'dart:io';void main() async {var file = File('test.txt');String contents = await file.readAsString();print(contents);
}

在这个示例中,我们使用 readAsString 方法读取了文件的内容,并将其打印出来。

1.2.2 以字节流写入文件

使用 writeAsString 方法可以向文件中写入字符串。如果文件不存在,writeAsString 方法会创建一个新的文件。如果文件已经存在,writeAsString 方法会覆盖文件的内容。

  /// 将字节列表写入文件。////// 打开文件,将字节列表写入文件,然后关闭文件。返回一个 `Future<File>`,当整个操作完成后,该Future将完成并返回此 [File] 对象。////// 默认情况下,[writeAsBytes] 会创建文件并进行写入,如果文件已存在,将会截断文件。如果要将字节追加到现有文件,可以将 [FileMode.append] 作为可选的mode参数传入。////// 如果参数 [flush] 设置为 `true`,在返回的Future完成之前,写入的数据将被刷新到文件系统。Future<File> writeAsBytes(List<int> bytes,{FileMode mode = FileMode.write, bool flush = false});

例如:

import 'dart:io';void main() async {var file = File('test.txt');await file.writeAsString('Hello, Dart!');
}

在这个示例中,我们使用 writeAsString 方法向文件中写入了一些文本。

1.3 使用流优化文件读写

在读取或写入大文件时,我们通常使用流来处理数据。流可以让我们以块的形式处理数据,而不是一次性加载整个文件到内存中。这样可以显著减少内存使用,并提高程序的响应性。

以下是一个使用流读取大文件的示例:

import 'dart:io';
import 'dart:convert';void main() {var file = File('large_file.txt');var inputStream = file.openRead();inputStream.transform(utf8.decoder)  // 将字节解码为UTF-8.transform(LineSplitter())  // 将流转换为单独的行.listen((String line) {  // 处理结果print('从流中获得 ${line.length} 个字符');}, onDone: () {print('文件现已关闭');}, onError: (e) {print(e.toString());});
}

在这个示例中,我们首先打开了一个文件的读取流,然后使用 transform 方法将字节流转换为字符串流,再将字符串流转换为行流。最后,我们使用 listen 方法处理每一行数据。

2. 文件权限

在进行文件操作时,我们需要考虑到平台权限问题。不同的操作系统和设备可能有不同的权限要求。以下是一些可能需要处理的权限问题:

2.1 不同移动平台上的权限

以往,在 Android 平台上,我们需要在 AndroidManifest.xml 文件中声明我们需要的权限。

  • READ_EXTERNAL_STORAGE:这个权限允许应用读取设备上的外部存储空间。
  • WRITE_EXTERNAL_STORAGE:这个权限允许应用写入设备上的外部存储空间。

但是从Android 6.0(API级别23)开始,用户可以在运行时授予或撤销某些权限。
即使你在 AndroidManifest.xml 文件中声明了这些权限,你仍然需要在运行时检查这些权限是否已经被授予,并在需要时请求用户授予这些权限。

而在iOS平台上,我们需要在Info.plist文件中声明我们需要的权限。以下是一些可能需要的权限:

  • NSFileProtectionCompleteUntilFirstUserAuthentication:这个权限允许应用在设备解锁后访问文件。

2.2 使用 permission_handler 请求权限

为了方便的获取相应的用户授权,在进行文件操作前,我们需要检查并请求必要的运行时权限,这可以使用 permission_handler 库来完成。我们可以使用来处理运行时权限。

2.2.1 安装和配置 permission_handler

首先,我们需要在项目中安装 permission_handler 库。在 pubspec.yaml 文件中添加以下依赖:

dependencies:flutter:sdk: flutterpermission_handler: ^11.0.1

然后,运行 flutter pub get 命令来获取库。

2.2.2 请求存储权限

以下是一个请求权限的示例:

import 'package:permission_handler/permission_handler.dart';void main() async {var status = await Permission.storage.status;if (!status.isGranted) {status = await Permission.storage.request();}if (status.isGranted) {// 你可以开始文件操作} else {// 不能启动文件操作}
}

在这个示例中,我们首先检查存储权限的状态。如果权限没有被授予,我们请求用户授予权限。如果权限被授予,我们可以开始文件操作。否则,我们不能开始文件操作。

2.3 处理权限拒绝

如果用户拒绝了我们的权限请求,我们需要处理这种情况。我们可以显示一个解释为什么我们需要这个权限的对话框,或者引导用户到系统设置中开启权限。例如:

import 'package:permission_handler/permission_handler.dart';void handler_storage_permission() async {var status = await Permission.storage.status;if (!status.isGranted) {status = await Permission.storage.request();}if (status.isGranted) {// 你可以开始文件操作// ...} else if (status.isPermanentlyDenied) {// 用户选择永久拒绝权限// 你可以在这里打开应用设置// ...openAppSettings();} else {// 用户选择拒绝权限// 你可以在这里显示一个对话框// ...}
}

在这个示例中,如果用户永久地拒绝了权限,我们可以打开应用设置。如果用户只是拒绝了权限,我们可以显示一个对话框。

3. Flutter 文件存储

本节讲解如何在Flutter中进行文件存储,包括如何使用path_provider库来获取应用的文件存储路径,如何使用File类的方法来进行文件的读写操作,以及如何读写特殊类型的文件。

3.1 path_provider 库及其用法

path_provider 是一个Flutter插件,用于查找iOS和Android上的常用位置的路径。这个库可以帮助我们找到存储应用数据的正确位置。

3.1.1 安装 path_provider

首先,我们需要在项目中安装path_provider库。在pubspec.yaml文件中添加以下依赖:

dependencies:flutter:sdk: flutterpath_provider: ^2.1.1

3.1.2 获取临时目录

我们可以使用getTemporaryDirectory方法来获取临时目录的路径。临时目录是一个可以用来存储临时数据的目录。系统可能会随时清理这个目录,因此不应将重要数据保存在这里。

import 'package:path_provider/path_provider.dart';Directory tempDir = await getTemporaryDirectory();
String tempPath = tempDir.path;print(tempPath);

3.1.3 取应用程序目录

我们可以使用getApplicationDocumentsDirectory方法来获取应用程序目录的路径。应用程序目录是一个可以用来存储应用需要持久化的数据的目录。系统不会清理这个目录,因此可以安全地将重要数据保存在这里。

import 'package:path_provider/path_provider.dart';Directory appDocDir = await getApplicationDocumentsDirectory();
String appDocPath = appDocDir.path;print(appDocPath);

3.1.4 获取外部存储中为应用程序创建的目录

我们可以使用 getExternalStorageDirectory 方法来获取外部存储中为应用程序创建的目录的路径。这个目录通常用来存储可以由用户在其他应用中访问的文件,如图片、音乐等。

import 'package:path_provider/path_provider.dart';Directory externalStorageDir = await getExternalStorageDirectory();
String externalStoragePath = externalStorageDir.path;print(externalStoragePath);

注意,由于Android 10的隐私更改,此方法不再可用。作为替代,你可以查看MediaStore。

3.1.5 获取应用程序缓存目录

我们可以使用getCacheDirectory方法来获取应用程序缓存目录的路径。这个目录用来存储临时缓存数据。

import 'package:path_provider/path_provider.dart';Directory cacheDir = await getCacheDirectory();
String cachePath = cacheDir.path;print(cachePath);

3.1.6 获取应用程序可以放置应用库文件的目录

我们可以使用getApplicationSupportDirectory方法来获取应用程序可以放置应用库文件的目录的路径。这个目录用来存储应用的支持文件,这些文件只有应用本身可以访问。

import 'package:path_provider/path_provider.dart';Directory supportDir = await getApplicationSupportDirectory();
String supportPath = supportDir.path;print(supportPath);

3.2 文件的读写操作

在Flutter中,我们可以使用File类的方法来进行文件的读写操作,与在Dart中的操作方式相同。因此你需要 导入 ‘dart:io’:

import 'dart:io';

具体操作这里不再赘述。

3.3 读写特殊类型的文件示例

在Flutter中,我们可以使用File类来读写各种类型的文件,包括图片、音频等特殊类型的文件。然而,由于这些特殊类型的文件通常是二进制格式的,因此我们需要使用readAsBytes和writeAsBytes方法来读写这些文件。

3.3.1 图片文件

  1. 读取图片文件

我们可以使用 readAsBytes 方法来读取图片文件,然后使用 Image.memory 构造函数来创建一个图片控件。

import 'dart:io';
import 'package:flutter/material.dart';void main() async {var file = File('path_to_your_image_file');var bytes = await file.readAsBytes();var image = Image.memory(bytes);runApp(MaterialApp(home: Scaffold(body: Center(child: image),),));
}
  1. 写入图片文件

我们可以使用writeAsBytes方法来写入图片文件。首先,我们需要获取图片的字节数据,然后将这些字节数据写入文件。

import 'dart:io';
import 'package:flutter/services.dart';void main() async {var bytes = await rootBundle.load('assets/image.png');var file = File('path_to_your_image_file');await file.writeAsBytes(bytes.buffer.asUint8List());
}

3.3.2 音频文件

  1. 读取音频文件

读取音频文件的方法与读取图片文件类似,我们可以使用 readAsBytes 方法来读取音频文件。然而,由于Flutter的核心库并不支持音频播放,因此我们需要使用一个第三方库,如audioplayers,来播放音频。

import 'dart:io';
import 'package:audioplayers/audioplayers.dart';void main() async {var file = File('path_to_your_audio_file');var bytes = await file.readAsBytes();var player = AudioPlayer();await player.playBytes(bytes);
}
  1. 写入音频文件

写入音频文件的方法与写入图片文件类似,我们可以使用writeAsBytes方法来写入音频文件。

import 'dart:io';
import 'package:flutter/services.dart';void main() async {var bytes = await rootBundle.load('assets/audio.mp3');var file = File('path_to_your_audio_file');await file.writeAsBytes(bytes.buffer.asUint8List());
}

相关文章:

Flutter笔记:目录与文件存储以及在Flutter中的使用(下)

Flutter笔记 目录与文件存储以及在Flutter中的使用&#xff08;下&#xff09; 文件读写与Flutter中文件管理 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;…...

机器学习笔记 - Ocr识别中的CTC算法原理概述

一、文字识别 在文本检测步骤中,分割出了文本区域。现在需要识别这些片段中存在哪些文本。 机器学习笔记 - Ocr识别中的文本检测EAST网络概述-CSDN博客文章浏览阅读300次。在 EAST 网络的这个分支中,它合并了 VGG16 网络不同层的特征输出。现在,该层之后的特征大小将等于 p…...

系列二、Lock接口

一、多线程编程模板 线程 操作 资源类 高内聚 低耦合 二、实现步骤 1、创建资源类 2、资源类里创建同步方法、同步代码块 三、12306卖票程序 3.1、synchronized实现 3.1.1、Ticket /*** Author : 一叶浮萍归大海* Date: 2023/11/20 8:54* …...

JVM虚拟机:通过日志学习PS+PO垃圾回收器

我们刚才设置参数的时候看到了-XXPrintGCDetails表示输出详细的GC处理日志&#xff0c;那么我们如何理解这个日志呢&#xff1f;日志是有规则的&#xff0c;我们需要按照这个规则来理解日志中的内容&#xff0c;它有两个格式&#xff0c;一个格式是GC的格式&#xff08;新生代&…...

从0开始学习JavaScript--JavaScript使用Promise

JavaScript中的异步编程一直是开发中的重要话题。传统的回调函数带来了回调地狱和代码可读性的问题。为了解决这些问题&#xff0c;ES6引入了Promise&#xff0c;一种更现代、更灵活的异步编程解决方案。本文将深入探讨JavaScript中如何使用Promise&#xff0c;通过丰富的示例代…...

使用契约的链上限价订单

我们开发了链上限价订单。 它基于一种称为契约的智能合约&#xff0c;只有在花费输出的交易满足特定条件时才可以花费输出。 为了演示其工作原理&#xff0c;我们实施了以比特币支付的 Ordinals 代币买卖限价订单&#xff0c;无需托管人。 它可以运行在任何比特币协议链上&…...

Iceberg学习笔记(1)—— 基础知识

Iceberg是一个面向海量数据分析场景的开放表格式&#xff08;Table Format&#xff09;&#xff0c;其设计的目的是解决数据存储和计算引擎之间的适配的问题 表格式&#xff08;Table Format&#xff09;可以理解为元数据以及数据文件的一种组织方式&#xff0c;处于计算框架&…...

springboot中动态api如何设置

1.不需要编写controller 等mvc层&#xff0c;通过接口动态生成api。 这个问题&#xff0c;其实很好解决&#xff0c;以前编写接口&#xff0c;是要写controller&#xff0c;需要有 RestController RequestMapping("/test1") public class xxxController{ ApiOperat…...

Java —— 抽象类和接口

目录 1. 抽象类 1.1 抽象类概念 1.2 抽象类语法与特性 1.3 抽象类的作用 2. 接口 2.1 接口的概念 2.2 接口的语法规则与特性 2.3 实现多个接口(解决多继承的问题) 2.4 接口间的继承 2.5 抽象类和接口的区别 2.6 接口的使用实例 2.7 Clonable 接口和深拷贝 2.7.1 Cloneable接口 …...

数字IC前端学习笔记:异步复位,同步释放

相关阅读 数字IC前端https://blog.csdn.net/weixin_45791458/category_12173698.html?spm1001.2014.3001.5482 异步复位 异步复位是一种常见的复位方式&#xff0c;可以使电路进入一个可知的状态。但是不正确地使用异步复位会导致出现意想不到的错误&#xff0c;复位释放便是…...

Linux内核移植之网络驱动更改说明一

一. 简介 本文学习 NXP官方Linux内核移植网络驱动的更改。 为了方便后面 Linux驱动的开发调试&#xff0c;所以&#xff0c;必须要把网络驱动调试好。 如果在做 Linux驱动开发时&#xff0c;写了一个 app或驱动&#xff0c;就需要将系统全部文件&#xff08;即 uboot&#…...

邮件|gitpushgithub报错|Lombok注解

基于 Spring Boot 搭建一个定时发送邮件的项目可以按照以下步骤进行&#xff1a; 创建一个新的 Spring Boot 项目&#xff0c;并添加所需的依赖。在 pom.xml 文件中添加以下依赖项&#xff08;根据你的需要进行调整&#xff09;&#xff1a; xml org.springframework.boot sp…...

【前端知识】Node——events模块的相关方法

一、events模块的常用方法 // 事件总线 const EventsEmitter require(events);const emitter new EventsEmitter();function HLog(msg){console.log(msg); }// 监听 emitter.on(hlog, HLog);setTimeout(() > {// 触发&#xff0c;打印emitter.emit(hlog, hello emitter!)…...

广州华锐互动VRAR | VR课件内容编辑器解决院校实践教学难题

VR课件内容编辑器由VR制作公司广州华锐互动开发&#xff0c;是一款专为虚拟现实教育领域设计的应用&#xff0c;它能够将传统的教学内容转化为沉浸式的三维体验。通过这款软件&#xff0c;教师可以轻松创建和编辑各种虚拟场景、模型和动画&#xff0c;以更生动、直观的方式展示…...

Wireshark抓包:理解TCP三次握手和四次挥手过程

TCP是一种面向连接、端到端可靠的协议&#xff0c;它被设计用于在互联网上传输数据和确保成功传递数据和消息。本节来介绍一下TCP中的三次握手和四次挥手。 文章目录 1 TCP头部格式2 wireshark抓包分析2.1 SEQ和ACK2.2 三次握手2.3 四次挥手 3 程序 1 TCP头部格式 TCP头部占据…...

网络工程师-HCIA网课视频学习

这里是速成的&#xff0c;只积累下&#xff0c;自己未曾学习到的东西。通过书本补充知识点。 视频&#xff1a;hcia17-链路聚合_哔哩哔哩_bilibili hcia16-路由高级特性&#xff1a; hcia17-链路聚合&#xff1a; 由于如果根据视频来学习的话&#xff0c;感觉视频的总结并不…...

【每日刷题——语音信号篇】

思考与练习 练习2.1 语音信号在产生的过程中&#xff0c;以及被感知的过程中&#xff0c;分别要经过人体的哪些器官&#xff1f; 1.产生过程&#xff1a; 肺部空气 → \rightarrow →冲击声带 → \rightarrow →通过声道&#xff08;可以调节&#xff09; → \rightarrow →…...

Linux进程通信——IPC、管道、FIFO的引入

进程间的通信——IPC 进程间通信 (IPC&#xff0c;InterProcess Communication) 是指在不同进程之间传播或交换信息。 IPC的方式通常有管道 (包括无名管道和命名管道) 、消息队列、信号量、共享存储、Socket、Streams等。其中 Socket和Streams支持不同主机上的两个进程IPC。 …...

数理统计的基本概念(一)

文章目录 总体、样本与统计量总体及其分布样本及其分布统计量统计量概念样本矩顺序统计量及其分布样本中位数与样本极差经验分布函数 参考文献 总体、样本与统计量 总体及其分布 在数理统计中&#xff0c;称所研究的对象的全体为总体&#xff0c;总体中的元素称为个体。若总体…...

clickhouse分布式之弹性扩缩容的故事

现状 社区不支持喔&#xff0c;以后也不会有了。曾经尝试过&#xff0c;难道是是太难了&#xff0c;无法实现吗&#xff1f;因为他们企业版支持了&#xff0c;可能是利益相关吧&#xff0c;谁知道呢&#xff0c;毕竟开源也要赚钱&#xff0c;谁乐意一直付出没有回报呢。 社区…...

数据结构--串的基本概念

目录 串的基本概念 串的定义 串与线性表对比 ​串的基本操作​ 串的比较 字符集编码 乱码问题​编辑 总结 ​串的存储结构 ​串的顺序存储​编辑 串的链式存储 串的基本操作 1、求字串 2、比较 3、定位操作 总结 串的基本概念 串的定义 串与线性表对比 串的…...

音视频流媒体之 IJKPlayer FFmpeg Android 编译

FIJK dockerfile 编译环境 FROM --platformlinux/amd64 ubuntu:18.04RUN apt-get update && apt-get install -y \wget \unzip \git \gcc \g \make \python \yasm \pkg-config \protobuf-compiler \sudoRUN apt-get install -y openjdk-8-jdkENV ANDROID_HOME…...

记录一次较为完整的Jenkins发布流程

文章目录 1. Jenkins安装1.1 Jenkins Docker安装1.2 Jenkins apt-get install安装 2. 关联github/gitee服务与webhook2.1 配置ssh2.2 Jenkins关联2.3 WebHook 3. 前后端关联发布 1. Jenkins安装 1.1 Jenkins Docker安装 Docker很好&#xff0c;但是我没有玩明白如何使用Docke…...

Virtual安装centos后,xshell连接centos 测试及遇到的坑

首先来一张官方的图--各种网络模式对应的连接状况&#xff1a; 1. 网络使用Host-Only模式动态分配IP&#xff0c;点确定后&#xff0c;centos 上运行 system restart network &#xff0c;使用ifconfig查看新的ip&#xff0c;XShell可以直接连上centos&#xff0c; 但是由于使用…...

【算法】最优乘车——bfs(stringsteam的实际应用,getline实际应用)

题目 H 城是一个旅游胜地&#xff0c;每年都有成千上万的人前来观光。 为方便游客&#xff0c;巴士公司在各个旅游景点及宾馆&#xff0c;饭店等地都设置了巴士站并开通了一些单程巴士线路。 每条单程巴士线路从某个巴士站出发&#xff0c;依次途经若干个巴士站&#xff0c;…...

『亚马逊云科技产品测评』活动征文|通过lightsail一键搭建Drupal VS 手动部署

『亚马逊云科技产品测评』活动征文&#xff5c;通过lightsail一键搭建Drupal 提示&#xff1a;授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 Developer Centre, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚…...

使用 VuePress 和 Vercel 打造个人技术博客:实现自动化部署

什么是VuePress? 以下是VuePress官方文档的介绍&#xff1a;VuePress 是一个以 Markdown 为中心的静态网站生成器。你可以使用 Markdown 来书写内容&#xff08;如文档、博客等&#xff09;&#xff0c;然后 VuePress 会帮助你生成一个静态网站来展示它们。VuePress 诞生的初…...

Re50:读论文 Large Language Models Struggle to Learn Long-Tail Knowledge

诸神缄默不语-个人CSDN博文目录 诸神缄默不语的论文阅读笔记和分类 论文名称&#xff1a;Large Language Models Struggle to Learn Long-Tail Knowledge ArXiv网址&#xff1a;https://arxiv.org/abs/2211.08411 官方GitHub项目&#xff08;代码和实体&#xff09;&#xf…...

Spring IOC - Bean的生命周期之依赖注入

在Spring启动流程中&#xff0c;创建的factoryBean是DefaultListableBeanFactory&#xff0c;其类图如下所示&#xff1a; 可以看到其直接父类是AbstractAutoireCapableBeanFactory&#xff0c;他主要负责完成Bean的自动装配和创建工作。 具体来说&#xff0c;AbstractAutowire…...

Android Termux安装MySQL,内网穿透实现公网远程访问

文章目录 前言1.安装MariaDB2.安装cpolar内网穿透工具3. 创建安全隧道映射mysql4. 公网远程连接5. 固定远程连接地址 前言 Android作为移动设备&#xff0c;尽管最初并非设计为服务器&#xff0c;但是随着技术的进步我们可以将Android配置为生产力工具&#xff0c;变成一个随身…...