如何存储只读数据以与应用程序一起部署?


17

我正在开发一个桌面应用程序,此应用程序需要运行一些信息,但不会更改任何这些信息(必须在应用程序的每次执行中加载数据,但永远不要更改数据)。数据必须与应用程序运行时存储在同一台计算机上(客户端存储吗?)。

如果用户不能轻易更改此信息(假设他们没有太多的IT知识),那也更好。

我应该如何存储这种信息?本地数据库?与应用程序一起发送的XML?

我正在使用WPF。


2
这不是一个meta。元是讨论有关提出问题的主要站点的问题或疑虑的站点。
jpmc26 2016年

1
您为什么不希望用户更改信息?那是安全问题还是什么?是否应该将此信息对用户保密?原因可能会大大改变合适的答案。
jpmc26 2016年

1
@ jpmc26嗯,这一个安全问题,但是没什么大不了的。该应用程序的主要目标是通过一个串行端口与温度控制器(如控制器 )进行通信,并且XML将存储有关该控制器的内存地址的一些信息。如果用户更改它,则在执行过程中可能会引起问题,因此我希望避免使用它。就像我说的,这只是一个问题,没什么大不了的。PS:编辑的问题,以取代SE。谢谢。
appa yip yip

2
如果需要本地数据库,请查看SQLite。(但是,如果数据足够小,可以在启动时加载到RAM中,则我更喜欢一个简单的结构化文件,如json或二进制文件)
CodesInChaos

1
“如果用户更改它,可能会在执行过程中引起问题,因此我希望避免使用它。” 听起来根本不像是安全问题。安全问题是指文件中包含密码短语或类似密码的地方。只需将设置放在可执行文件旁边的XML文件中,然后在顶部添加注释,即“请勿触摸此文件中的设置!”。如果用户在您的安装目录中编辑随机文件,那么他们应得到的任何损坏。
罗杰·利普斯科姆2016年

Answers:


14

二进制文件将是一个很明显的答案,但是它取决于您如何加载它-如果可能,还可以使自己的生活更轻松。

XML可能是一个不错的选择,因为C#中内置了读取方法。您可以将校验和添加到数据中,以便如果用户更改校验和,校验和将不再匹配(您需要添加校验以确保校验和有效)。

本地数据库可能会产生更多问题,因为您需要其他依赖项才能访问它


我还没有考虑过校验和,这是一个非常好的主意。因此,我生成了一个校验和并将其存储在我的应用程序中,因此,每次我对XML进行反序列化时,都会生成一个新的校验和并将其与第一个校验和进行比较?
appa yip yip

4
如果将校验和存储在应用程序中,则永远不会允许使用其他配置,因此您最好将配置数据作为应用程序常量存储在代码中。如果您希望将来能够更改配置,请添加校验和(更好的术语是“哈希”)作为XML的字段,并使用它来验证XML是否未被篡改。当然,坚定的攻击者可以研究您的代码,找到您的哈希逻辑并使用它生成有效的XML文件,但是无论如何,客户端应用程序始终容易受到坚定的攻击者的攻击。
SJuan76 '16

4
代替文件或本地数据库,嵌入程序集中的资源文件会更好。对最终用户隐藏,可由开发人员轻松管理,但仍然对用户友好。如果需要考虑性能,则二进制序列化会更好。
PTwr

@ SJuan76是的,XML哈希的问题是,如果有人反序列化它,则可以更改它。无论如何,如果 XML发生变化(我认为这不会发生,但谁知道),它将仅在新版本的应用程序上发生变化,所以我猜我会坚持使用代码上的哈希值。
appa yip yip

2
@schmaedeck:资源文件实际上是可执行二进制文件中的文件。图标和字符串以及程序需要的任何其他常量数据。
Mooing Duck

21

如果数据永不更改且为只读,则只需将其作为常量列表放入代码文件中即可。

public readonly string AppStartUpData = "MyAppNeedsThis";

如果每个部署的数据不同,则可以使用外部文件。

.Net带有内置的.config文件(App.Config)。人们应该使用这些方法,因为存在标准方法(内置于框架中)从它们中读取信息。

如果配置只是文本文件(Xml),请使用配置文件以防需要更改设置(不要说永不)。如果存在敏感信息,则可以根据需要加密设置。


我想到了常量/只读,问题是有很多数据,所以我想我将跟进外部文件。谢谢!
appa yip yip

5
@schmaedeck ...是吗?您可以将这些定义放在单独的文件中,然后导入该文件。实际上,我相信Qt在编译表单和内容时会执行此类操作,因此您最终会获得自动生成的文件,这些文件的某些常量具有兆字节的二进制数据(例如,图像),但是如果在单独的文件中,则没有任何问题。
巴库里

15

您始终可以将文件添加到项目中,并将其构建类型设置为,Embedded Resource以便将其直接嵌入到应用程序本身中。

或者,将文件加密并放置在可访问的位置。


1
这是最好的答案。我希望看到更多有关实现它的指导。您可以从可能会更改的配置文件中受益,但由于它嵌入在程序集中,因此可以保持静态。
Gusdor

5

如果您不希望用户查看数据,则应将其序列化为二进制数据文件。

只有应用程序会知道要从中读取的块的长度。

我不知道C#,但是在Java中,您将创建如下文件:

FileOutputStream fos = new FileOutputStream(file);      
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(var1);
oos.writeObject(var2);
oos.writeObject(var3);
oos.writeObject(var4);

...他们这样读:

FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);
Object o[] = new Object[4];
o[0] = ois.readObject();
o[1] = ois.readObject();
o[2] = ois.readObject();
o[3] = ois.readObject();

我一定会使用二进制序列化。非常感谢您的宝贵时间!
appa yip yip
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.