/*************************************************************************** * FileOperations.cs * ------------------- * begin : May 1, 2002 * copyright : (C) The RunUO Software Team * email : info@runuo.com * * $Id$ * ***************************************************************************/ /*************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * ***************************************************************************/ using System; using System.IO; using System.Collections.Generic; using System.Text; #if !MONO using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; #endif namespace Server { public static class FileOperations { public const int KB = 1024; public const int MB = 1024 * KB; #if !MONO 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 ); #endif private static int bufferSize = 1 * MB; private static int concurrency = 1; private static bool unbuffered = true; public static int BufferSize { get { return bufferSize; } set { bufferSize = value; } } public static int Concurrency { get { return concurrency; } set { concurrency = value; } } public static bool Unbuffered { get { return unbuffered; } set { unbuffered = value; } } public static bool AreSynchronous { get { return ( concurrency < 1 ); } } public static bool AreAsynchronous { get { return ( concurrency > 0 ); } } public static FileStream OpenSequentialStream( string path, FileMode mode, FileAccess access, FileShare share ) { FileOptions options = FileOptions.SequentialScan; if ( concurrency > 0 ) { options |= FileOptions.Asynchronous; } #if MONO return new FileStream( path, mode, access, share, bufferSize, options ); #else if ( unbuffered ) { options |= NoBuffering; } else { return new FileStream( path, mode, access, share, bufferSize, options ); } SafeFileHandle 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 ) ); #endif } #if !MONO private class UnbufferedFileStream : FileStream { private 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 ); } } #endif } }