Electron 如何在电子应用程序中保存数据?

Electron 如何在电子应用程序中保存数据?,electron,Electron,我一直在浏览文档,试图找出如何在电子应用程序中保存数据。例如,在iOS或OS X中,可以使用NSUserDefaults存储用户设置和首选项。我想做类似的事情。如何在Electron应用程序中保存数据?Electron视图是使用Webkit构建的,您可以使用Webkit访问基于web的localstorage api。适用于简单易用的存储设置 如果需要更强大的功能或需要从主脚本访问存储,可以使用众多基于节点的存储模块之一。我个人喜欢 对于大多数节点存储模块,您需要提供文件位置。尝试: var a

我一直在浏览文档,试图找出如何在电子应用程序中保存数据。例如,在iOS或OS X中,可以使用NSUserDefaults存储用户设置和首选项。我想做类似的事情。如何在Electron应用程序中保存数据?

Electron视图是使用Webkit构建的,您可以使用Webkit访问基于web的localstorage api。适用于简单易用的存储设置

如果需要更强大的功能或需要从主脚本访问存储,可以使用众多基于节点的存储模块之一。我个人喜欢

对于大多数节点存储模块,您需要提供文件位置。尝试:

var app = require('app');
app.getPath('userData');

我编写了一个名为NPM的模块,旨在将其抽象出来,并为开发人员提供一个友好、简单的界面

模块在内部从
app.getPath('userData')
读取/写入JSON:


有一个模块提供了获取json文件并将其设置到此目录的简单方法,如果需要,可以创建子目录,并支持回调和承诺:

自述:

装置

$ npm install --save electron-storage
$ npm install electron-store
用法

原料药

storage.get(文件路径,cb)

storage.get(文件路径)

storage.set(文件路径、数据、cb)

storage.set(文件路径、数据)

storage.isPathExists(路径,cb)

storage.isPathExists(路径)

是目前唯一推荐或推荐的用于Electron by Electron的嵌入式持久化数据库的工具。-

如果设置很复杂,存储用户设置也很有用

为什么NeDB是这个案件的更好的解决方案? Node.js、nw.js、Electron的嵌入式持久或内存数据库 浏览器,100%JavaScript,无二进制依赖。API是一个子集 MongoDB的而且速度很快

创建或加载数据库:

var Datastore = require('nedb')
  , db = new Datastore({ filename: 'path/to/datafile', autoload: true });
// You can issue commands right away
var doc = { hello: 'world'
               , n: 5
               , today: new Date()
               , nedbIsAwesome: true
               , notthere: null
               , notToBeSaved: undefined  // Will not be saved
               , fruits: [ 'apple', 'orange', 'pear' ]
               , infos: { name: 'nedb' }
               };

db.insert(doc, function (err, newDoc) {   // Callback is optional
  // newDoc is the newly inserted document, including its _id
  // newDoc has no key called notToBeSaved since its value was undefined
});
// Finding all inhabited planets in the solar system
db.find({ system: 'solar', inhabited: true }, function (err, docs) {
  // docs is an array containing document Earth only
});
插入文档:

var Datastore = require('nedb')
  , db = new Datastore({ filename: 'path/to/datafile', autoload: true });
// You can issue commands right away
var doc = { hello: 'world'
               , n: 5
               , today: new Date()
               , nedbIsAwesome: true
               , notthere: null
               , notToBeSaved: undefined  // Will not be saved
               , fruits: [ 'apple', 'orange', 'pear' ]
               , infos: { name: 'nedb' }
               };

db.insert(doc, function (err, newDoc) {   // Callback is optional
  // newDoc is the newly inserted document, including its _id
  // newDoc has no key called notToBeSaved since its value was undefined
});
// Finding all inhabited planets in the solar system
db.find({ system: 'solar', inhabited: true }, function (err, docs) {
  // docs is an array containing document Earth only
});
查找文档:

var Datastore = require('nedb')
  , db = new Datastore({ filename: 'path/to/datafile', autoload: true });
// You can issue commands right away
var doc = { hello: 'world'
               , n: 5
               , today: new Date()
               , nedbIsAwesome: true
               , notthere: null
               , notToBeSaved: undefined  // Will not be saved
               , fruits: [ 'apple', 'orange', 'pear' ]
               , infos: { name: 'nedb' }
               };

db.insert(doc, function (err, newDoc) {   // Callback is optional
  // newDoc is the newly inserted document, including its _id
  // newDoc has no key called notToBeSaved since its value was undefined
});
// Finding all inhabited planets in the solar system
db.find({ system: 'solar', inhabited: true }, function (err, docs) {
  // docs is an array containing document Earth only
});
名单还在继续

更新日期:2019年9月
截至2019年,这不再是有效答案。请参见下面@jviotti@Tharanga的答案

有一个很好的模块用于在elecron中存储用户数据。它叫

装置

$ npm install --save electron-storage
$ npm install electron-store
示例用法(从第页复制)

const-Store=require('electron-Store');
常量存储=新存储();

store.set('unicorn','在Electron中可以使用大量的数据持久化方法,选择正确的方法主要取决于您的用例。如果只是关于保存应用程序设置,那么您可以使用简单的机制,如平面文件或HTML5存储API,对于高级数据需求,您应该选择大型数据库解决方案,如MySQL或MongoDB(带或不带ORM)


您可以查看此方法/工具列表以查看

您可以选择Indexeddb,它很可能适合客户端应用程序需求,因为:

  • 其内置的版本控制机制。客户端应用程序经常面临版本碎片,因为用户通常不会同时更新到新版本。因此,检查现有数据库的版本并进行相应更新是一个好主意
  • 它是无模式的,允许灵活地将更多数据添加到客户机的存储中(这在我的经验中经常发生),而无需将数据库更新到新版本,除非创建新索引
  • 它支持多种数据:基本类型以及blob数据(文件、图像)

总而言之,这是一个不错的选择。唯一需要注意的是,如果未设置navigator.storage.persist
,或者主机崩溃,导致indexeddb处于损坏状态,铬内核可能会在存储紧张时自动清除indexeddb以回收磁盘空间。

自NeDB的最新版本于4年前发布以来我不推荐有很多悬而未决的问题。但是现在有很多其他的选择你可以使用

(许多功能、可观察的查询)

(简单但有许多悬而未决的问题)

(仅在内存中存储)


(适用于简单的小数据集)

除了其他答案中提到的内容之外,您还有多种观点

如果要将数据存储在SQL数据库中,则可以

或者,如果您正在存储配置,则可以直接存储在操作系统的
userData
存储中

const electron=require('electron');
常数fs=要求('fs');
const path=require('path');
const dataPath=electron.app.getPath('userData');
const filePath=path.join(dataPath'config.json');
函数writeData(键、值){
let contents=parseData()
内容[键]=值;
writeFileSync(filePath,JSON.stringify(contents));
}
函数readData(键、值){
let contents=parseData()
返回内容[键]
}
函数parseData(){
const defaultData={}
试一试{
返回JSON.parse(fs.readFileSync(filePath));
}捕获(错误){
返回默认数据;
}
}

谢谢,这很有帮助。我还想弄清楚我的模型/控制器逻辑应该放在哪里。我写的内容是否与浏览器窗口相同?否则,我如何将数据从electron js传递到窗口js?是的,浏览器窗口可以完全访问electron提供的所有内容。主脚本只对star真正有用升级Electron,或者如果您正在编写一个主要生活在后台的应用程序。Electron一开始感觉有点奇怪,因为它合并节点和DOM的方式。从浏览器窗口中完全访问所有节点感觉很奇怪。jviotti,您的示例显示了承诺,并使用了库回调。感谢sharing.Hi@Vjeko,该库最初使用Promise,但由于一些技术问题,我们放弃了对它们的支持(请参阅)。您可以使用Bluebird的promisifyAll()之类的东西来promisify该模块,以获得相同的效果。这将是一个满足您需求的好模块。在构建自定义
const Store = require('electron-store');
const store = new Store();

store.set('unicorn', 'There are a plethora of ways for data persistence that can be used in Electron and choosing the right approach depends essentially on your use case(s). If it's only about saving application settings then you can use simple mechanisms such as flat files or HTML5 Storage APIs, for advanced data requirements you should opt for large scale database solutions such as MySQL or MongoDB (with or without ORMs).

You can check this list of methods/tools to persist data in Electron apps

You can go for Indexeddb, which is most likely suitable for client-side app needs due to:

  • Its built-in versioning mechanism. Client-side applications often face version fragmentation as users don't usually update to new version at the same time. So checking version of existing database and update accordingly is a good idea.
  • It's schemaless, which allows flexibility of adding more data to client's storage (which happen pretty often in my experience) without having to update database to a new version, unless you create new indices.
  • It support wide ranges of data: basic types as well as blob data (file, images)
All in all it's a good choice. The only caveat is that chromium cores may automatically wipe out indexeddb to reclaim disk space when storage is under strain if
navigator.storage.persist
is not set, or when the host machine is crashed leaving indexeddb in corrupted state.

Since NeDB's latest release was 4 years ago and there are many open issues, I would not recommend it. But there are many other alternatives you can use now.

https://github.com/pubkey/rxdb (many features, observable queries)

https://github.com/pouchdb/pouchdb (simple but many open issues)

https://github.com/techfort/LokiJS (only in-memory storage)

https://github.com/typicode/lowdb (good for simple, small datasets)

You have multiple opions other than what mentioned in other answers.

If you want to store data in an SQL databse then you can https://github.com/mapbox/node-sqlite3

Or if you are storing configurations, You can store directly in OS's
userData
storage.

 const electron = require('electron');
 const fs = require('fs');
 const path = require('path');

 const dataPath = electron.app.getPath('userData');
 const filePath = path.join(dataPath, 'config.json');

 function writeData(key, value){
   let contents = parseData()
   contents[key] = value;
   fs.writeFileSync(filePath, JSON.stringify(contents));
 }

 function readData(key, value) {
  let contents = parseData()
  return contents[key]
 }

 function parseData(){
   const defaultData = {}
   try {
    return JSON.parse(fs.readFileSync(filePath));
  } catch(error) {
    return defaultData;
  }
 }