cdenley
April 26th, 2007, 11:22 AM
I'm writing a C# program that writes data to multiple drives simultaneously. Using a regular BinaryWriter makes my program and the entire system run slow. Would using a Unix stream with the O_DIRECT flag be more efficient. If so, how do I make this work?
Here is a simple example of what I'm trying to do:
using System;
using System.IO;
using Mono.Unix;
using Mono.Unix.Native;
namespace test
{
class MainClass
{
public static void Main(string[] args)
{
int bufferSize=(int)Syscall.sysconf(SysconfName._SC_PA GESIZE);
FileStream fs=new FileStream("data.img",FileMode.Open,FileAccess.Read);
BinaryReader br=new BinaryReader(fs);
int fd=Syscall.open("/dev/sdc",OpenFlags.O_WRONLY|OpenFlags.O_DIRECT);
UnixStream us=new UnixStream(fd);
byte[] buffer=br.ReadBytes(bufferSize);
while(buffer.Length>0)
{
us.Write(buffer,0,buffer.Length);
buffer=br.ReadBytes(bufferSize);
}
us.Close();
br.Close();
}
}
}
The error I get is:
Unhandled Exception: System.ArgumentException: Invalid argument ---> Mono.Unix.UnixIOException: Invalid argument [EINVAL].--- End of inner exception stack trace ---
at Mono.Unix.UnixMarshal.ThrowExceptionForLastError () [0x00000] in /build/buildd/mono-1.2.3.1/mcs/class/Mono.Posix/Mono.Unix/UnixMarshal.cs:456
at Mono.Unix.UnixStream.Write (System.Byte[] buffer, Int32 offset, Int32 count) [0x00056] in /build/buildd/mono-1.2.3.1/mcs/class/Mono.Posix/Mono.Unix/UnixStream.cs:299
at test.MainClass.Main (System.String[] args) [0x00043] in /home/cdenley/test/test/Main.cs:21
If I remove the O_DIRECT flag, the code works.
Here is a simple example of what I'm trying to do:
using System;
using System.IO;
using Mono.Unix;
using Mono.Unix.Native;
namespace test
{
class MainClass
{
public static void Main(string[] args)
{
int bufferSize=(int)Syscall.sysconf(SysconfName._SC_PA GESIZE);
FileStream fs=new FileStream("data.img",FileMode.Open,FileAccess.Read);
BinaryReader br=new BinaryReader(fs);
int fd=Syscall.open("/dev/sdc",OpenFlags.O_WRONLY|OpenFlags.O_DIRECT);
UnixStream us=new UnixStream(fd);
byte[] buffer=br.ReadBytes(bufferSize);
while(buffer.Length>0)
{
us.Write(buffer,0,buffer.Length);
buffer=br.ReadBytes(bufferSize);
}
us.Close();
br.Close();
}
}
}
The error I get is:
Unhandled Exception: System.ArgumentException: Invalid argument ---> Mono.Unix.UnixIOException: Invalid argument [EINVAL].--- End of inner exception stack trace ---
at Mono.Unix.UnixMarshal.ThrowExceptionForLastError () [0x00000] in /build/buildd/mono-1.2.3.1/mcs/class/Mono.Posix/Mono.Unix/UnixMarshal.cs:456
at Mono.Unix.UnixStream.Write (System.Byte[] buffer, Int32 offset, Int32 count) [0x00056] in /build/buildd/mono-1.2.3.1/mcs/class/Mono.Posix/Mono.Unix/UnixStream.cs:299
at test.MainClass.Main (System.String[] args) [0x00043] in /home/cdenley/test/test/Main.cs:21
If I remove the O_DIRECT flag, the code works.