2012-01-18 82 views
3

我想覆盖在Windows上的Matlab中已经存在的csv文件。问题是有时我在Excel中打开文件。在这种情况下,写入操作失败。如何打开已经与文件共享权限打开的文件

有无论如何覆盖在Matlab文件?我不想使用ActiveX连接到Excel会话并以这种方式编辑文件。

看到this post about FileShare settings让我觉得这可能是可能的,但没有一个fopen参数似乎能够做到这一点。 Excel可能会使用独占写入访问来锁定文件,在这种情况下,没有办法绕过它。有谁知道如何检查这个?问题

例子:

% make csv file 
x = magic(4); 
csvwrite('foo.csv', x); 

% open foo.csv in EXCEL 

% try writing again 
csvwrite('foo.csv', x); % cannot write a new file 
[fid, msg] = fopen('foo.csv' ,'w'); % cannot open handle for writing 

作为一个方面说明,我曾经是能够覆盖文件在Excel中打开时,该文件在Linux中存在,我在网络上打开文件在Windows机器上。

+0

您是否尝试以只读模式在Excel中打开文件? – katrasnikj 2012-01-18 14:45:30

+0

我敢肯定,这将工作,但我很懒,不想手动决定我想编辑哪些文件,哪些我可能会覆盖在Matlab中。 – 2012-01-18 15:07:18

回答

2

这些FileShare设置用于从Win32 API的CreateFile功能家族打开的文件,而不是Matlab公开的C风格fopen家族。 fopen选项不会让你在那里。请参阅http://support.microsoft.com/kb/99173以快速了解差异。 (如果您真的想使用CreateFile或其他Win32 I/O,例如检查Excel是否锁定文件或自己锁定文件,可以使用System.IO.File通过.NET从Matlab调用它。)

无论如何,默认情况下,Excel以写入模式打开文件,并获得独占(写入)锁定。因此,无论如何您都无法打开它,这些文件共享设置只会让您打开文件进行阅读。如果您希望能够在Excel中打开Excel文件时覆盖Excel文件,则需要让Excel以像katrasnikj所示的只读模式打开它。这导致Excel将其读入内存一次,然后释放文件句柄。

尝试打开这些文件的只读文件属性后,通过将其写入attrib命令来写入它们。这将导致Excel在默认情况下以只读方式打开它们。然后清除只读属性,然后再从Matlab中打开它进行重写。

if exist(file, 'file') 
    [status,result] = system(sprintf('attrib -R "%s"', file)); 
end 
[fid,msg] = fopen(file, 'w'); 
% ... write the file and close it ... 
[status,result] = system(sprintf('attrib +R "%s"', file)); 

目前仍然读者与作者之间的竞争条件,但如果你写的文件快,它会是一个短期的窗口。更好的做法是将csv写入同一个目录中的临时文件,然后关闭只读属性足够长的时间,以便将新文件交换到movefilejava.io.File.renameTo。仍然是一场比赛,但可能足以在实践中使用。

您还可以更改文件所在目录的权限,以便您的编写器进程具有修改权限,但运行Excel的用户只具有读取权限。然后,Excels将总是以只读方式打开,而不必乱搞文件属性。