C#高级编程笔记(22至25章节)文件\注册表\权限\事务
22安全(using System.Security.Principal;)
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);//当前线程用户
var principal = WindowsPrincipal.Current as WindowsPrincipal; //window组成员
var identity = principal.Identity as WindowsIdentity; //用户,可用属性.name
24文件与注册表操作
- FileSystemInfo 表示任何文件系统对象的基类。
- FileInfo和File表示文件系统上的文件
- DirectoryInfo和Directory表示文件系统上的文件夹。
- Path这个类包含的静态成员可以用于处理路径名。
- DriveInfo它的属性和方法提供了指定驱动器的信息。
- System.MarshalByRefObject .NET类中用于远程操作的基对象类,允许在应用程序域之间编组数据。
属性
属性名称 | 属性作用 |
CreationTime | 文件或文件夹创建时间 |
DirectoryName(仅用于文件类) | 包含文件夹的完整路径名 |
Parent(仅用于文件夹类) | 指定子目录的父目录 |
Exists | 文件或文件夹是否存在 |
Extension | 文件的扩展名,对于文件夹它返回空白 |
FullName | 文件或文件夹的完整路径名 |
LastAccessTime | 最后一次的访问文件或文件夹的时间 |
LastWriteTime | 最后一次修改文件或文件夹的时间 |
Name | 文件或文件夹的名称 |
Roct(仅用于文件夹类) | 路径的根部分 |
Length(仅用于文件类) | 返回文件的大小(以字节为单位) |
操作方法
操作名称 | 操作作用 |
Create() | 创建给定名称的文件夹或空文件,对于FilenInfo,该方法会返回一个流对象,经便写入文件. |
Delete() | 删除文件或文件夹,对于文件夹,有一个可以递归的Delete选项 |
MoveTo() | 移动和/或重命名文件或文件夹 |
CopyTo() | (只适用于FieInfo类)复制文件,注意文件夹没有复制方法.如果复制完整的目录树,需要单独复制每一个文件,创建对应于旧文件夹的新文件夹 |
GetDirectories() | (只适用于DirectoryInfo)返回DirectoryInfo对象数组,该数组表示文件夹中包含的所有文件夹 |
GetFiles() | (只适用于DirectoryInfo)返回FilesInfo对象数组,该数组表示文件夹中包含的所有文件. |
EnumerateFiles() | 返回文件名的IEnumerable<string>,在返回整个列表之前,可以对列表中的项执行操作 |
GetFileSystemInfos() | (只适用于DirectoryInfo)返回FilesInfo和DirectoryInfo对象,它把文件夹中包含的所有对象表示为一个FileSystemInfo引用数组 |
流数数的操作方法有Open()、OpenRead()、OpenText()、OpenWrite()、Create()、CreateText()等方法,它们都是返回流对象。
Path类
path.Combine()//合并
FileProperties示例
try
{
string folderPath = txtBoxInput.Text;
DirectoryInfo theFolder = new DirectoryInfo(folderPath);//得到 一个文件夹实例
if (theFolder.Exists)//检测存在
{
DisplayFolderList(theFolder.FullName);//执行方法
return;//返回
}
FileInfo theFile = new FileInfo(folderPath); //得到一个文件实例
if (theFile.Exists)//检测存在
{
DisplayFolderList(theFile.Directory.FullName);//执行方法
int index = listBoxFiles.Items.IndexOf(theFile.Name);//文件属性
listBoxFiles.SetSelected(index, true);
return;//返回
}
throw new FileNotFoundException("没有文件或文件夹 " + "this name: " + txtBoxInput.Text);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
读取文件
- File.ReadAllText(路径,Encoding.ASCII)//使用ASCII打开目标文件
- File.ReadAllBytes()//返回字节数组
- File.ReadAllLines()//逐行语取字符串返回数组
写入文件
- File.WriteAllText(路径,字符串);//把字符串写入路径文件
FileSteam文件流
FileStream test =new FileStream(path,fileMode,FileAccess,FileShare) //相关参数见下表(以下值可以使用'|'进行合并使用)
枚举 | 值 |
path路径名 | 字符串路径 |
FileMode文件打开模式 | Append追加,Create覆盖新建,CreateNew新建(存在则报错),Open打开(没有则报错),OpenOrCreate新建与打开(没有新建并打开)Truncate清除内容打开(慎用) |
FileAccess文件访问权限 | Read读取,ReadWrite读取写入,Write写入 |
FileShare文件共享方式 | None独占,Read允许别的程序读取,Write允许别的程序写入,ReadWrite允许别的程序读取与写入 |
- FileSteam.ReadByte();//读取一个字节,返回0-255的整数,如果到达流的末尾则返回-1
- FileSteam.Read(ByteArray,0,nBytes);//把流写入一个ByteArray的字节数组中,参数0为偏移量,nBytes为字节数(参考网络传输文件),返回值为0时表示到达了流的末尾.
- FileSteam.WritByte();//把一个字节写入流中,没有返回值
- FileSteam.Writ(ByteArray,0,nBytes);//把一个字节数组写入流中,参数0为数组元素索引,后面为字节数,没有返回值
FileStream对象表示在磁盘或网络路径上指向文件的流。这个类提供了在文件中读写字节的方法,但经常使用StreamReader或 StreamWriter执行这些功能。这是因为FileStream类操作的是字节和字节数组,而Stream类操作的是字符数据。这是这两种类的一个重要区别,如果你是准备读取byte数据的话,用StreamReader读取然后用 System.Text.Encoding.Default.GetBytes转化的话,如下,则可能出现数据丢失的情况,如byte数据的个数不对等。因此操作byte数据时要用FileStream.
StreamReader类用于读取文本文件
- StreamReader sr = new StreamReader(FileStream实例);//FileStream(@"d:\123.txt",filemode.open,fileAccess.read)
- StreamReader sr = FileInfo实例.OpenText();
StreamReader方法 | 作用 |
ReadLine() | 读取一行 |
ReadToEnd() | 读取剩于的内容 |
Read() | 读取一个字符 |
StreamWriter类用于写入文本文件
- StreamWriter sw = new StreamWriter(@"D:\123.txt",true,Encoding.ASCII);以ASCII写入
- StreamWriter sw = new StreamWriter(FileStream实例);
- StreamWriter sw = FileInfo实例.CreateText();
24映射内存的文件
主要用于减少I/O的操作,让CPU直接操作储存,操作请查阅网上资料
24.6读取驱动器信息
DriveInfo [] di = DriveInfo.GetDrives(); //获取计算机驱动器数组,可以使用Froeach
DriveInfo di1 = new DriveInfo(@"C:\");//获取C:\驱动器的实例
属性TotalSize总字节大小,TotalFreeSpace可用空间字节(为帐户磁盘配额),AvailableFreeSpace可用空间字节
24.7.1从文件中读取ACL(安全权限列表System.Security.AccessControl)
string myFilePath = @"D:\123.txt";
try
{
using (FileStream myFile = new FileStream(myFilePath, FileMode.Open, FileAccess.Read))
{
FileSecurity fileSec = myFile.GetAccessControl();
foreach (FileSystemAccessRule fileRule in fileSec.GetAccessRules(true, true, typeof(NTAccount)))
{
Console.WriteLine("{0} {1} {2} 通道出口 {3}", myFilePath, fileRule.AccessControlType == AccessControlType.Allow ? "提供" : "拒绝", fileRule.FileSystemRights, fileRule.IdentityReference);
}
}
}
catch
{
Console.WriteLine("不正确的文件路径 !");
}
/*
输出
D:\123.txt 拒绝 FullControl 通道出口 YJCN\qibobo
D:\123.txt 提供 Modify, Synchronize 通道出口 NT AUTHORITY\Authenticated Users
D:\123.txt 提供 FullControl 通道出口 NT AUTHORITY\SYSTEM
D:\123.txt 提供 FullControl 通道出口 BUILTIN\Administrators
D:\123.txt 提供 FullControl 通道出口 BUILTIN\Users
*/
24.7.1从目录中读取ACL
如上面示例相同,FileStream改为
DirectoryInfo myDir = new DirectoryInfo(mentionedDir);
if (myDir.Exists) {DirectorySecurity myDirSec = myDir.GetAccessControl();程序2};//这里可以用myDirSec.GetAccessControl()
24.7.2添加ACL信息(加权限)
try
{
using (FileStream myFile = new FileStream(@"d:\123.txt", FileMode.Open, FileAccess.ReadWrite))
{
FileSecurity filesec = myFile.GetAccessControl();//取得文件的权限列表
FileSystemAccessRule newRule = new FileSystemAccessRule(new System.Security.Principal.NTAccount(@"YJCN\liganwei"), FileSystemRights.FullControl, AccessControlType.Allow);//表示一条新的权限条目,其中YJCN\liganwei可以是域/帐户 或计算机名/帐户
filesec.AddAccessRule(newRule);//把上面的条目添加到列表中
File.SetAccessControl(@"d:\123.txt", filesec);//把权限列表应用到文件中
}
}
catch(ArgumentException ex)
{
Console.WriteLine(ex);
}
24.8注册表
HKCR文件打开方式、 HKCU用户配置、 HKLM软件信息 注:软件一般存储在HKLM\Software\<CompanyName>键中
数据类型:REG_SZ(字符串), REG_DWORD(int类型), REG_BINARY(字节数组)
RegistryKey hklm = Registry.LocalMachine;
RegistryKey hkSoftware = hklm.OpenSubKey("Software",true); //true表示写入权,无法写入注册表时,应该是注册表权限问题!把当前帐号加入权限
RegistryKey hkMine = hkSoftware.CreateSubKey("MyOwnSoftware");//在software目录下建立MyOwnSoftware目录
hkMine.SetValue("MyStringValue", "Hello World"); //在MyOwnSoftware目录建立REG_DWORD子项
hkMine.SetValue("MyIntValiue", ); //在MyOwnSoftware目录建立REG_DWORD子项
//hkMine.DeleteValue();删除键值 或DeleteSubKey()
24.9 写入独立存储器(System.IO.IsolatedStorage)
创建(主要学习XML的创建)
IsolatedStorageFile storFile = IsolatedStorageFile.GetUserStoreForDomain(); //创建独立存储文件实例
IsolatedStorageFileStream storStream = new IsolatedStorageFileStream("SelfPlacingWindow.Xml", FileMode.Create, FileAccess.Write);//创建独立存储文件流
System.Xml.XmlTextWriter writer = new System.Xml.XmlTextWriter(storStream, Encoding.UTF8); //创建XmlTextWriter对象,以构建XMl文档,
writer.Formatting = System.Xml.Formatting.Indented; //设置格式子元素缩进
writer.WriteStartDocument(); //写入版本号为1.0的XML声明
writer.WriteStartElement("Settings"); //开始标记
writer.WriteValue(); //值
writer.WriteEndElement(); //结束标记
writer.Flush();
writer.Close();
storStream.Close();
storFile.Close();
读取(主要学习XML的读取)
IsolatedStorageFile storFile1 = IsolatedStorageFile.GetUserStoreForDomain(); //创建独立存储文件实例
String[] userFiles = storFile1.GetFileNames("SelfPlacingWindow.Xml"); //获取匹配文件名的文件,如果没带参数,返回所有
foreach (string userFile in userFiles)
{
if(userFile == "SelfPlacingWindow.Xml") //找到相应文件
{
StreamReader storStream1 = new StreamReader(new IsolatedStorageFileStream("SelfPlacingWindow.Xml", FileMode.Open, storFile1)); //流读取文件
System.Xml.XmlTextReader reader = new System.Xml.XmlTextReader(storStream1); ////创建XmlTextReader对象,读取文档
while (reader.Read()) //读取下个节点
{
switch (reader.Name) //节点限定名
{
case "Settings":
Console.WriteLine(reader.ReadString());
break;
default:
break;
}
}
}
}
storFile1.Close();
userFiles.Clone();
25 事务
ACID属性
- A原子性
- C 一致性
- I 隔离性
- D 持久性
25.3 数据库和实体类
SqlConnection connection = new SqlConnection( Properties.Settings.Default.CourseManagementConnectionString);
SqlCommand courseCommand = connection.CreateCommand();
courseCommand.CommandText ="INSERT INTO Courses (Number, Title) VALUES (@Number, @Title)";
await connection.OpenAsync();
SqlTransaction tx = connection.BeginTransaction(); //事务开始
try
{
courseCommand.Transaction = tx; //加入事务
courseCommand.Parameters.AddWithValue("@Number", course.Number);
courseCommand.Parameters.AddWithValue("@Title", course.Title);
await courseCommand.ExecuteNonQueryAsync();
tx.Commit(); //提交事务
}
catch (Exception ex)
{
Trace.WriteLine("Error: " + ex.Message);
tx.Rollback(); //回滚事务
throw;
}
finally
{
connection.Close();
}
25.4传统事务
SQLConnection类 BeginTransaction()开始事务, Commit()提交事务 Rollback() 回滚事务
25.4.2 System.EnterpriseServices 优点是自动登陆事务,要派生基类(少用)
25.5 System.Transaction
25.5.1可提交的事务
相关代码查阅书本
SqlConnection connection = new SqlConnection(Properties.Settings.Default.CourseManagementConnectionString);
await connection.OpenAsync();
try
{
if (tx != null) connection.EnlistTransaction(tx); //检测事务是否有事务实例,把sql连接装入事务
....
wait command.ExecuteNonQueryAsync();
}
var tx = new CommittableTransaction();
try
{
await db.AddStudentAsync(s1, tx);
tx.Commit();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine();
tx.Rollback();
}
25.5.2 事务处理的升级
代码与上示例相同,
await db.AddStudentAsync(s1, tx);
await db.AddStudentAsync(s2, tx);//事务升级需要启动分布式事务协调器(DTC) 在windows服务里可以找到MS DTC
可以在设置超时时间!请查看书本
25.5.3依赖事务
static void DependentTransaction()
{
var tx = new CommittableTransaction(); //根事务
Utilities.DisplayTransactionInformation("TX创建根", tx.TransactionInformation);
try
{
Task.Factory.StartNew(TxTask, tx.DependentClone(DependentCloneOption.BlockCommitUntilComplete)); //创建依赖事务Transaction.DependentClone 方法返回一个依赖事务,阻塞父事务
if (Utilities.AbortTx()){throw new ApplicationException("transaction abort");}
tx.Commit(); //尝试提交事务
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
tx.Rollback(); //回滚事务
}
Utilities.DisplayTransactionInformation("TX 完成了",tx.TransactionInformation);
}
static void TxTask(object obj)
{
var tx = obj as DependentTransaction;
Utilities.DisplayTransactionInformation("相关事务",tx.TransactionInformation);
Thread.Sleep();
tx.Complete();//尝试完成依赖事务
Utilities.DisplayTransactionInformation("相关TX完成",tx.TransactionInformation);
}
25.5.4环境事务
事务完成时的事件设置调用OnTransactionCompleted方法,因为SQLConnection支持环境事务,并且会自动通过连接登记它
static async Task TransactionScopeAsync()
{
using (var scope = new TransactionScope())
{
Transaction.Current.TransactionCompleted += OnTransactionCompleted; //为环境事务的TransactionCompleted完成事件加入OnTransactionCompleted方法
Utilities.DisplayTransactionInformation("Ambient TX created", Transaction.Current.TransactionInformation);
var s1 = new Student { FirstName = "Angela",LastName = "Nagel",Company = "Kantine M101"};
var db = new StudentData();
await db.AddStudentAsync(s1);
if (!Utilities.AbortTx())
scope.Complete();//指示范围中的所有操作都已成功完成。
else
Console.WriteLine("transaction will be aborted");
}
// scope.Dispose();这里代表结束事务,如果没调用Complete()方法,就应该调Dispose()方法结束事务
}
static void OnTransactionCompleted(object sender, TransactionEventArgs e)
{
Utilities.DisplayTransactionInformation("TX completed",e.Transaction.TransactionInformation);
}
1嵌套的作用域和环境事务
TransactionScopeOption枚举的值:
- Required(需要的)嵌套的事务要提交后才生效
- Required(新的事务)二个独立的事务
- Suppress(取消事务)
2多线程与环境事务
try
{
using (var scope = new TransactionScope())
{
Transaction.Current.TransactionCompleted += TransactionCompleted; //完成时输出
Utilities.DisplayTransactionInformation("Main thread TX",Transaction.Current.TransactionInformation);
Task.Factory.StartNew(TaskMethod, Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete));//创建依赖事务,如果这里没有依赖事务选项,则因是不同的线程,所以是二个不同的事务
scope.Complete();
}
}
catch (TransactionAbortedException ex)
{
Console.WriteLine("Main—Transaction was aborted, {0}",ex.Message);
}
25.6隔离级别
隔离级别 | 脏读 | 不可重复读 | 幻读 |
ReadUncommitted (可读取修改可变数据) | Y | Y | Y |
ReadCommitted (可读取不可修改可变数据) | N | Y | Y |
RepeatableRead (可读取不可修改可变数据,可添加) | N | N | Y |
Serializable (可读取不可修改可变数据,不可添加) | N | N | N |
var options = new TransactionOptions
{
IsolationLevel = IsolationLevel.ReadUncommitted,Timeout = TimeSpan.FromSeconds() //设置事务可读可修改可变数据,超时设置为90毫秒
};
using (var test = new TransactionScope(TransactionScopeOption.Required, options))
{
}
25.7自定义资源管理器
此节涉及"浅拷贝"与"深拷贝"的相关知识 请先查看 相关的知识点
因理解问题,以下是Transactions的所有代码注释
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Transactions; namespace Wrox.ProCSharp.Transactions
{
public class Transactional<T>
{
private T liveValue; //实时值
private ResourceManager<T> enlistment; //临时值
private Transaction enlistedTransaction; //事务 public Transactional(T value)
{
if (Transaction.Current == null)
{
this.liveValue = value;
}
else
{
this.liveValue = default(T);
GetEnlistment().Value = value;
}
} public Transactional(): this(default(T)) { } /// <summary>
/// 检测是否在环境事务中,如果有
/// </summary>
/// <returns></returns>
private ResourceManager<T> GetEnlistment()
{
Transaction tx = Transaction.Current; //获取环境事务
Trace.Assert(tx != null, "必须用环境事务调用");//检查条件;如果条件为 false,则输出消息并显示一个消息框,后者用于显示调用堆栈。
if (enlistedTransaction == null)//如果没有登记事务
{
enlistment = new ResourceManager<T>(this, tx); //实例化内部类
tx.EnlistVolatile(enlistment, EnlistmentOptions.None); //登记事务
enlistedTransaction = tx;
return enlistment;
}
else if (enlistedTransaction == Transaction.Current) //查看是否是在同一线程中4
{
return enlistment; //返回资源管理器
}
else
{
throw new TransactionException("此类仅支持与一个事务一起使用的列表");
}
} public T Value
{
get { return GetValue(); }
set { SetValue(value); }
}
protected virtual T GetValue()
{
if (Transaction.Current == null)
{
return liveValue;
}
else
{
return GetEnlistment().Value;
}
} protected virtual void SetValue(T value)
{
if (Transaction.Current == null)
{
liveValue = value;
}
else
{
GetEnlistment().Value = value;
}
}
/// <summary>
/// 提交事务的方法
/// </summary>
/// <param name="value"></param>
/// <param name="tx"></param>
internal void Commit(T value, Transaction tx)
{
liveValue = value;
enlistedTransaction = null;
}
/// <summary>
/// 回滚事务的方法
/// </summary>
/// <param name="tx"></param>
internal void Rollback(Transaction tx)
{
enlistedTransaction = null;
}
internal class ResourceManager<T1> : IEnlistmentNotification //内部类,只有当前项目可以访问
{
private Transactional<T1> parent; //临时值()
public T1 Value { get; set; } //实时值
private Transaction currentTransaction;//事务 internal ResourceManager(Transactional<T1> parent, Transaction tx)
{
this.parent = parent;
Value = DeepCopy(parent.liveValue);//序列化"parent.liveValue"
currentTransaction = tx;//事务
} static ResourceManager()
{
Type t = typeof(T1);//获取类型类型
//Assert方法检查条件;如果条件为 false,则输出消息并显示一个消息框,后者用于显示调用堆栈。
Trace.Assert(t.IsSerializable, "Type " + t.Name + " 不可串行化");//Type.IsSerializable 属性如果可序列化则为 true;否则为 false。
}
/// <summary>
/// 序列化对象到流中
/// </summary>
/// <param name="value">对象</param>
/// <returns></returns>
private static T1 DeepCopy(T1 value)
{
using (var stream = new MemoryStream())
{
var formatter = new BinaryFormatter();//以二进制格式将对象或整个连接对象图形序列化和反序列化。
formatter.Serialize(stream, value);//序列化value到stream流中
stream.Flush();//当重写Flush方法时,将清除该流的所有缓冲区,并使得所有缓冲数据被写入到基础设备
stream.Seek(, SeekOrigin.Begin);//将当前流中的位置设置为指定值。
return (T1)formatter.Deserialize(stream);//返回 将流反序列化为对象图形。
}
}
public void Prepare(PreparingEnlistment preparingEnlistment)
{
preparingEnlistment.Prepared();
} public void Commit(Enlistment enlistment)
{
parent.Commit(Value, currentTransaction);
enlistment.Done();
} public void Rollback(Enlistment enlistment)
{
parent.Rollback(currentTransaction);
enlistment.Done();
} public void InDoubt(Enlistment enlistment)
{
enlistment.Done();
}
}
} }
Transactional类
ng System;
using System.Diagnostics.Contracts;
using System.Transactions; namespace Wrox.ProCSharp.Transactions
{
public static class Utilities
{
public static bool AbortTx()
{
Console.Write("中止事务 (y/n)?");
return Console.ReadLine().ToLower().Equals("y");
} public static void DisplayTransactionInformation(string title, TransactionInformation ti)
{
if (ti == null) { throw new Exception("事务不能为空"); }
Console.WriteLine(title);
Console.WriteLine("创建 Time: {0:T}", ti.CreationTime);
Console.WriteLine("状态: {0}", ti.Status);
Console.WriteLine("本地 ID: {0}", ti.LocalIdentifier);
Console.WriteLine("分布式 ID: {0}", ti.DistributedIdentifier);
Console.WriteLine();
}
} }
Utilities中断事务方法
以上是理解主要在于添加了接口与序列化的问题!请细心解读
25.8文件事务
因此节涉及COM的相关知识,这里不做解读!!直接拿着用吧!!在代码中加下面类
using System;
using System.Runtime.InteropServices; namespace Wrox.ProCSharp.Transactions
{
[ComImport]
[Guid("79427A2B-F895-40e0-BE79-B57DC82ED231")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IKernelTransaction
{
void GetHandle(out SafeTransactionHandle ktmHandle);
}
}
IKernelTransaction.cs
using System;
using System.Security;
using System.Security.Permissions;
using System.Security.AccessControl;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using Microsoft.Win32.SafeHandles; namespace Wrox.ProCSharp.Transactions
{
[SecurityCritical]
internal static class NativeMethods
{
[DllImport("Kernel32.dll", CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Unicode)]
internal static extern SafeFileHandle CreateFileTransacted(
String lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
IntPtr lpSecurityAttributes,
uint dwCreationDisposition,
int dwFlagsAndAttributes,
IntPtr hTemplateFile,
SafeTransactionHandle txHandle,
IntPtr miniVersion,
IntPtr extendedParameter); [DllImport("Kernel32.dll", SetLastError = true)]
[ResourceExposure(ResourceScope.Machine)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool CloseHandle(IntPtr handle); }
}
NativeMethods.cs
using System;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Microsoft.Win32.SafeHandles; namespace Wrox.ProCSharp.Transactions
{
[SecurityCritical]
internal sealed class SafeTransactionHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private SafeTransactionHandle(): base(true) { } //安全事务句柄
public SafeTransactionHandle(IntPtr preexistingHandle, bool ownsHandle): base(ownsHandle)
{
SetHandle(preexistingHandle);
}
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
protected override bool ReleaseHandle()
{
return NativeMethods.CloseHandle(handle);
}
} }
SafeTransactionHandle.cs
using System;
using System.IO;
using System.Security.Permissions;
using System.Transactions;
using Microsoft.Win32.SafeHandles; namespace Wrox.ProCSharp.Transactions
{
public static class TransactedFile
{
internal const short FILE_ATTRIBUTE_NORMAL = 0x80;
internal const short INVALID_HANDLE_VALUE = -;
internal const uint GENERIC_READ = 0x80000000;
internal const uint GENERIC_WRITE = 0x40000000;
internal const uint CREATE_NEW = ;
internal const uint CREATE_ALWAYS = ;
internal const uint OPEN_EXISTING = ; [FileIOPermission(SecurityAction.Demand, Unrestricted = true)]
public static FileStream GetTransactedFileStream(string fileName)
{
IKernelTransaction ktx = (IKernelTransaction)
TransactionInterop.GetDtcTransaction(Transaction.Current); SafeTransactionHandle txHandle;
ktx.GetHandle(out txHandle); SafeFileHandle fileHandle = NativeMethods.CreateFileTransacted(
fileName, GENERIC_WRITE, ,
IntPtr.Zero, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero,
txHandle, IntPtr.Zero, IntPtr.Zero); return new FileStream(fileHandle, FileAccess.Write);
}
}
}
TransactedFile.cs
调用方法如下:
using System;
using System.IO;
using System.Transactions;
namespace Wrox.ProCSharp.Transactions
{
class Program
{
static void Main()
{
WriteFileSample();
}
static async void WriteFileSample()
{
using (var scope = new TransactionScope())
{
FileStream stream = TransactedFile.GetTransactedFileStream("sample.txt");
var writer = new StreamWriter(stream);
await writer.WriteLineAsync("Write a transactional file");
writer.Close();
if (!Utilities.AbortTx())
scope.Complete();
}
}
}
}
C#高级编程笔记(22至25章节)文件\注册表\权限\事务的更多相关文章
- C#高级编程笔记 (6至10章节)运算符/委托/字符/正则/集合
数学的复习,4^-2即是1/4/4的意思, 4^2是1*2*2的意思,而10^-2为0.01! 7.2运算符 符号 说明 例 ++ 操作数加1 int i=3; j=i++; 运算后i的值为4,j ...
- C#高级编程笔记(17至21章节)线程/任务
17 Visual Studio 2013 控制台用Ctrl+F5可以显示窗口,不用加Console.ReadLine(); F5用于断点调式 程式应该使用发布,因为发布的程序在发布时会进行优化, 2 ...
- C#高级编程笔记 (1至6章节)数组,类/方法/泛型
2.3变量 var 类型推断 type 类的分类 如:type nametype = name.GetType(); //取变量name的类型 const 常量 const int painame ...
- Android高级编程笔记(四)深入探讨Activity(转)
在应用程序中至少包含一个用来处理应用程序的主UI功能的主界面屏幕.这个主界面一般由多个Fragment组成,并由一组次要Activity支持.要在屏幕之间切换,就必须要启动一个新的Activity.一 ...
- C#高级编程笔记之第二章:核心C#
变量的初始化和作用域 C#的预定义数据类型 流控制 枚举 名称空间 预处理命令 C#编程的推荐规则和约定 变量的初始化和作用域 初始化 C#有两个方法可以一确保变量在使用前进行了初始化: 变量是字段, ...
- UNIX环境高级编程笔记之文件I/O
一.总结 在写之前,先唠几句,<UNIX环境高级编程>,简称APUE,这本书简直是本神书,像我这种小白,基本上每看完一章都是“哇”这种很吃惊的表情.其实大概三年前,那会大三,我就买了这本书 ...
- javascript高级编程笔记01(基本概念)
1.在html中使用JavaScript 1. <script> 元素 <script>定义了下列6个属性: async:可选,异步下载外部脚本文件. charset:可选, ...
- C#高级编程笔记之第三章:对象和类型
类和结构的区别 类成员 匿名类型 结构 弱引用 部分类 Object类,其他类都从该类派生而来 扩展方法 3.2 类和结构 类与结构的区别是它们在内存中的存储方式.访问方式(类似存储在堆上的引用类型, ...
- C#高级编程笔记2016年10月12日 运算符重载
1.运算符重载:运算符重重载的关键是在对象上不能总是只调用方法或属性,有时还需要做一些其他工作,例如,对数值进行相加.相乘或逻辑操作等.例如,语句if(a==b).对于类,这个语句在默认状态下会比较引 ...
随机推荐
- [LOJ161] 仙人掌计数
Statement 带标号仙人掌计数问题. \(n< 131072\). Solution 设\(x\)个点的仙人掌个数的生成函数为\(C(x)\) 对于与根相邻的块, 还是仙人掌, 生成函数为 ...
- Yii 1.1 常规框架部署和配置
<?php //index.php //入口文件配置操作 // change the following paths if necessary $yii=dirname(__FILE__).'/ ...
- Java 封装 继承 多态
Java 继承 继承的概念 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类. 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法 ...
- 阿里云code下载代码和更新代码
1- 本地新建一个文件夹,进入文件夹下面右击打开git 2- Git init初始化一个.git文件夹 3- Git clone git@code.aliyun.com:username/space- ...
- JVisualVM 模拟一次内存泄漏场景分析
首先贴一段内存泄漏的代码并且执行.(内存泄漏:GC回收不掉的实例对象) package com.example.demo.memoryLeakDemo; import com.example.demo ...
- 批量执行SQL脚本
新建文件夹all_sql,并将需要执行的sql脚本放入其中. 新建bat脚本,执行即可,ORACLE 也可改Mysql,按需:如下 ::echo off :: @echo off echo 开始执行数 ...
- iframe的基础应用
点击top.html里面的按钮,刷新left.html右边的内容 <a href="left.html?id=11111&k=5&b=4" target=& ...
- Python笔记(十九)_继承
继承 继承可以把父类的所有功能都直接拿过来,这样就不必从零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写 多重继承 通过多重继承,一个子类就可以同时获得多个父类的所有功能 > ...
- 泛微e-cology OA Beanshell组件远程代码执行漏洞复现CNNVD-201909-1041
靶机 影响版本 泛微e-cology<=9.0 https://github.com/jas502n/e-cology 部署 复现 /weaver/bsh.servlet.BshServlet ...
- android button click事件
package a.a; import android.app.Activity;import android.os.Bundle;import android.view.View;import an ...