Windows не позволяет двум процессам совместно использовать потоковую передачу файловой системы, поэтому вы не можете решить проблему, но вы можете подождать, пока файл используется, и затем получить к нему доступ.
Я предлагаю вам избегать использования в loopE решения (for
, while
или рекурсивного вызова), поскольку они могут вызвать утечки памяти. Вместо этого я предлагаю вам использовать вращающийся цикл (это цикл, который ожидает следующего тактового цикла, чтобы достичь следующей итерации).
Этот вид цикла уже реализован в большинстве языков, таких как C #.
Сначала импортируйте это:
using System.Threading;
Затем вызовите SpinWait.SpinUntil
, передав в качестве параметра делегат Func<bool>
: этот делегат будет вызываться до тех пор, пока он не вернет условие true
.
SpinWait.SpinUntil(delegate
{
try
{
File.Open("yourPath", FileMode.Open, FileAccess.Read, FileShare.None);
}
catch
{
return false;
}
return true;
});
На данный момент вы ждете, пока не сможете открыть поток для файла, а затем откройте его!
Очевидно, вы также можете создать полезный класс:
using System.Diagnostics;
using System.Threading;
public class HardFileStream : FileStream
{
[DebuggerHidden, DebuggerStepperBoundary]
private static T Preconstructor<T>(T value, string path)
{
SpinWait.SpinUntil(delegate
{
try
{
using (File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
}
}
catch
{
return false;
}
return true;
});
Thread.MemoryBarrier();
return value;
}
[DebuggerHidden, DebuggerStepperBoundary]
public HardFileStream(string path, FileMode mode)
: base(Preconstructor(path, path), mode)
{
}
[DebuggerHidden, DebuggerStepperBoundary]
public HardFileStream(string path, FileMode mode, FileAccess access)
: base(Preconstructor(path, path), mode, access)
{
}
[DebuggerHidden, DebuggerStepperBoundary]
public HardFileStream(string path, FileMode mode, FileAccess access, FileShare share)
: base(Preconstructor(path, path), mode, access, share)
{
}
[DebuggerHidden, DebuggerStepperBoundary]
public HardFileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize)
: base(Preconstructor(path, path), mode, access, share, bufferSize)
{
}
[DebuggerHidden, DebuggerStepperBoundary]
public HardFileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options)
: base(Preconstructor(path, path), mode, access, share, bufferSize, options)
{
}
[DebuggerHidden, DebuggerStepperBoundary]
public HardFileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool useAsync)
: base(Preconstructor(path, path), mode, access, share, bufferSize, useAsync)
{
}
[DebuggerHidden, DebuggerStepperBoundary]
public HardFileStream(string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, FileOptions options)
: base(Preconstructor(path, path), mode, rights, share, bufferSize, options)
{
}
[DebuggerHidden, DebuggerStepperBoundary]
public HardFileStream(string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, FileOptions options, FileSecurity fileSecurity)
: base(Preconstructor(path, path), mode, rights, share, bufferSize, options, fileSecurity)
{
}
}
Затем вы можете использовать HardFileStream
вместо FileStream
(кроме случаев, когда вы используете файловые дескрипторы, функция, которая еще не поддерживается в моем классе):
StreamReader sr = new StreamReader(new HardFileStream(path, FileMode.Open, FileAccess.Read));