Как открыть файл, который уже открыт с разрешениями на обмен файлами - PullRequest
3 голосов
/ 18 января 2012

Я пытаюсь переписать CSV-файл, который уже существует в Matlab в Windows.Проблема иногда в том, что у меня файл открыт в Excel.В этом случае операция записи завершается неудачей.

Есть ли способ перезаписать файл в Matlab?Я НЕ хочу использовать ActiveX для подключения к сеансу Excel и редактирования файла таким образом.

Просмотр этого поста о настройках FileShare заставил меня думать, что это возможно, но ни один изПараметры 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 box, и у меня был файл, открытый по сети на Windows box.

1 Ответ

2 голосов
/ 18 января 2012

Эти настройки FileShare предназначены для файлов, открытых из семейства функций Win32 API CreateFile, а не из семейства C style fopen, которые предоставляет Matlab. Опции fopen не приведут вас туда. См. http://support.microsoft.com/kb/99173 для краткого изложения различий. (Если вы действительно хотите использовать CreateFile или другой ввод / вывод Win32, например, чтобы проверить, заблокировал ли файл Excel или заблокировали его самостоятельно, вы можете вызвать его из Matlab через .NET, используя System.IO.File.)

Независимо от того, по умолчанию 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 во временный файл в том же каталоге, а затем просто отключить атрибут «только для чтения», чтобы заменить новый файл на movefile или java.io.File.renameTo. Все еще гонка, но, вероятно, достаточно хорошая, чтобы использовать на практике.

Вы также можете изменить разрешения для каталога, в котором находятся файлы, чтобы ваш процесс записи имел разрешения на изменение, но пользователи, работающие с Excel, имеют только права на чтение. Тогда Excels будет всегда открываться только для чтения, и вам не придется возиться с атрибутами файлов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...