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

【Android】数据存储方案——文件存储、SharedPreferences、SQLite数据库用法总结

文章目录

  • 文件存储
    • 存储到文件
    • 读取文件
  • SharedPreferences存储
    • 存储
      • 获取SharedPreferences对象
      • Context 类的 getSharedPreferences() 方法
        • Activity 类的 getPreferences() 方法
        • PreferenceManager 类中的 getDefaultSharedPreferences() 方法
      • 示例
    • 读取
    • 记住密码的功能
  • SQLite数据库存储
    • 创建数据库
    • 升级数据库
    • 添加数据
    • 更新数据
    • 删除数据
    • 查询数据

今天来介绍一下Android的数据持久化技术,提供了三种存储方式,还可以存储到SD卡中。

主要介绍这三种:

文件存储

适用于存储较大或复杂的数据文件,比如图像、视频、文档等。

也适合存储简单的文本文件。

SharedPreferences存储

适用于存储简单的键值对数据,比如用户设置和应用配置。

数据量通常较小,数据结构简单。

数据库存储

适用于存储结构化数据,支持复杂的查询和数据管理。

文件存储

使用Context提供的openFileOutputopenFileInput方法,他们返回

存储到文件

openFileOutput()

public class MainActivity extends AppCompatActivity {private EditText edit; @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);edit = findViewById(R.id.editText); }@Overrideprotected void onDestroy() {super.onDestroy();String inputText = edit.getText().toString();  // 获取EditText中的文本save(inputText);  }// 将输入的文本保存到文件的方法private void save(String inputText) {FileOutputStream out = null;  // 声明FileOutputStream变量BufferedWriter writer = null;  // 声明BufferedWriter变量try {// 打开名为 "data" 的文件out = openFileOutput("data", Context.MODE_PRIVATE);writer = new BufferedWriter(new OutputStreamWriter(out));  // 创建BufferedWriter对象writer.write(inputText);  // 将输入的文本写入文件} catch (IOException e) {throw new RuntimeException(e); } finally {try {if (writer != null) {writer.close();}} catch (IOException e) {throw new RuntimeException(e); }}}
}

读取文件

openFileInput

public class MainActivity extends AppCompatActivity {private EditText edit; @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main); edit = findViewById(R.id.editText);String inputText = load(); // 如果加载到的文本内容不为空if (!TextUtils.isEmpty(inputText)) { // 如果加载到的文本内容不为空edit.setText(inputText); // 将光标移动到文本末尾edit.setSelection(inputText.length()); Toast.makeText(this, "加载成功", Toast.LENGTH_SHORT).show(); }}// 加载之前保存的文本内容private String load() {FileInputStream input = null; BufferedReader reader = null;// 创建 StringBuilder 对象,用于存储加载的文本内容StringBuilder content = new StringBuilder(); try {// 打开名为 "data" 的文件input = openFileInput("data"); // 创建 BufferedReader 对象reader = new BufferedReader(new InputStreamReader(input)); String line;while ((line = reader.readLine()) != null) { content.append(line);}} catch (IOException e) {throw new RuntimeException(e);} finally {try {if (reader != null) {reader.close(); }} catch (IOException e) {throw new RuntimeException(e); }}return content.toString(); }@Overrideprotected void onDestroy() {super.onDestroy();String inputText = edit.getText().toString();save(inputText); }private void save(String inputText) {//省略}
}

SharedPreferences存储

存储

获取SharedPreferences对象

利用SharedPreferences来存储数据,有三种获取SharedPreferences对象的方法

Context 类的 getSharedPreferences() 方法

  • 第一个参数指定SharedPreferences文件名
  • 第二个参数指定操作模式,MODE_PRIVATE:只有当前应用程序可以对SharedPreferences文件读写
SharedPreferences sharedPreferences = getSharedPreferences("data", MODE_PRIVATE);
Activity 类的 getPreferences() 方法
  • 只接受一个操作模式

  • 自动使用当前应用程序包名作为前缀命名SharedPreferences文件

SharedPreferences preferences = getPreferences(MODE_PRIVATE);
PreferenceManager 类中的 getDefaultSharedPreferences() 方法

步骤:

  1. 获取 SharedPreferences.Editor 编辑器对象

通过SharedPreferences对象的edit()方法

  1. SharedPreferences 中存储数据

  2. 提交数据

SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = sharedPreferences.edit();

或者

SharedPreferences.Editor editor = getSharedPreferences("data", MODE_PRIVATE).edit();

示例

public void StoringData(View view) {// 获取 SharedPreferences 编辑器对象SharedPreferences.Editor editor = getSharedPreferences("data", MODE_PRIVATE).edit();// 向 SharedPreferences 中存储数据editor.putString("name", "feng"); // 存储一个字符串值editor.putInt("age", 20); // 存储一个整数值editor.putBoolean("married", false); // 存储一个布尔值// 提交数据editor.apply();
}
  1. 获取 SharedPreferences 编辑器对象

    SharedPreferences.Editor editor = getSharedPreferences("data", MODE_PRIVATE).edit();
    
    • getSharedPreferences("data", MODE_PRIVATE):获取名为 dataSharedPreferences 文件。
    • MODE_PRIVATE:操作模式,表示只有本应用可以访问此文件。
    • edit():获取 SharedPreferences.Editor 对象,用于修改 SharedPreferences
  2. SharedPreferences 中存储数据

    editor.putString("name", "feng");
    editor.putInt("age", 20);
    editor.putBoolean("married", false);
    
    • putString("name", "feng"):存储一个字符串键值对。
    • putInt("age", 20):存储一个整数键值对。
    • putBoolean("married", false):存储一个布尔键值对。
  3. 提交数据

    editor.apply();
    
    • apply():异步提交数据,不会返回任何结果,更加高效。可以使用 commit() 同步提交数据,但会返回一个布尔值表示提交是否成功。

读取

get方法:允许你根据键(key)从 SharedPreferences 文件中获取相应的值

getStringgetIntgetBooleangetFloatgetLonggetStringSet

getStringSet(String key, Set<String> defValues)
  • 获取一个字符串集合
  • 第一个参数:键
  • 第二个参数:键不存在,返回的默认值
public void readData(View view) {// 获取 SharedPreferences 对象SharedPreferences sharedPreferences = getSharedPreferences("data", MODE_PRIVATE);// 读取数据String name = sharedPreferences.getString("name", ""); int age = sharedPreferences.getInt("age", 0); boolean married = sharedPreferences.getBoolean("married", false); // 打印读取到的数据Log.d("SecondActivity", "name: " + name + " age: " + age + " married: " + married);
}

记住密码的功能

展示登陆界面

image-20240725160811071

记住密码:

public class MainActivity extends BaseActivity {private EditText editText1;  // 用于输入账号的 EditTextprivate EditText editText2;  // 用于输入密码的 EditTextprivate Button btn;          // 用于触发登录的按钮private CheckBox rememberPass; // 用于是否记住密码的复选框private SharedPreferences sharedPreferences; // 用于存储和读取用户的登录信息private SharedPreferences.Editor editor; // 用于编辑 SharedPreferences 的数据@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main); editText1 = findViewById(R.id.editText1);editText2 = findViewById(R.id.editText2);btn = findViewById(R.id.button);rememberPass = findViewById(R.id.remeber_pass);// 获取 SharedPreferences 对象,用于存储和读取数据sharedPreferences = getSharedPreferences("data", MODE_PRIVATE);// 检查 SharedPreferences 中是否保存了记住密码的设置Boolean isRemember = sharedPreferences.getBoolean("remember_password", false);if (isRemember) {// 如果记住密码被勾选,填充账号和密码的 EditText,并且勾选复选框editText1.setText(sharedPreferences.getString("account", ""));editText2.setText(sharedPreferences.getString("password", ""));rememberPass.setChecked(true);}// 登陆按钮点击事件监听器btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// 获取用户输入的账号和密码String count = editText1.getText().toString();String password = editText2.getText().toString();// 验证账号和密码if (count.equals("feng") && password.equals("123")) {// 获取 SharedPreferences 的编辑器对象,注意是在判断语句的外面的大editor = sharedPreferences.edit();// 根据复选框的状态决定是否保存账号和密码if (rememberPass.isChecked()) {// 如果勾选了复选框,保存账号和密码editor.putBoolean("remember_password", true);editor.putString("account", editText1.getText().toString());editor.putString("password", editText2.getText().toString());} else {// 如果未勾选复选框,清除保存的账号和密码editor.clear();}// 应用编辑器的更改editor.apply();// 启动新的 Activity 并结束当前 ActivityIntent intent = new Intent(MainActivity.this, FirstActivity.class);startActivity(intent);finish();} else {// 如果账号或密码错误,显示错误提示Toast.makeText(MainActivity.this, "账号或密码错误", Toast.LENGTH_SHORT).show();}}});}
}

SQLite数据库存储

创建数据库

SQLiteOpenHelper抽象类,需要重写onCreate() onUpgrade()两个方法

自定义一个帮助类继承SQLiteOpenHelper

  • getReadableDatabase()getWritableDatabase()

    都可以创建或打开一个现有的数据库(没有就新创建一个)

    返回一个可以对新数据库进行读写操作的对象

  • SQLiteOpenHelper构造方法

     public MyDatabaseHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {super(context, name, factory, version);mContext = context;}
    
    1. Context:在构造函数中,这个参数用于初始化mContext,以便在数据库创建时(例如在onCreate方法中)显示Toast消息或访问其他资源

    2. String:指定你想要创建或打开的数据库文件的名称。数据库文件会保存在应用的默认数据库目录中(通常是/data/data/<package_name>/databases/

    3. SQLiteDatabase.CursorFactory

      作用: 这是一个SQLiteDatabase.CursorFactory对象,用于创建Cursor对象。这个工厂对象可以用于自定义Cursor的创建方式,但通常不需要使用它,默认值为null

      使用: 你可以传递一个自定义的CursorFactory对象,以便自定义Cursor的行为。如果不需要自定义,可以传递null,这时SQLite会使用默认的CursorFactory

    4. int version

      数据库的版本号。每次对数据库结构进行更改时,都需要增加这个版本号,以便触发onUpgrade方法。

    数据库创建代码示例:

public class MyDatabaseHelper extends SQLiteOpenHelper {// SQL语句用于创建Book表public static final String CREATE_BOOK = "create table Book("+ "id integer primary key autoincrement,"  // id字段,自增主键+ "author text,"  // author字段,作者名称+ "price real,"  // price字段,书的价格+ "pages integer,"  // pages字段,书的页数+ "name text)";  // name字段,书名private Context mContext;  // 用于显示Toast消息的Context对象// 构造函数,初始化数据库助手对象public MyDatabaseHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {super(context, name, factory, version);  // 调用父类构造函数mContext = context;  // 保存Context对象}// 创建数据库时调用,执行SQL语句创建表@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(CREATE_BOOK);  // 执行创建Book表的SQL语句db.execSQL(CREATE_CATEGORY);  // 执行创建Category表的SQL语句(注意CREATE_CATEGORY未定义)Toast.makeText(mContext, "创建成功", Toast.LENGTH_SHORT).show();  // 显示表创建成功的消息}// 升级数据库时调用,处理数据库版本升级@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
}
public class MainActivity extends AppCompatActivity {private MyDatabaseHelper databaseHelper;  // 数据库帮助类的实例private Button btn;  // 按钮控件的实例@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);btn = findViewById(R.id.btn1);  // 初始化数据库帮助类databaseHelper = new MyDatabaseHelper(this, "BookStore", null, 1);btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// 获取可写的数据库实例databaseHelper.getWritableDatabase();}});}
}

升级数据库

因为oncreate方法只执行一次,当我们要更新数据库是无法成功

public class MyDatabaseHelper extends SQLiteOpenHelper {// 定义创建 Book 表的 SQL 语句public static final String CREATE_BOOK = "create table Book("+ "id integer primary key autoincrement,"  // 自增主键 id+ "author text,"  // 作者+ "price real,"  // 价格+ "pages integer,"  // 页数+ "name text)";  // 书名// 定义创建 Category 表的 SQL 语句public static final String CREATE_CATEGORY = "create table Category("+ "id integer primary key autoincrement,"  // 自增主键 id+ "category_name text,"  // 类别名称+ "category_code integer)";  // 类别代码private Context mContext;  // 上下文对象// 构造函数,初始化数据库帮助类public MyDatabaseHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {super(context, name, factory, version);mContext = context;  // 初始化上下文}@Overridepublic void onCreate(SQLiteDatabase db) {// 创建 Book 表db.execSQL(CREATE_BOOK);// 创建 Category 表db.execSQL(CREATE_CATEGORY);// 显示提示信息Toast.makeText(mContext, "创建成功", Toast.LENGTH_SHORT).show();}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// 如果表存在,删除 Book 表db.execSQL("drop table if exists Book");// 如果表存在,删除 Category 表db.execSQL("drop table if exists Category");// 重新创建数据库onCreate(db);}
}

更新版本号,比刚才大,onUpgrade()就可以执行了

        databaseHelper = new MyDatabaseHelper(this, "BookStore", null, 2);

添加数据

CRUD:创建(Create)、读取(Read)、更新(Update)和删除(Delete)

getReadableDatabase()getWritableDatabase()返回一个可以对新数据库进行读写操作的对象

调用该对象insert方法

insert

long insert (String table, String nullColumnHack, ContentValues values)
  • table:要插入数据的表名,例如 "Book"

  • nullColumnHack

    未指定添加数据情况下给某些可为空的列自动赋值NULL,一般不使用该功能,直接传入null

  • values: 一个 ContentValues 对象,包含列名和相应的值。

    使用它的put方法添加数据

    ContentValues values = new ContentValues();
    values.put("name", "The Da Vinci Code");
    values.put("author", "Dan Brown");
    values.put("pages", 454);
    values.put("price", 16.96);
    

    添加数据示例:

btn2.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// 获取可写的数据库实例SQLiteDatabase db = databaseHelper.getWritableDatabase();// 创建 ContentValues 实例并存储第一条记录的数据ContentValues values = new ContentValues();values.put("name", "The Da Vinci Code"); // 书名values.put("author", "Dan Brown"); // 作者values.put("pages", 454); // 页数values.put("price", 16.96); // 价格// 插入第一条记录到数据库的 "data" 表db.insert("Book", null, values);// 清空 ContentValues 实例并存储第二条记录的数据values.clear();values.put("name", "The Lost Symbol"); // 书名values.put("author", "Dan Brown"); // 作者values.put("pages", 510); // 页数values.put("price", 19.95); // 价格// 插入第二条记录到数据库的 "data" 表db.insert("Book", null, values);// 清空 ContentValues 实例以备将来使用values.clear();}
});

更新数据

与插入数据类似,最后使用update方法更新

  • 第一个参数:表名 “Book”
  • 第二个参数:ContentValues 对象,包含要更新的列及其新值
  • 第三个参数:WHERE 子句,指定哪些行需要更新,这里使用占位符 ‘?’
  • 第四个参数:占位符的实际值,这里是 “The Da Vinci Code”
btn3.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// 获取可写的数据库实例SQLiteDatabase db = databaseHelper.getWritableDatabase();// 创建 ContentValues 实例并存储要更新的列及其新值ContentValues values = new ContentValues();values.put("price", 150); // 更新书籍的价格为 150// 执行更新操作db.update("Book", values, "name = ?", new String[]{"The Da Vinci Code"});}
});

删除数据

delete方法

  • 第一个参数:表名 “Book”
  • 第二个参数:WHERE 子句,指定哪些行需要删除,这里使用占位符 ‘?’
  • 第三个参数:占位符的实际值,这里是 “500”
btn4.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// 获取可写的数据库实例SQLiteDatabase db = databaseHelper.getWritableDatabase();// 执行删除操作// 删除五百页以上的书db.delete("Book", "pages > ?", new String[]{"500"});}
});

查询数据

  • Cursor cursor = db.query("Book", null, null, null, null, null, null);
    
    • 第一个参数 "Book" 是要查询的表名。
    • 第二个参数 null 表示查询所有列。
    • 第三个到第六个参数 null 分别表示 WHERE 子句、WHERE 子句参数、GROUP BY 子句和 HAVING 子句,这里都没有使用。
    • 第七个参数 null 表示排序顺序,这里没有指定。

1721912823839

  • 处理查询结果:

    if (cursor.moveToFirst()) 检查游标是否包含数据,如果包含数据,则移动到第一行。

    • do {...} while (cursor.moveToNext());
      

      循环遍历游标中的所有行,读取每一行的数据,在这里使用 Log.d 方法将读取到的数据输出到日志中,方便调试和查看。

btn5.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// 获取可写的数据库实例SQLiteDatabase db = databaseHelper.getWritableDatabase();// 查询 "Book" 表中的所有数据Cursor cursor = db.query("Book", null, null, null, null, null, null);// 检查游标是否至少包含一行数据if (cursor.moveToFirst()) {do {// 读取当前行的数据String name = cursor.getString(cursor.getColumnIndex("name")); // 读取 "name" 列的数据String author = cursor.getString(cursor.getColumnIndex("author")); // 读取 "author" 列的数据int pages = cursor.getInt(cursor.getColumnIndex("pages")); // 读取 "pages" 列的数据double price = cursor.getDouble(cursor.getColumnIndex("price")); // 读取 "price" 列的数据// 打印读取的数据到日志Log.d("MainActivity", "book name is " + name);Log.d("MainActivity", "book author is " + author);Log.d("MainActivity", "book pages is " + pages);Log.d("MainActivity", "book price is " + price);} while (cursor.moveToNext()); // 移动到下一行数据}// 关闭游标cursor.close();}
});


感谢您的阅读
如有错误烦请指正


参考:

  1. 《第一行代码》

相关文章:

【Android】数据存储方案——文件存储、SharedPreferences、SQLite数据库用法总结

文章目录 文件存储存储到文件读取文件 SharedPreferences存储存储获取SharedPreferences对象Context 类的 getSharedPreferences() 方法Activity 类的 getPreferences() 方法PreferenceManager 类中的 getDefaultSharedPreferences() 方法 示例 读取记住密码的功能 SQLite数据库…...

抖音矩阵管理系统功能说明:一站式掌握

在当下这个信息爆炸的时代&#xff0c;抖音作为短视频领域的佼佼者&#xff0c;其用户规模持续扩大&#xff0c;影响力日益增强。对于内容创作者和营销人员来说&#xff0c;如何高效管理抖音账号&#xff0c;实现内容的多平台分发和精准触达&#xff0c;成为了亟待解决的问题。…...

旅游卡使用指南及常见疑问解答

近期&#xff0c;许多朋友对旅游卡的免费旅游政策表示浓厚兴趣&#xff0c;但心中不免存疑&#xff1a;这真的是全程免费&#xff0c;无需自费一分吗&#xff1f; 在此&#xff0c;我们明确告知&#xff1a;免费旅游确实存在&#xff0c;但享受范围与条件需清晰界定。 本文将…...

【MySQL篇】Percona XtraBackup标准化全库完整备份策略(第三篇,总共五篇)

&#x1f4ab;《博主介绍》&#xff1a;✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ &#x1f4ab;《擅长领域》&#xff1a;✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux&#xff0c;也在扩展大数据方向的知识面✌️…...

背单词工具(C++)

功能分析 生词本管理&#xff1a; 创建生词本文件&#xff1a;在构造函数中创建了“生词本.txt”“背词历史.log”“历史记录.txt”三个文件。添加单词&#xff1a;用户可以输入单词、词性和解释&#xff0c;将其添加到生词本中。查询所有单词&#xff1a;展示生词本中所有的单…...

面试八股 | 数据库引擎 | InnoDB和myISAM的区别?

⭐️⭐️⭐️InnoDB和MyISAM的区别? InnoDB &#xff1a; 1、使用的是行锁&#xff0c;操作时候只锁一行数据&#xff0c;不会对其他有影响&#xff0c;适合高并发工作 2、支持事务 3、不仅缓存索引还要缓存真实数据&#xff0c;适合高并发 4、默认安装 5、支持外键 6、…...

GEE计算五种植被指数(NDVI、EVI2、RVI、MTVI2、OSAVI)

目录 计算公式源代码计算公式 源代码 // 定义感兴趣区域(这里以一个简单的矩形区域为例) var region = ee.FeatureCollection("projects/a-flyllf0313/assets/dachang"); // 定义时间范围 var startDate = 2023-04-18; var endDate &...

C/S架构和B/C架构

C/S架构&#xff08;Client/Server Architecture&#xff09;和B/C架构&#xff08;Browser/Client Architecture&#xff09;是两种不同 的软件架构模型&#xff0c;它们各自有不同的特点和应用场景。 一、C/S架构&#xff08;Client/Server Architecture&#xff09; 1. 定…...

音乐曲谱软件Guitar Pro 8.2 for Mac 中文破解版

Guitar Pro 8.2 for Mac 中文破解版是一款功能强大的音乐曲谱软件&#xff0c;非常适合学习如何玩&#xff0c;改进技巧&#xff0c;重现喜爱的歌曲或陪伴自己。 Guitar Pro for Mac 是一款功能强大的音乐曲谱软件&#xff0c;非常适合学习如何玩&#xff0c;改进技巧&#xf…...

浅聊Web Storage(localStorage 和 sessionStorage)、cookie的使用场合

Web Storage&#xff08;localStorage 和 sessionStorage&#xff09;、cookie 一、Cookie二、Web StoragelocalStoragesessionStorage与 Cookies 的比较 一、Cookie Cookies 主要用于以下几种情况&#xff1a; 会话管理&#xff08;Session Management&#xff09;: 登录、购…...

C语言输入输出缓冲机制

文章目录 输入输出缓冲机制概述为什么要有缓冲区缓冲区的类型引发缓冲区的刷新 原理实现 输入输出缓冲机制 概述 缓冲区又称为缓存&#xff0c;它是内存空间的一部分。也就是说&#xff0c;在内存空间中预留了一定的存储空间&#xff0c;这些存储空间用来缓冲输入 或者输出的数…...

javaEE-03-cookie与session

文章目录 Cookie创建Cookie获取Cookie更新CookieCookie 生命控制Cookie 有效路径 Session 会话创建和获取sessionSession 域数据的存取Session 生命周期控制浏览器和 Session 之间关联 Cookie Cookie 是服务器通知客户端保存键值对的一种技术,客户端有了 Cookie 后&#xff0c…...

EtherNet/IP转Profinet协议网关(经典配置案例)

怎么样才能把EtherNet/IP和Profinet网络连接起来呢?这几天有几个朋友问到了这个问题&#xff0c;作者在这里统一为大家详细说明一下。其实有一个设备可以很轻松地解决这个问题&#xff0c;名为JM-PN-EIP&#xff0c;下面是详细介绍。 一&#xff0c;设备主要功能 1、捷米特J…...

华为云依赖引入错误

问题&#xff1a;记录一次项目加在华为云依赖错误&#xff0c;如下&#xff1a; 错误信息&#xff1a;Could not find artifact com.huawei.storage:esdk-obs-java:pom:3.1.2.1 in bintray-qcloud-maven-repo (https://dl.bintray.com/qcloud/maven-repo/) 找到本地仓库&#…...

【Ubuntu】Ubuntu 配置镜像源(ARM)

【Ubuntu】Ubuntu 配置镜像源&#xff08;ARM&#xff09; 零、起因 最近在QEMU中安装了个ubuntu-24.04-live-server-arm64&#xff0c;默认是国外的软件源&#xff0c;很慢&#xff0c;故替换到国内。 壹、替换 源地址&#xff08;清华源&#xff09; https://mirror.tun…...

速腾聚创激光雷达复现FAST-LIO

目录 1.软件环境 2.测试执行 3.代码学习 3.1.找主节点代码文件 3.2.整体流程结构 3.3.具体函数理解 记录复现FAST-LIO算法的过程和&#xff0c;代码梳理和理解 1.软件环境 Windows 10(64bits) VMware 16 Pro Ubuntu 20.04 ROS Noetic FAST-LIO的简化版、注释版。感谢…...

k8s核心知识总结

写在前面 时间一下子到了7月份尾&#xff1b;整个7月份都乱糟糟的&#xff0c;不管怎么样&#xff0c;日子还是得过啊&#xff0c; 1、7月份核心了解个关于k8s&#xff0c;iceberg等相关技术&#xff0c;了解了相关的基础逻辑&#xff0c;虽然和数开主线有点偏&#xff0c;但是…...

语言模型及数据集

一、定义 1、语言模型的目标是估计序列的联合概率&#xff0c;一个理想的语言模型就能够基于模型本身生成自然文本。 2、对一个文档&#xff08;词元&#xff09;序列进行建模&#xff0c; 假设在单词级别对文本数据进行词元化。 3、计数建模 &#xff08;1&#xff09;其中…...

linux如何卸载python3.5

卸载&#xff1a; 1、卸载python3.5 sudo apt-get remove python3.5 2、卸载python3.5及其依赖 sudo apt-get remove --auto-remove python3.5 3、清除python3.5 sudo apt-get purge python3.5 或者 sudo apt-get purge --auto-remove python3.5...

【BUG】已解决:TypeError: expected string or bytes-like object

TypeError: expected string or bytes-like object 目录 TypeError: expected string or bytes-like object 【常见模块错误】 【解决方案】 常见原因及解决方法 示例代码 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展&#xff0c;光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域&#xff0c;IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选&#xff0c;但在长期运行中&#xff0c;例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...