FileShare.ReadWrite в System.IO.Packaging

Я использую System.IO.Packaging для работы с файлами пакетов.

Но похоже, что Package не может открыть файл с доступом для чтения, предоставляющим FileShare.ReadWrite. Вот код:

 myPackage = Package.Open("fileName", FileMode.Open,  FileAccess.Read,  FileShare.ReadWrite);

Когда я пытаюсь загрузить файл, возникает следующее исключение:

Возникло исключение: «System.NotSupportedException» в WindowsBase.dll

Дополнительная информация. Поддерживаются только FileShare.Read и FileShare.None.

Можно ли что-нибудь сделать, чтобы это заработало? Мне нужно, чтобы FileShare был установлен на ReadWrite.

РЕДАКТИРОВАТЬ: я пытаюсь работать с файлом docx в своем коде. Я просто хочу иметь возможность читать содержимое файла без его изменения. В то же время я также хочу, чтобы его можно было редактировать с помощью Word. Это то, чего я пытаюсь достичь. Для этой цели я успешно использовал библиотеку DotNetZip Ionic.Zip. Но я столкнулся с некоторыми ошибками при сохранении файлов с помощью этого. Поэтому мне пришлось вернуться к System.IO.Packaging. Любая помощь будет оценена по достоинству.


person user3868244    schedule 10.09.2015    source источник
comment
Ошибка имеет смысл. Зачем вам нужно писать в архив, пока он читается? Библиотека просто не позволяет (поддерживает) такой параллелизм.   -  person Henk Holterman    schedule 10.09.2015
comment
Наверное, да. Но, как я уже сказал в своем вопросе, я смог сделать это с помощью Ionic.Zip. Но у него есть известные проблемы, которые имеют решающее значение для других моих потребностей.   -  person user3868244    schedule 10.09.2015
comment
Вы должны искать явные обещания, что это сработает. Потому что я не понимаю, как один экземпляр архива может предотвратить перезапись внутренних файлов другим. Это не настоящие файлы с защитой ОС.   -  person Henk Holterman    schedule 10.09.2015


Ответы (1)


Непонятно, почему вы хотите это сделать, но вы можете попробовать указать параметры в файловом потоке напрямую следующим образом:

using (var file = new FileStream(@"myfile", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
    var myPackage = Package.Open(file);
}

ОБНОВЛЕНИЕ, чтобы уточнить, когда это может быть полезно. Предположим, вы пытаетесь сделать что-то вроде этого:

using (var fs1 = new FileStream("myfile", FileMode.Append, FileAccess.Write, FileShare.Read))
using (var fs2 = new FileStream("myfile", FileMode.Open, FileAccess.Read, FileShare.Read)) {
}

Итак, первый файл открывается для записи с FileShare = Read. Потом еще одна попытка открыть файл, на чтение, опять же с FileShare = Read. Это не сработает, потому что если файл уже был открыт для записи, любой запрос с FileShare = read завершится ошибкой. Чтобы сделать эту работу, вы должны сделать это следующим образом:

using (var fs1 = new FileStream("myfile", FileMode.Append, FileAccess.Write, FileShare.Read))
using (var fs2 = new FileStream("myfile", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
}

Здесь вы запрашиваете FileShare.ReadWrite, который позволяет вам читать файл, открытый fs1 для записи.

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

ОБНОВЛЕНИЕ 2. Вполне возможно использовать приведенный выше код для достижения вашей цели (откройте .docx для чтения, пока MS Word открывает его для записи:

using (var file = new FileStream(@"my.docx", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
    var myPackage = Package.Open(file);
    // here do what you want with your .docx
}
person Evk    schedule 10.09.2015
comment
И как вы думаете, это будет безопасно использовать? - person Henk Holterman; 10.09.2015
comment
@HenkHolterman Обновлен пост, пытающийся ответить на ваш вопрос. - person Evk; 10.09.2015
comment
Удаление потока делает объект myPackage бесполезным. - person user3868244; 10.09.2015
comment
Ну, это просто пример, его не нужно утилизировать. Предполагается, что перед тем, как избавиться от него, вы сделали с ним то, что хотели. - person Evk; 10.09.2015
comment
Мне жаль. Я отредактировал вопрос, предоставив больше информации о том, чего я хочу достичь. - person user3868244; 10.09.2015
comment
Открытие файла — это только начало. Обход проверки безопасности не решает реальной проблемы. - person Henk Holterman; 10.09.2015
comment
@HenkHolterman, как вы видите, у автора вполне разумная проблема - прочитать .docx, открытый приложением MS Word. И подход выше действительно решает эту проблему. Во многих случаях вы можете быть совершенно уверены, что пользователь не будет записывать (и сохранять) этот текстовый файл, пока вы читаете, или вы можете явно предупредить пользователя, чтобы он этого не делал. Таким образом, чтение файла, открытого для записи, не требуется в обход проверки безопасности. - person Evk; 10.09.2015
comment
Обязательно сообщите пользователю об отключении функции автосохранения. - person Henk Holterman; 10.09.2015