问题
我正在运行一个 Matlab 脚本,该脚本创建存储在“.m”文件中的网格几何体;所有这些都是为了使用有限元求解器运行。我给它一些元素,它会创建一个适合边界的四边形网格;图 1 和图 2 显示了两个几何示例。当我仅将它用于单个元素时,它效果很好。另一方面,当我尝试在循环中使用网格生成脚本时,改变所需元素的数量 (n = 1,2,4,...32,64),该文件读起来就像我刚刚运行它位于 n = 1 处。就好像“.m”文件没有被重写。
图 1. 具有 10 个四边形单元的网格。
图 2. 具有 40 个四边形单元的网格。
当前方法
for i = 1:4
n = 2^i % n stores the desired number of elements (2^i is only an example)
% Check if '.m' file exists in current directory
allFiles = dir(currentFolder)
allNames = {allFiles.name}
check = ismember('p4.m',allNames);
% If so, delete the file
if check
delete 'p4.m'
end
% Create the 'p4.m' file
p4Mesh(n)
end
p4Mesh功能总结:
function p4Mesh
close all;
inputfile = 'p4.m';
% open file
fid = fopen(inputfile,'w');
fprintf(fid,'MESH CODE HERE')
% Close file
[st] = fclose('all');
end
最佳答案
摘要
p4
函数定义可能会被缓存,因此您在后续调用 p4()
时不会获取写入磁盘的新版本。使用 clear p4
删除缓存的定义并强制它在每次更新时重新读取 p4.m
。
详细信息
您可能会遇到 Matlab 函数定义缓存的问题。当您第一次调用函数或类时,Matlab 从磁盘上的 .m
文件中读取定义、编译并运行它,然后缓存已编译的定义。文件写入不太可能滞后于 Matlab 循环,因为 fopen/fprintf/fclose 是同步的,而 Matlab 是单线程的。但 Matlab 的函数加载机制可能无法按照您需要的速度注意到磁盘上的更改。
如果 Matlab 发现磁盘上的定义已更改,它将重新读取函数定义。如果您从 Matlab 编辑器保存函数文件,它会立即注意到更改,因为该更改会通过 Matlab。但如果您从代码写入文件的内容,Matlab 看起来就像是外部更改。 Matlab 以依赖于系统的方式获取有关这些更改的更新,例如从操作系统获取文件更改通知事件,或定期轮询文件系统以检查文件时间戳。有关详细信息,请参阅 docchangeNotification
和 docchangeNotificationAdvanced
。
由于您在紧密循环中重写文件,因此更新可能发生得太快,Matlab 的更改通知无法注意到。事实上,Matlab 可能会延迟文件更新检查,直到完成运行用户函数(出于性能和一致性原因),因此可能根本不会执行更新检查,直到循环完成并从该脚本返回到命令行。在这种情况下,如果您在循环内多次调用 p4()
,则每次都会使用第一遍中缓存的函数定义,并且您会看到该函数的相同输出。这听起来像您所描述的。
诊断
要查看这是否是实际发生的情况,请在将其作为 Matlab 函数调用的机制之外检查磁盘上 p4.m
文件的内容。您可以使用许多系统上可用的 md5sum
程序来输出它的一行校验和。或者您可以调用 cat
或使用 fopen/fread/fclose 重新读取它,然后从 Matlab 中将其或其 md5 校验和打印到控制台。如果文件每次在磁盘上看起来都不同,但您通过调用 p4()
获得相同的输出,则可能是函数缓存。
修复
您可以使用 clear
命令从内存中删除其缓存的编译定义,强制 Matlab 从磁盘上当前的 .m
文件重新读取函数。在这种情况下,在调用 p4mesh
写出 p4.m
后,在循环的每次传递中执行 clear p4;
文件,并在再次调用 p4
之前。
在循环内执行 pause
或 drawnow
也可以让 Matlab 的函数缓存机制有机会注意到磁盘上更新的 .m
文件。但是 clear p4
应该更加可靠和确定性,因为它每次都会强制重新读取。
从长远来看,如果您能让教授给您一个生成 .mat
数据文件而不是 .m 的
函数定义文件,就像评论者建议的那样。 p4mesh
,可能会更好.mat
数据文件更适合快速更改的定义,并且不存在此缓存问题。
关于matlab - 如何在 Matlab 上等待文件被写入或删除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23553727/