using System;
using System.Runtime.InteropServices;
using System.Text;
class FileRead
{
const uint GENERIC_READ = 0x80000000;
const uint OPEN_EXISTING = 3;
int handle;
public FileRead(string filename)
{
// Эта функция открывает существущийй файл на диске для чтения
handle = CreateFile(filename,
GENERIC_READ,
0,
0,
OPEN_EXISTING,
0,
0);
}
// Импортируем Win32-функцию CreateFile
[DllImport("kernel32", SetLastError=true)]
static extern unsafe int CreateFile(
string filename,
uint desiredAccess,
uint shareMode,
uint attributes, // really SecurityAttributes pointer
uint creationDisposition,
uint flagsAndAttributes,
uint templateFile);
// Импортируем Win32-функцию ReadFile
[DllImport("kernel32", SetLastError=true)]
static extern unsafe bool ReadFile(int hFile,
void* lpBuffer, int nBytesToRead,
int* nBytesRead, int overlapped);
// Импортируем Win32-функцию GetLastError
[DllImport("kernel32", SetLastError=true)]
static extern int GetLastError();
// Этот метод помечен как unsafe, так как он использует указатели.
// Можно также пометить как unsafe лишь блок кода - нуно заключить его в блок unsafe {...}
public unsafe int Read(byte[] buffer, int index, int count)
{
int n = 0;
// Блок fixed запрещает передвигать переменную в памяти, чтобы указатель на нее не изменился
fixed (byte* p = buffer)
{
ReadFile(handle, p + index, count, &n, 0);
}
return n;
}
}
class Test
{
public static void Main(string[] args)
{
FileRead fr = new FileRead(args[0]);
byte[] buffer = new byte[128];
ASCIIEncoding e = new ASCIIEncoding();
// Читаем весь файл блоками по 128 байт
while (fr.Read(buffer, 0, 128) != 0)
{
Console.Write("{0}", e.GetString(buffer));
}
}
}
|