Serialization 是否可以通过TestStream截取matlab save()文件
在matlab中,可以使用matlab save()调用将matlab对象,甚至整个工作空间写入文件。我想截取ByTestStream并在它进入文件之前对其进行后处理,这可能吗?或者,可以指定ByTestStream写入的filedescriptor,而不是通常作为参数进入save()调用的文件名 请注意,我不是在寻找用matlab编写文件的替代方法,我知道我可以用fopen()编写文件并编写任何我想要的内容,但重点是我想(重新)使用save调用内部的对象序列化,而不是再发明我自己的 load()调用当然会出现一个类似的问题,但在这种情况下,在进入反序列化过程之前拦截ByTestStream,但我想如果save()是可能的,那么load()问题的解决方案自然会随之而来 一些澄清:Serialization 是否可以通过TestStream截取matlab save()文件,serialization,matlab,save,Serialization,Matlab,Save,在matlab中,可以使用matlab save()调用将matlab对象,甚至整个工作空间写入文件。我想截取ByTestStream并在它进入文件之前对其进行后处理,这可能吗?或者,可以指定ByTestStream写入的filedescriptor,而不是通常作为参数进入save()调用的文件名 请注意,我不是在寻找用matlab编写文件的替代方法,我知道我可以用fopen()编写文件并编写任何我想要的内容,但重点是我想(重新)使用save调用内部的对象序列化,而不是再发明我自己的 load(
- matlab中的
函数中使用的功能似乎不仅仅是常规的顺序写入。通过检查库的目标代码,似乎使用save
(以前称为matPutVariable
)实现了保存功能,它将matPutArray
类型的给定变量写入使用mxArray*
打开的matOpen
类型的文件中。这里的问题是MATFile*
说明中的以下文本: 如果MAT文件中不存在matPutVariable
,则函数会将其追加到末尾。如果文件中存在同名的mxArray
,则该函数通过重写文件,将现有的mxArray
替换为新的mxArray
这意味着mxArray
函数必须通过文件进行搜索,显然,使用管道时无法进行搜索,因此使用管道实现对ByTestStream的处理在使用现有序列化功能时是不可能的matPutVariable
save('workspace.mat');
fid = fopen('workspace.mat','r');
byteData = fread(fid,inf,'*uint8');
fclose(fid);
%# ... Process byteData here ...
fid = fopen('workspace.mat','w');
fwrite(fid,byteData,'uint8');
fclose(fid);
旧答案:
对于用户定义的类对象,我相信您要寻找的是重载的and方法,在将对象保存到文件或从文件加载对象之前对其进行调用。当从.MAT文件转换到或转换到.MAT文件时,可以使用这些方法,以便可以以不同的方式格式化对象。但是,我认为您不能对内置数据类型执行此操作,只能对用户定义的对象执行此操作。对于HG对象,您可以通过内部(可修改)*.m文件截获保存处理,此处将对此进行说明:
您的最佳选择可能是将mat文件写入tmpfs/ramdisk,然后在将其保存到磁盘之前对其进行加密。您牺牲了可移植性,依靠操作系统提供安全的虚拟内存,但如果您甚至不能信任本地磁盘,您可能无法实现令人满意的安全性
顺便问一下,为什么您根本无法信任本地磁盘,甚至无法将临时文件放在权限设置为仅允许拥有matlab进程的用户(和root用户)访问的目录中?您是否正在尝试实施DRM系统 也许你可以做如下事情:
%# serialize objects into a byte array using Java
bout = java.io.ByteArrayOutputStream();
out = java.io.ObjectOutputStream(bout);
out.writeObject( rand(3) ) %# MATLAB matrix
out.writeObject( num2cell(rand(3)) ) %# MATLAB cell array
out.flush()
out.close()
bout.close()
b = bout.toByteArray(); %# vector of type int8
%# perform processing on `b` ...
%# write byte[] stream to file
save file.mat b
然后,在相反的方向,您只需加载保存的MAT文件,反转您执行的任何处理,并反序列化字节流以接收原始对象
%# load MAT-file
load file.mat b
b = typecast(b,'int8'); %# cast as int8 just to be sure
%# undo any processing on `b`...
%# deserialize
in = java.io.ObjectInputStream( java.io.ByteArrayInputStream(b) );
X1 = double( in.readObject() ) %# recover matrix
X2 = cell( in.readObject() ) %# recover cell array
in.close()
请注意,您必须自己维护变量的元信息,例如它们的编号和类型(也许您可以将其保存在同一MAT文件中),并使用自定义包装函数来处理所有封送处理,但您得到的想法是
我还遇到了一些关于FEX的意见书,它们有助于序列化/反序列化MATLAB类型:
- 您不能加密变量的内容吗
使用
whos
,您可以按字母顺序获得所有变量的列表。对于每一个,使用加密算法生成一个大小相同的掩码,并将“true”值本身替换为XOR掩码。要完成此操作,请使用save
保存加密的变量。变量的名称和大小是可见的,但这可能并不重要(如果必要,也可以对名称进行加密)
以相同的方式加载。我也对这个问题感兴趣。我找到了一些东西,但什么都不管用:
- matlab save stdio您可以找到此隐藏功能,但它不起作用
- engGetArray/engPutArray“此例程允许您将变量复制出工作区。”
- <
edit([matlabroot '/extern/examples/eng_mat/matcreat.c']);
edit([matlabroot '/extern/examples/eng_mat/matcreat.cpp']);
$ openssl enc -aes-256-cbc -a -e -in fifo -out safe # (in another terminal, "echo foo > fifo") enter aes-256-cbc encryption password: Verifying - enter aes-256-cbc encryption password: $ cat safe U2FsdGVkX18aWBw0Uz8N3SfrRg4PigL609F+HQPuc6o=
$ openssl enc -aes-256-cbc -a -d -in safe enter aes-256-cbc decryption password: foo
mxArray* mxSerialize(const mxArray*); mxArray* mxDeserialize(const void*, size_t);
% A cell array of several data types >> byteStream = getByteStreamFromArray({pi, 'abc', struct('a',5)}); % 1x312 uint8 array >> getArrayFromByteStream(byteStream) ans = [3.14159265358979] 'abc' [1x1 struct]