servuo/Server/Persistence/FileOperations.cs
VitaNex f840e50340 Updated .editorconfig file with advanced configuration settings that will help maintain user code style and best practices with most IDE's.
Complete core housekeeping operation using "Profile 1" with new .editorconfig settings.
2021-01-15 12:51:10 -08:00

105 lines
No EOL
2.6 KiB
C#

using System;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
namespace Server
{
public static class FileOperations
{
public const int KB = 1024;
public const int MB = 1024 * KB;
private const FileOptions NoBuffering = (FileOptions)0x20000000;
[DllImport("Kernel32", CharSet = CharSet.Auto, SetLastError = true)]
private static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, FileShare dwShareMode, IntPtr securityAttrs, FileMode dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);
private static int bufferSize = 1 * MB;
private static int concurrency = 1;
private static bool unbuffered = true;
public static int BufferSize
{
get => bufferSize;
set => bufferSize = value;
}
public static int Concurrency
{
get => concurrency;
set => concurrency = value;
}
public static bool Unbuffered
{
get => unbuffered;
set => unbuffered = value;
}
public static bool AreSynchronous => concurrency < 1;
public static bool AreAsynchronous => concurrency > 0;
public static FileStream OpenSequentialStream(string path, FileMode mode, FileAccess access, FileShare share)
{
var options = FileOptions.SequentialScan;
if (concurrency > 0)
{
options |= FileOptions.Asynchronous;
}
if (unbuffered)
{
options |= NoBuffering;
}
else
{
return new FileStream(path, mode, access, share, bufferSize, options);
}
var fileHandle = CreateFile(path, (int)access, share, IntPtr.Zero, mode, (int)options, IntPtr.Zero);
if (fileHandle.IsInvalid)
{
throw new IOException();
}
return new UnbufferedFileStream(fileHandle, access, bufferSize, concurrency > 0);
}
private class UnbufferedFileStream : FileStream
{
private readonly SafeFileHandle fileHandle;
public UnbufferedFileStream(SafeFileHandle fileHandle, FileAccess access, int bufferSize, bool isAsync)
: base(fileHandle, access, bufferSize, isAsync)
{
this.fileHandle = fileHandle;
}
public override void Write(byte[] array, int offset, int count)
{
base.Write(array, offset, bufferSize);
}
public override IAsyncResult BeginWrite(byte[] array, int offset, int numBytes, AsyncCallback userCallback, object stateObject)
{
return base.BeginWrite(array, offset, bufferSize, userCallback, stateObject);
}
protected override void Dispose(bool disposing)
{
if (!fileHandle.IsClosed)
{
fileHandle.Close();
}
base.Dispose(disposing);
}
}
}
}