Это работает для меня (используйте «По умолчанию» вместо «UTF8»):
$MyFile = Get-Content $MyPath
$MyFile | Out-File -Encoding "Default" $MyPath
Результатом является ASCII без спецификации.
Обновлено ПРИМЕЧАНИЕ по этому решению : проверка с помощью FileAccess.ReadWrite
не удастся для файлов только для чтения, поэтому решение было изменен для проверки с помощью FileAccess.Read
. Хотя это решение работает, потому что попытка проверки с помощью FileAccess.Read
не удастся, если файл имеет блокировку записи или чтения, однако это решение не будет работать, если файл не имеет записи или чтения. заблокирован, т.е. он был открыт (для чтения или записи) с доступом FileShare.Read или FileShare.Write.
ORIGINAL: Я использовал этот код последние несколько лет, и у меня не было никаких проблем с ним.
Поймите, что вы не уверены в использовании исключений, но вы не можете избегать их все время:
protected virtual bool IsFileLocked(FileInfo file)
{
try
{
using(FileStream stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None))
{
stream.Close();
}
}
catch (IOException)
{
//the file is unavailable because it is:
//still being written to
//or being processed by another thread
//or does not exist (has already been processed)
return true;
}
//file is not locked
return false;
}
Я когда-то должен был загрузить PDFs на архив резервных копий онлайн. Но резервное копирование перестало бы работать, если бы у пользователя был файл, открытый в другой программе (такой как читатель PDF). В моей поспешности я делал попытку нескольких главных ответов в этом потоке, но не мог заставить их работать. То, что действительно работало на меня, пыталось переместить файл PDF в его собственный каталог . Я нашел, что это перестанет работать, если бы файл был открыт в другой программе, и если бы перемещение было успешно то не было бы никакой операции восстановления, требуемой, поскольку было бы то, если бы это было перемещено в отдельный каталог. Я хочу отправить свое основное решение в случае, если это может быть полезно для определенных вариантов использования других.
string str_path_and_name = str_path + '\\' + str_filename;
FileInfo fInfo = new FileInfo(str_path_and_name);
bool open_elsewhere = false;
try
{
fInfo.MoveTo(str_path_and_name);
}
catch (Exception ex)
{
open_elsewhere = true;
}
if (open_elsewhere)
{
//handle case
}
Попробуйте переместить / скопировать файл во временный каталог. Если вы можете, у него нет блокировки, и вы можете безопасно работать во временном каталоге, не получая блокировок. В противном случае просто попробуйте переместить его снова через x секунд.
the only way I know of is to use the Win32 exclusive lock API which isn't too speedy, but examples exist.
Most people, for a simple solution to this, simply to try/catch/sleep loops.
Возможно, вы могли бы использовать FileSystemWatcher и следить за событием Changed.
Я сам этим не пользовался, но, возможно, стоит попробовать. Если средство просмотра файловой системы окажется для этого случая немного тяжелым, я бы выбрал цикл try / catch / sleep.
You can suffer from a thread race condition on this which there are documented examples of this being used as a security vulnerability. If you check that the file is available, but then try and use it you could throw at that point, which a malicious user could use to force and exploit in your code.
Your best bet is a try catch / finally which tries to get the file handle.
try
{
using (Stream stream = new FileStream("MyFilename.txt", FileMode.Open))
{
// File/Stream manipulating code here
}
} catch {
//check here why it failed and ask user to retry if the file is in use.
}