1
using
System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.IO;
5 using System.Runtime.InteropServices; /**/ /* 平台调用命名空间 */
6
7 namespace CSharpFoundationStudy
8 {
9 /**//*
10 * 操作系统实验之快速文件系统C#实现
11 * P/Invoke 平台调用
12 * extern 修饰符用于声明由程序集外部实现的成员函数
13 * 经常用于系统API函数的调用(通过 DllImport )。注意,和DllImport一起使用时要加上static修饰符,也可以用于对于同一程序集不同版本组件的调用(用 extern 声明别名)
14 */
15
16 public enum dwCreationDisposition
17 {
18 CREATE_NEW = 1,
19 CREATE_ALWAYS = 2,
20 OPEN_EXISTING = 3,
21 OPEN_ALWAYS = 4,
22 TRUNCATE_EXISTING = 5,
23 }
24
25 //异步调用需要使用
26 public struct OVERLAPPED
27 {
28 public int Internal;
29 public int InternalHigh;
30 public int Offset;
31 public int OffsetHigh;
32 public int hEvent;
33 }
34
35 /**//*
36 * MSDN文档
37 * 要封装平台功能,一种有效的方法是将常用的 DLL 函数包装在托管类中。虽然不必在每种情形下都这样做,但由于定义 DLL 函数可能会相当麻烦并且容易出错,所以提供类包装是一种很方便的方法。
38 * 在一个类中,为每个要调用的 DLL 函数定义静态方法。定义中可以包括一些附加信息,如在传递方法参数时使用的字符集或调用约定;如果省略这些信息,将选择默认设置。
39 * 包装之后,就可以按照对其他任何静态函数调用方法的相同方式来对该函数调用方法。平台调用将自动处理底层的导出函数。
40 */
41 class Win32Invoke
42 {
43 // dwDesiredAccess
44 public const uint GENERIC_READ = 0x80000000;
45 public const uint GENERIC_WRITE = 0x40000000;
46
47 //dwShareMode
48 public const uint FILE_NOSHARE = 0;
49 public const uint FILE_SHARE_READ = 0x00000001;
50 public const uint FILE_SHARE_WRITE = 0x00000002;
51
52 //dwFlagsAndAttributes
53 // 定义:C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Include\WinBase.h
54 public const uint FILE_FLAG_WRITE_THROUGH = 0x80000000;
55 public const uint FILE_FLAG_OVERLAPPED = 0x40000000; // 异步方法
56 public const uint FILE_FLAG_NO_BUFFERING = 0x20000000; // 无缓冲
57 public const uint FILE_FLAG_RANDOM_ACCESS = 0x10000000;
58 public const uint FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000; // 缓冲
59
60 //VirtualAlloc参数
61 //flAllocationType
62 public const uint MEM_COMMIT = 0x1000;
63 public const uint MEM_RESERVE = 0x2000;
64 //flProtect
65 public const uint PAGE_READWRITE = 0x04;
66 public const uint PAGE_READONLY = 0x02;
67 public const uint PAGE_NOACCESS = 0x01;
68
69 //This function closes an open object handle[MSDN]
70 [DllImport("kernel32.dll", SetLastError = true)]
71 public static extern bool CloseHandle(IntPtr hObject);
72
73 [DllImport("kernel32.dll", SetLastError = true)]
74 public static extern IntPtr CreateFile(
75 string lpFileName,
76 uint desiredAccess,
77 uint shareMode,
78 uint lpSecurityAttributes,
79 dwCreationDisposition creationDisposition,
80 uint flagsAndAttributes,
81 int hTemplateFile);
82
83 [DllImport("kernel32.dll", SetLastError = true)]
84 public static extern bool ReadFile(
85 IntPtr hFile, //Handle to the file to be read.
86 byte[] lpBuffer, //Pointer to the buffer that receives the data read from the file
87 int nNumberOfBytesToRead, //Number of bytes to be read from the file
88 ref int lpNumberOfBytesRead, //Pointer to the number of bytes read.
89 ref OVERLAPPED overlapped);
90
91 //Return: Nonzero indicates success. Zero indicates failure
92 [DllImport("kernel32.dll", SetLastError = true)]
93 public static extern bool WriteFile(
94 IntPtr hFile, //Handle to the file to be written to
95 byte[] lpBuffer, //Pointer to the buffer containing the data to write to the file
96 int nNumberOfBytesToWrite, //Number of bytes to write to the file
97 ref int lpNumberOfBytesWritten, //Pointer to the number of bytes written by this function call
98 ref OVERLAPPED overlapped);
99
100 //The GetDiskFreeSpace function retrieves information about the specified disk, including the amount of free space on the disk
101 [DllImport("kernel32.dll", SetLastError = true)]
102 public static extern bool GetDiskFreeSpace(
103 string lpRootPathName, //Pointer to a null-terminated string that specifies the root directory of the disk for which information is to be returned.
104 ref int lpSectorsPerCluster, //Pointer to a variable that receives the number of sectors per cluster
105 ref int lpBytesPerSector, //Pointer to a variable that receives the number of bytes per sector
106 ref int lpNumberOfFreeClusters, //Pointer to a variable for the total number of free clusters on the disk that are available to the user who is associated with the calling thread.
107 ref int lpTotalNumberOfClusters); //Pointer to a variable for the total number of clusters on the disk that are available
108
109 //Reserves or commits a region of pages in the virtual address space of the calling process
110 [DllImport("kernel32.dll", SetLastError = true)]
111 public static extern IntPtr VirtualAlloc(
112 IntPtr lpAddress,
113 uint dwSize,
114 uint flAllocationType,
115 uint flProtect);
116
117 [DllImport("kernel32.dll", SetLastError = true)]
118 public static extern bool VirtualFree(
119 IntPtr lpAddress,
120 uint dwSize,
121 uint dwFreeType);
122
123 [DllImport("kernel32.dll", SetLastError = true)]
124 public static extern uint GetTickCount();
125 }
126
127 class quickFileSys
128 {
129 //读取文件长度为 2M
130 public static readonly int length = 1024 * 1024 * 2;
131
132 //返回实际读取的字节数
133 public static int ReadFrom(string sourceFileName, byte[] sourceBytes, uint mode)
134 {
135 int count = 0;
136 OVERLAPPED overlap = new OVERLAPPED();
137
138 IntPtr fHandle = Win32Invoke.CreateFile(sourceFileName, Win32Invoke.GENERIC_READ, Win32Invoke.FILE_SHARE_READ, 0, dwCreationDisposition.OPEN_EXISTING, mode, 0);
139
140 Win32Invoke.ReadFile(fHandle, sourceBytes, length, ref count, ref overlap);
141
142 return count;
143 }
144
145 //返回实际写入的字节数
146 public static int WriteTo(string destiFileName, byte[] destiBytes, uint mode)
147 {
148 int count = 0;
149 OVERLAPPED overlap = new OVERLAPPED();
150
151 IntPtr fHandle = Win32Invoke.CreateFile(destiFileName, Win32Invoke.GENERIC_WRITE, Win32Invoke.FILE_NOSHARE, 0, dwCreationDisposition.CREATE_ALWAYS, mode, 0);
152
153 Win32Invoke.WriteFile(fHandle, destiBytes, length, ref count, ref overlap);
154
155 return count;
156 }
157
158 public static uint filter(string sourceFileName, string destiFileName, uint mode)
159 {
160 byte[] data = new byte[length];
161 uint dwStartTime = Win32Invoke.GetTickCount();
162 ReadFrom(sourceFileName, data, mode);
163 WriteTo(destiFileName, data, mode);
164 uint dwEndTime = Win32Invoke.GetTickCount();
165
166 return dwEndTime - dwStartTime;
167 }
168
169 public static void display(uint mode, string displayStr)
170 {
171 int loop = 10;
172 uint dwTimeElapsed = 0;
173 uint total_nobuffering = 0;
174 for (int i = 0; i < loop; i++)
175 {
176 dwTimeElapsed = filter("test.txt", string.Format(displayStr + "{0}.txt", i), mode);
177 total_nobuffering += dwTimeElapsed;
178 Console.WriteLine(string.Format(displayStr + "{0}: {1}ms", i, dwTimeElapsed));
179 }
180 Console.WriteLine(string.Format(displayStr + "[Total]: {0}ms", total_nobuffering));
181 Console.WriteLine(string.Format(displayStr + "[Average]: {0}ms", total_nobuffering / loop));
182 Console.WriteLine("**************************************************************************");
183 }
184
185 //public static void Main()
186 //{
187 // display(Win32Invoke.FILE_FLAG_NO_BUFFERING, "file_flag_no_buffering");
188 // display(Win32Invoke.FILE_FLAG_SEQUENTIAL_SCAN, "file_flag_sequential_scan");
189 // display(Win32Invoke.FILE_FLAG_OVERLAPPED, "file_flag_overlapped");
190 // Console.Read();
191 //}
192 }
193}
194
195
2 using System.Collections.Generic;
3 using System.Text;
4 using System.IO;
5 using System.Runtime.InteropServices; /**/ /* 平台调用命名空间 */
6
7 namespace CSharpFoundationStudy
8 {
9 /**//*
10 * 操作系统实验之快速文件系统C#实现
11 * P/Invoke 平台调用
12 * extern 修饰符用于声明由程序集外部实现的成员函数
13 * 经常用于系统API函数的调用(通过 DllImport )。注意,和DllImport一起使用时要加上static修饰符,也可以用于对于同一程序集不同版本组件的调用(用 extern 声明别名)
14 */
15
16 public enum dwCreationDisposition
17 {
18 CREATE_NEW = 1,
19 CREATE_ALWAYS = 2,
20 OPEN_EXISTING = 3,
21 OPEN_ALWAYS = 4,
22 TRUNCATE_EXISTING = 5,
23 }
24
25 //异步调用需要使用
26 public struct OVERLAPPED
27 {
28 public int Internal;
29 public int InternalHigh;
30 public int Offset;
31 public int OffsetHigh;
32 public int hEvent;
33 }
34
35 /**//*
36 * MSDN文档
37 * 要封装平台功能,一种有效的方法是将常用的 DLL 函数包装在托管类中。虽然不必在每种情形下都这样做,但由于定义 DLL 函数可能会相当麻烦并且容易出错,所以提供类包装是一种很方便的方法。
38 * 在一个类中,为每个要调用的 DLL 函数定义静态方法。定义中可以包括一些附加信息,如在传递方法参数时使用的字符集或调用约定;如果省略这些信息,将选择默认设置。
39 * 包装之后,就可以按照对其他任何静态函数调用方法的相同方式来对该函数调用方法。平台调用将自动处理底层的导出函数。
40 */
41 class Win32Invoke
42 {
43 // dwDesiredAccess
44 public const uint GENERIC_READ = 0x80000000;
45 public const uint GENERIC_WRITE = 0x40000000;
46
47 //dwShareMode
48 public const uint FILE_NOSHARE = 0;
49 public const uint FILE_SHARE_READ = 0x00000001;
50 public const uint FILE_SHARE_WRITE = 0x00000002;
51
52 //dwFlagsAndAttributes
53 // 定义:C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Include\WinBase.h
54 public const uint FILE_FLAG_WRITE_THROUGH = 0x80000000;
55 public const uint FILE_FLAG_OVERLAPPED = 0x40000000; // 异步方法
56 public const uint FILE_FLAG_NO_BUFFERING = 0x20000000; // 无缓冲
57 public const uint FILE_FLAG_RANDOM_ACCESS = 0x10000000;
58 public const uint FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000; // 缓冲
59
60 //VirtualAlloc参数
61 //flAllocationType
62 public const uint MEM_COMMIT = 0x1000;
63 public const uint MEM_RESERVE = 0x2000;
64 //flProtect
65 public const uint PAGE_READWRITE = 0x04;
66 public const uint PAGE_READONLY = 0x02;
67 public const uint PAGE_NOACCESS = 0x01;
68
69 //This function closes an open object handle[MSDN]
70 [DllImport("kernel32.dll", SetLastError = true)]
71 public static extern bool CloseHandle(IntPtr hObject);
72
73 [DllImport("kernel32.dll", SetLastError = true)]
74 public static extern IntPtr CreateFile(
75 string lpFileName,
76 uint desiredAccess,
77 uint shareMode,
78 uint lpSecurityAttributes,
79 dwCreationDisposition creationDisposition,
80 uint flagsAndAttributes,
81 int hTemplateFile);
82
83 [DllImport("kernel32.dll", SetLastError = true)]
84 public static extern bool ReadFile(
85 IntPtr hFile, //Handle to the file to be read.
86 byte[] lpBuffer, //Pointer to the buffer that receives the data read from the file
87 int nNumberOfBytesToRead, //Number of bytes to be read from the file
88 ref int lpNumberOfBytesRead, //Pointer to the number of bytes read.
89 ref OVERLAPPED overlapped);
90
91 //Return: Nonzero indicates success. Zero indicates failure
92 [DllImport("kernel32.dll", SetLastError = true)]
93 public static extern bool WriteFile(
94 IntPtr hFile, //Handle to the file to be written to
95 byte[] lpBuffer, //Pointer to the buffer containing the data to write to the file
96 int nNumberOfBytesToWrite, //Number of bytes to write to the file
97 ref int lpNumberOfBytesWritten, //Pointer to the number of bytes written by this function call
98 ref OVERLAPPED overlapped);
99
100 //The GetDiskFreeSpace function retrieves information about the specified disk, including the amount of free space on the disk
101 [DllImport("kernel32.dll", SetLastError = true)]
102 public static extern bool GetDiskFreeSpace(
103 string lpRootPathName, //Pointer to a null-terminated string that specifies the root directory of the disk for which information is to be returned.
104 ref int lpSectorsPerCluster, //Pointer to a variable that receives the number of sectors per cluster
105 ref int lpBytesPerSector, //Pointer to a variable that receives the number of bytes per sector
106 ref int lpNumberOfFreeClusters, //Pointer to a variable for the total number of free clusters on the disk that are available to the user who is associated with the calling thread.
107 ref int lpTotalNumberOfClusters); //Pointer to a variable for the total number of clusters on the disk that are available
108
109 //Reserves or commits a region of pages in the virtual address space of the calling process
110 [DllImport("kernel32.dll", SetLastError = true)]
111 public static extern IntPtr VirtualAlloc(
112 IntPtr lpAddress,
113 uint dwSize,
114 uint flAllocationType,
115 uint flProtect);
116
117 [DllImport("kernel32.dll", SetLastError = true)]
118 public static extern bool VirtualFree(
119 IntPtr lpAddress,
120 uint dwSize,
121 uint dwFreeType);
122
123 [DllImport("kernel32.dll", SetLastError = true)]
124 public static extern uint GetTickCount();
125 }
126
127 class quickFileSys
128 {
129 //读取文件长度为 2M
130 public static readonly int length = 1024 * 1024 * 2;
131
132 //返回实际读取的字节数
133 public static int ReadFrom(string sourceFileName, byte[] sourceBytes, uint mode)
134 {
135 int count = 0;
136 OVERLAPPED overlap = new OVERLAPPED();
137
138 IntPtr fHandle = Win32Invoke.CreateFile(sourceFileName, Win32Invoke.GENERIC_READ, Win32Invoke.FILE_SHARE_READ, 0, dwCreationDisposition.OPEN_EXISTING, mode, 0);
139
140 Win32Invoke.ReadFile(fHandle, sourceBytes, length, ref count, ref overlap);
141
142 return count;
143 }
144
145 //返回实际写入的字节数
146 public static int WriteTo(string destiFileName, byte[] destiBytes, uint mode)
147 {
148 int count = 0;
149 OVERLAPPED overlap = new OVERLAPPED();
150
151 IntPtr fHandle = Win32Invoke.CreateFile(destiFileName, Win32Invoke.GENERIC_WRITE, Win32Invoke.FILE_NOSHARE, 0, dwCreationDisposition.CREATE_ALWAYS, mode, 0);
152
153 Win32Invoke.WriteFile(fHandle, destiBytes, length, ref count, ref overlap);
154
155 return count;
156 }
157
158 public static uint filter(string sourceFileName, string destiFileName, uint mode)
159 {
160 byte[] data = new byte[length];
161 uint dwStartTime = Win32Invoke.GetTickCount();
162 ReadFrom(sourceFileName, data, mode);
163 WriteTo(destiFileName, data, mode);
164 uint dwEndTime = Win32Invoke.GetTickCount();
165
166 return dwEndTime - dwStartTime;
167 }
168
169 public static void display(uint mode, string displayStr)
170 {
171 int loop = 10;
172 uint dwTimeElapsed = 0;
173 uint total_nobuffering = 0;
174 for (int i = 0; i < loop; i++)
175 {
176 dwTimeElapsed = filter("test.txt", string.Format(displayStr + "{0}.txt", i), mode);
177 total_nobuffering += dwTimeElapsed;
178 Console.WriteLine(string.Format(displayStr + "{0}: {1}ms", i, dwTimeElapsed));
179 }
180 Console.WriteLine(string.Format(displayStr + "[Total]: {0}ms", total_nobuffering));
181 Console.WriteLine(string.Format(displayStr + "[Average]: {0}ms", total_nobuffering / loop));
182 Console.WriteLine("**************************************************************************");
183 }
184
185 //public static void Main()
186 //{
187 // display(Win32Invoke.FILE_FLAG_NO_BUFFERING, "file_flag_no_buffering");
188 // display(Win32Invoke.FILE_FLAG_SEQUENTIAL_SCAN, "file_flag_sequential_scan");
189 // display(Win32Invoke.FILE_FLAG_OVERLAPPED, "file_flag_overlapped");
190 // Console.Read();
191 //}
192 }
193}
194
195