.NET Forum / .NET Framework / CLR / October 2006
Question about file write bufferring.
|
|
Thread rating:  |
Ken Varn - 26 Oct 2006 19:48 GMT I have used the FileStream class to write to a file, however I have some questions concerning disk i/o buffering.
I come from the C++ world where there is a little more control over file buffering and it would appear that some of this control is masked out when using the .NET File I/O classes. Staying on the focus of the FileStream class, I am trying to figure out how to disable any buffering and have all file I/O go directory to a file without it being cached. There is info on setting a member called AutoFlush in the MSDN help, but this member is not part of the FileStream class. It is only in the StreamWriter class. The only other alternative I could see is to call Flush() everytime I want to flush the stream. I would prefer to have the stream buffer size set, similar to the setbuf() function in C++, or via open flags that are part of the win32 CreateFile() or OpenFile() functions.
Can someone give me some insight on how to control file I/O buffering and set me straight on how .NET handles it?
 Signature ----------------------------------- Ken Varn Senior Software Engineer Diebold Inc.
EmailID = varnk Domain = Diebold.com -----------------------------------
Bryan Phillips - 27 Oct 2006 03:18 GMT Try creating the FileStream this way so that you can modify the parameters to the CreateFile method:
(pasted from MSDN help)
using System; using Microsoft.Win32.SafeHandles; using System.Runtime.InteropServices; using System.ComponentModel;
class SafeHandlesExample {
static void Main() { try {
UnmanagedFileLoader loader = new UnmanagedFileLoader("example.xml");
FileStream fs = new FileStream(loader.SafeFileHandle, FileAccess.Write);
} catch (Exception e) { Console.WriteLine(e); } Console.ReadLine();
} }
class UnmanagedFileLoader {
public const short FILE_ATTRIBUTE_NORMAL = 0x80; public const short INVALID_HANDLE_VALUE = -1; public const uint GENERIC_READ = 0x80000000; public const uint GENERIC_WRITE = 0x40000000; public const uint CREATE_NEW = 1; public const uint CREATE_ALWAYS = 2; public const uint OPEN_EXISTING = 3;
// Use interop to call the CreateFile function. // For more information about CreateFile, // see the unmanaged MSDN reference library. [DllImport("kernel32.dll", SetLastError = true)] static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);
private SafeFileHandle handleValue = null;
public UnmanagedFileLoader(string Path) { Load(Path); }
public void Load(string Path) { if (Path == null && Path.Length == 0) { throw new ArgumentNullException("Path"); }
// Try to open the file. handleValue = CreateFile(Path, GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
// If the handle is invalid, // get the last Win32 error // and throw a Win32Exception. if (handleValue.IsInvalid) { Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error()); } }
public SafeFileHandle Handle { get { // If the handle is valid, // return it. if (!handleValue.IsInvalid) { return handleValue; } else { return null; } }
}
}
Bryan Phillips MCSD, MCDBA, MCSE Blog: http://bphillips76.spaces.live.com
> I have used the FileStream class to write to a file, however I have some > questions concerning disk i/o buffering. [quoted text clipped - 23 lines] > Domain = Diebold.com > ----------------------------------- Ken Varn - 27 Oct 2006 14:36 GMT So outside of using interop, there is no way to control buffering when using the standard .net classes for file i/o?
 Signature ----------------------------------- Ken Varn Senior Software Engineer Diebold Inc.
EmailID = varnk Domain = Diebold.com -----------------------------------
Try creating the FileStream this way so that you can modify the parameters to the CreateFile method:
(pasted from MSDN help)
using System; using Microsoft.Win32.SafeHandles; using System.Runtime.InteropServices; using System.ComponentModel;
class SafeHandlesExample {
static void Main() { try {
UnmanagedFileLoader loader = new UnmanagedFileLoader("example.xml");
FileStream fs = new FileStream(loader.SafeFileHandle, FileAccess.Write);
} catch (Exception e) { Console.WriteLine(e); } Console.ReadLine();
} }
class UnmanagedFileLoader {
public const short FILE_ATTRIBUTE_NORMAL = 0x80; public const short INVALID_HANDLE_VALUE = -1; public const uint GENERIC_READ = 0x80000000; public const uint GENERIC_WRITE = 0x40000000; public const uint CREATE_NEW = 1; public const uint CREATE_ALWAYS = 2; public const uint OPEN_EXISTING = 3;
// Use interop to call the CreateFile function. // For more information about CreateFile, // see the unmanaged MSDN reference library. [DllImport("kernel32.dll", SetLastError = true)] static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);
private SafeFileHandle handleValue = null;
public UnmanagedFileLoader(string Path) { Load(Path); }
public void Load(string Path) { if (Path == null && Path.Length == 0) { throw new ArgumentNullException("Path"); }
// Try to open the file. handleValue = CreateFile(Path, GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
// If the handle is invalid, // get the last Win32 error // and throw a Win32Exception. if (handleValue.IsInvalid) { Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error()); } }
public SafeFileHandle Handle { get { // If the handle is valid, // return it. if (!handleValue.IsInvalid) { return handleValue; } else { return null; } }
}
}
Bryan Phillips MCSD, MCDBA, MCSE Blog: http://bphillips76.spaces.live.com
"Ken Varn" <nospam> wrote in message news:#FWYe9S#GHA.4800@TK2MSFTNGP05.phx.gbl:
> I have used the FileStream class to write to a file, however I have some > questions concerning disk i/o buffering. [quoted text clipped - 25 lines] > Domain = Diebold.com > ----------------------------------- Bryan Phillips - 27 Oct 2006 22:58 GMT Unfortunately, not without doing extra work.
Bryan Phillips MCSD, MCDBA, MCSE Blog: http://bphillips76.spaces.live.com
> So outside of using interop, there is no way to control buffering when using > the standard .net classes for file i/o? [quoted text clipped - 146 lines] > > Domain = Diebold.com > > ----------------------------------- Willy Denoyette [MVP] - 28 Oct 2006 11:35 GMT | Unfortunately, not without doing extra work. Not needed in V2, see my other reply.
Willy.
Willy Denoyette [MVP] - 28 Oct 2006 11:34 GMT |I have used the FileStream class to write to a file, however I have some | questions concerning disk i/o buffering. [quoted text clipped - 13 lines] | Can someone give me some insight on how to control file I/O buffering and | set me straight on how .NET handles it? In V2 of the framework, you can force unbuffered IO by means of the FileOptions.WriteThrough option in the FileStream contructor overload that takes a FileOptions argument.
Willy.
William Stacey [C# MVP] - 30 Oct 2006 20:49 GMT Not sure this helps, but you can set the buf size (min of 8 bytes) in the FileStream ctor and use Flush when you need it.
using (FileStream fs = new FileStream(@"c:\junk.txt", FileMode.Create, FileAccess.Write, FileShare.None, 10)) { byte[] buf = new byte[10]; fs.Write(buf, 0, buf.Length); fs.Flush(); // Not sure this would be needed? }
 Signature William Stacey [C# MVP]
|I have used the FileStream class to write to a file, however I have some | questions concerning disk i/o buffering. [quoted text clipped - 13 lines] | Can someone give me some insight on how to control file I/O buffering and | set me straight on how .NET handles it? Ken Varn - 31 Oct 2006 19:08 GMT I think that this would only work for fixed length data.
 Signature ----------------------------------- Ken Varn Senior Software Engineer Diebold Inc.
EmailID = varnk Domain = Diebold.com -----------------------------------
Not sure this helps, but you can set the buf size (min of 8 bytes) in the FileStream ctor and use Flush when you need it.
using (FileStream fs = new FileStream(@"c:\junk.txt", FileMode.Create, FileAccess.Write, FileShare.None, 10)) { byte[] buf = new byte[10]; fs.Write(buf, 0, buf.Length); fs.Flush(); // Not sure this would be needed? }
 Signature William Stacey [C# MVP]
|I have used the FileStream class to write to a file, however I have some | questions concerning disk i/o buffering. [quoted text clipped - 6 lines] | setting a member called AutoFlush in the MSDN help, but this member is not | part of the FileStream class. It is only in the StreamWriter class. The
| only other alternative I could see is to call Flush() everytime I want to | flush the stream. I would prefer to have the stream buffer size set, | similar to the setbuf() function in C++, or via open flags that are part of
| the win32 CreateFile() or OpenFile() functions. | | Can someone give me some insight on how to control file I/O buffering and | set me straight on how .NET handles it?
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|