1
feirisu 252 天前
没看懂
|
2
wangtian2020 252 天前
不就是跟个系统自带的相册、或者说是图片查看器差不多吗。搞个缩略图差不多得了
|
3
xtreme1 252 天前
意思是图片在内存里什么样就在文件里什么样?
存 PPM 呗 |
4
testonly 252 天前 1
9k 张图片也不多,我近千万张图片在电脑。
将所有文件的名字存在一个文本文件里就行了,随机到那个图片的名字再读哪个图片出来,我还是用弱鸡 C#弄的。 |
5
h3xz OP 感谢大家的回复。我没有表达清楚问题的意思,我是希望将所有的图片能够序列化到一个文件中(不是文件夹),我保存的不单单只有图片,还有与图片相关的一系列的数据,编号等,因此我想请教有没有这样一种第三方库:能够以将图片,数据,编号,日期作为一个对象进行序列化,我起初使用的是 protobuf ,但是该库不能序列化太大的文件 。如果采用的是读取图片的名称,用户一旦修改了图片名,那么读取图片就会出错了。非常感谢大家的建议。
|
6
xieym 252 天前
sqlite?
|
8
hitmanx 252 天前 1
看不出来这个用例里面,图片和普通的二进制文件对于序列化有什么区别?你把图片想象成一个普通的二进制文件不就行了。
那么现在就是序列化一个 array 或者 map ,里面每个元素包含一些 metadata(number, string etc)和一个不定长的二进制文件。 |
9
F7TsdQL45E0jmoiG 252 天前
这不就是对象存储干的事儿嘛
|
10
StrangerA 252 天前
9k * 4M ,36 个 G 存入一个文件,还想瞬间读写?
建议存缩略图进 sqlite |
11
jones2000 252 天前
内存数据库
|
12
mxalbert1996 252 天前 via Android 1
换个思路,直接把文件打包成一个不带压缩的 zip 文件。zip 文件是支持随机读取的。
|
13
3dwelcome 252 天前
zip 文件可以,但是大小有一定限制,有 zip64 的变种,可以支持 4G 以上的大文件。
|
14
picone 252 天前
记录 offset ,fseek 即可
|
15
leonshaw 252 天前
在文件上建文件系统,mount
|
16
taygetus 252 天前
#include <boost/serialization/map.hpp>
#include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> |
17
linauror 252 天前
如果要存的数据不多,直接把这些数据给图片命名呢,比如 xxxx_yyyy_20240101235959.jpg
|
18
shyrock 252 天前 3
建议直接说原始需求,而不是你分析之后想要的算法。。。
|
19
shakeyo 252 天前
简单点就 zip
麻烦点就自己设计一个文件格式,类似|magicNumber|version|indexOffset|fileOffset| 生成过程就是计算头,填充并依次将头、文件索引表、文件数据 1 ,文件数据 2 。。。。。写入到文件中 |
20
edward1987 252 天前
确定需求是 [随机访问图片] 而不是 [随时访问图片] ? 怎么看着像是在做一个图文游戏,然后想用序列化的方式加密啊
|
21
xytysingle 252 天前
用 base64 编码图片为字符串,比如一行一个编号,日期,图片的 base64 字符串
|
22
bertonzh 252 天前
.img 文件
|
23
knva 252 天前
还是实现个文件系统简单。
|
24
kokutou 252 天前 via Android
啥都无所谓的话。。。直接丢数据库?
|
25
feirisu 252 天前 1
大概懂了,就是游戏资源的打包方式呗,其设计目的就是不让用户修改,又能快速定位资源,格式也简单。
但是单文件过大建议考虑分包。 通常格式是: 固定自定义格式头,包含多少个文件[int]等 资源名长度[int]、资源名[char*]、资源尺寸[int]、资源内容[byte*] 读取时可以直接打开文件,用文件句柄偏移的方式可以快速构建索引以及针对对应的偏移取出数据。 |
26
GeruzoniAnsasu 252 天前
数据库中存索引和 meta info ,图片文件一律改名成 ID ,完毕。
IO 不够就把文件丢进分布式文件系统里从网络读 |
27
mioktiar56 252 天前
我怀疑你是微信上找我的那个人
内存映射即可解决 |
28
feirisu 252 天前
就依照我#25 写的,可以直接让 chatgpt 给你封装一套打包加拆包的类。
|
29
wxf666 252 天前 1
@h3xz 那就存 SQLite 数据库呗。。
优点: - 单文件 - 可随机读写 - 依赖库只有几百 KB - 有原生 C/C++ 接口 - 可存一系列数据(编号、日期、数据、图片文件本身、……),单个数据最大 2GB 写了 10GB 共 2500 条数据(每条包含 4MB 图片及数据), 再测试下,随机读取图片速度(测试前,已用 RamMap 清空系统文件缓存): - 机械盘:27 条数据/秒( 150 MB/s 顺序读取,0.65 MB/s 随机 4K 读取) - 内存盘:323 条数据/秒( 6754 MB/s 顺序读取,310 MB/s 随机 4K 读取,感觉明显没吃满 IO ) |
30
rpWQTyfsAjMCKgPA 252 天前 via iPhone 1
@h3xz 谷歌的 protobuf 。你这个需求和深度学习里准备训练数据十分类似:都是要把图片和一些 meta 信息(标注)序列化到硬盘上方便 retrieval 。
|
34
wxf666 251 天前 1
@h3xz 不知道你是怎么存的。我写个示例,你按情况改了后,执行看看?
1. 准备 SQLite 环境 原因: ① 不想在这儿写 C/C++,太冗长。 ② 后文的脚本,需要用到 dll 没有的,仅命令行版本才有的 readfile 函数。 步骤: ① 打开 https://sqlite.org/download.html ② 找到 sqlite-tools-win-x64-3450200.zip (当前版本)并下载(若 Linux/MacOS 找对应平台的) ③ 解压,得到 sqlite3.exe 2. 准备(存数据的) SQL 文件 参考以下内容,按你自己情况更改后,用 UTF-8 编码,保存为 test.sql 。 ```sql -- 把默认页大小 4KB 改为 64KB 。因为你大部分数据都很大,一次读取便加载更多数据,能提速 PRAGMA page_size = 65536; CREATE TABLE image ( id INTEGER PRIMARY KEY, -- 假设你通过名字来定位图片及其他数据。UNIQUE 既创建了索引,也保证名字唯一 name TEXT NOT NULL UNIQUE, -- 注意,默认生成的时间,是 UTC 时间,比中国慢 8 个小时 created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, extra_data JSON, data BLOB NOT NULL ); BEGIN; -- 省略 id ,SQLite 则会自动填写为最大 ID + 1 。 -- 单引号内的 \ 不用转义。若要表示 ',双写即可。如 'Kai''Sa.jpg'。 -- 文件路径不要包含中文,因为 SQLite 会把 UTF8 字符串,原样调用系统 API ,然而 Windows 会以为是 GBK 编码。。 -- 如果文件路径一定包含中文,请保证其它字符串(如 name 列)没有中文,然后 SQL 文件转为 GBK 编码。 INSERT INTO image (name, data) VALUES ('aaa.jpg', readfile('C:\aaa.jpg')); INSERT INTO image (name, data) VALUES ('bbb.jpg', readfile('C:\bbb.jpg')); INSERT INTO image (name, extra_data, data) VALUES ('ccc.jpg', '{"width": 123, "height": 456}', readfile('C:\ccc.jpg')); COMMIT; -- 可选:碎片整理数据库文件,并去除冗余空间,达到瘦身紧实的效果。 -- VACUUM; SELECT printf('写入了 %d 个文件,共 %d 字节。', COUNT(*), SUM(LENGTH(data))) FROM image; ``` 3. 执行 ```shell sqlite3.exe images.db < test.sql ``` |