将文件类型图标保存在数据库或XML文件中

3
我正在使用c#,wpf和mvvm。
在我的数据表格中,每一行的最后一个单元格都有一个名为“期”的与该行相关的文档ListBox。
用户可以向每个期添加文档。
我想为每个文档显示文件类型图标(16x16)和文档名称。
文件类型图标让我有点头疼。
我不确定是否应该像.DOC这样将每个文档的文件类型图标保存在数据库中,因为一天可能有10个期,每个期都附有2个.DOC文件,因此我在数据库中保存了20个图标,这些图标是19次冗余的...
大多数用户附加的内容都是Office文件类型,如.xls、.doc、.pdf、图像、zip/rar等。
另一个但技术上更先进的方法是将唯一的文件类型图标作为编码的base-64字符串保存在XML文件中,文件类型扩展名作为键/值对。
XML在应用程序启动时加载一次到字典中。
<FileTypes>
<Extension ext="doc" base64string="ff5598sdfusd98fjs9df98sd9f" />
<Extension ext="docx" base64string="ff5498sdfusd98fjs9df98sd9f" />
<Extension ext="xls" base64string="ff9548sdfdsfdfusd98fjs9df98sd9f" />
<Extension ext="xlsx" base64string="ff98sfdfddfusd98fjs9df98sd9f" />
<Extension ext="pdf" base64string="ff98fdfdsdfusd98fjs9df98sd9f" />
<Extension ext="zip" base64string="ff98dfdfsdfusd98fjs9df98sd9f" />
<Extension ext="rar" base64string="fffdf98sdfusd98fjs9df98sd9f" />
</FileTypes>

每次数据库传输文件时,我会检查文件名中的文件扩展名并检索字典以获取文件的Base64字符串。我可以实现一种缓存机制来缓存文件类型的Base64字符串,这样我就不需要每次获取.doc文件时都解码它们... 也许你有一个非常不同/更好 的想法,请告诉我或提出有关数据库/XML保存的优缺点的建议 :)

为什么要在数据库中保存20个图标?你可以创建一个FileTypes表并保存20个引用。这比xml文件更好,因为应用程序加载速度更快。如果使用“一个用户-一个数据库”的方法,还可以将图标保存在应用程序的文件夹中。如果您添加有关上传图标的人员、图标来源以及应用程序的用户数量的信息,回答会更容易些。 - vortexwolf
3
@msfanboy 我的意思是你可以在应用程序文件夹中创建一个名为Images的新文件夹,并在其中存储图像。在数据库中仅存储图标文件的链接。采用这种方法,就不需要将所有图像加载到内存中,将图像存储为文件比将它们存储为字节更加灵活。 - vortexwolf
@所有人,如果我没有拥有这些图片,我该如何将它们存储在应用程序文件夹中?@vorrtex 嗯,我们讨论的是16x16像素的图像,在应用程序启动时将它们加载到内存中不会花费太多时间 :) - msfanboy
@msfanboy 我认为调用本地文件系统10次不会花费太多时间。但如果你不确定哪种方式更好,可以编写一个测试应用程序,并测量加载1000个带有4个不同图标的项目的速度。 - vortexwolf
@vorrtex,我拿了一个256x256像素分辨率的.png文件,将它们适配到32x32的XAML中,并在20个文档中加载它们。我没有看到任何延迟,在通过以下方式显示它们时:<Image Width="32" Height="32" Source="C:\images\Word.png" /> @Vorrtex,我现在决定按照你的方式使用自己的免费办公等图标,并将它们放在我的应用程序目录中的一个图像文件夹中。然后,我在数据库中有一个字段,包含文档的扩展名,如docx、doc、pdf等,根据这个字符串,我从硬盘/我的图像文件夹中加载图像。不需要缓存。 - msfanboy
显示剩余8条评论
2个回答

0
如果您有少量文件类型和大量文件,最好将文件类型存储为file_type_master数据库或XML文件,并在使用时加载一次。但是,这仅适用于在加载和使用方面存在良好的权衡的情况下。否则,您也可以进行缓存处理。

这真酷...正是你建议的,我在帖子中描述过...声誉不会得到积分。 - msfanboy

0

始终避免将二进制图像存储在数据库中。查询和转换是额外负担。对于这个特定选项,最好的方法是将所有图片保存为资源,并将资源名称保存在数据库中。你可以通过保留资源名称的枚举,并在onrowdatabound时解析(eNUM.PARSE)名称来实现。将其作为数据网格行的单元格模板源绑定到数据行。该单元格可以包含模板内容作为图像


2
始终避免在数据库中存储二进制图像。@niladridm:在数据库中存储BLOB数据本身并没有什么问题。如果操作者知道自己在做什么并正确设置了数据库,那么存储二进制数据时性能损失可以忽略不计。 - FreeAsInBeer
谢谢,先生。我总是讨厌别人只凭主观意见就说“不要做某某事……”而没有提供更多的支持理由。 - FreeAsInBeer
问题在于存储没有问题,但当您查询大量 Blob 记录并通过服务层将其传递给演示层时,转换会因数据增长而变得繁重。WPF 的数据网格需要更长的加载时间。这是我的意见,经过测试。如果您有更多要补充的,我很乐意学习。 - niladridm
@niladridm 当我加载文档时,我不会从数据库中加载任何byte[]数据,而且我也没有计划这样做。当用户单击打开文档按钮时,我会进行惰性加载;-) 所以我加载的只是文档的名称。 - msfanboy
@msfanboy 没关系,不加载文档是很自然的。在aspx页面中,对于同样的问题,我们通常会在单元格模板中保留两个隐藏的图像,并在行绑定时可以将其中任何一个设置为可见。我认为在WPF的datagrid视图上也可能是这样的。我们需要存储0/1/...来表示文档类型。这是你所说的吗? - niladridm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接