C#文件安全管理解析
在实际的项目开发中,我们经常需要使用到文件的I/O操作,主要包含对文件的增改删查等操作,这些基本的操作我们都是很熟悉,但是较少的人去考虑文件的安全和操作的管理等方面,例如文件的访问权限管理,文件数据的彻底删除和数据的恢复等等,这一系列的操作需要我们对.NET的相关知识有一个深刻的学习。
在本文章主要介绍文件和目录的一些基本操作,以及文件目录的权限和安全设置的相关内容。
一.DotNet文件目录常用操作:
提到文件的I/O操作,这个对于每一个开发者来说都不是陌生的事,因为这些操作是我们在项目开发过程中经常使用到的一些操作。那么在.NET中操作文件的类在System.IO命名空间下,一下介绍一下常见的I/O操作类:
DiveInfo:提供了对逻辑磁盘的基本信息访问的途径。(只能查看信息,不能做任何修改。)
System.Environment:用来枚举驱动器。(不能获取驱动器的属性)
System.Management:.NET针对WMI调用。
Directory和DircetoryInfo:用于操作目录。(前者为静态类,后者则须在实例化后调用,功能上相同)
File和FileInfo:用于操作文件。(前者为静态类,后者须实例化后调用,功能上相同)
以上介绍了一些文件的基本操作类,本次主要讲解目录和文件操作,一下给出文件和目录操作的一些基本方法:
1.文件常规操作:
(1).文件读写操作:
/// <summary>/// 写文件/// </summary>/// <param name="fileName">文件名</param>/// <param name="content">文件内容</param>/// <param name="encoding">指定文件编码</param>protected void Write_Txt(string fileName, string content, string encoding){if (string.IsNullOrEmpty(fileName)){throw new ArgumentNullException(fileName);}if (string.IsNullOrEmpty(content)){throw new ArgumentNullException(content);}if (string.IsNullOrEmpty(encoding)){throw new ArgumentNullException(encoding);}var code = Encoding.GetEncoding(encoding);var htmlfilename = HttpContext.Current.Server.MapPath("Precious\\" + fileName + ".txt");var str = content;var sw = StreamWriter.Null;try{using (sw = new StreamWriter(htmlfilename, false, code)){sw.Write(str);sw.Flush();}}catch (IOException ioex){throw new IOException(ioex.Message);}catch (Exception ex){throw new Exception(ex.Message);}finally{sw.Close();}}/// <summary>/// 读文件/// </summary>/// <param name="filename">文件路径</param>/// <param name="encoding">文件编码</param>/// <returns></returns>protected string Read_Txt(string filename, string encoding){if (string.IsNullOrEmpty(filename)){throw new ArgumentNullException(filename);}if (string.IsNullOrEmpty(encoding)){throw new ArgumentNullException(encoding);}var code = Encoding.GetEncoding(encoding);var temp = HttpContext.Current.Server.MapPath("Precious\\" + filename + ".txt");var str = string.Empty;if (!System.IO.File.Exists(temp)) return str;var sr = StreamReader.Null;try{using (sr = new StreamReader(temp, code)){str = sr.ReadToEnd();}}catch (IOException ioex){throw new IOException(ioex.Message);}catch (Exception ex){throw new Exception(ex.Message);}finally{sr.Close();}return str;}
(2).文件附加操作:
/// <summary>/// 拷贝文件/// </summary>/// <param name="orignFile">原始文件</param>/// <param name="newFile">新文件路径</param>public static void FileCoppy(string orignFile, string newFile){if (string.IsNullOrEmpty(orignFile)){throw new ArgumentException(orignFile);}if (string.IsNullOrEmpty(newFile)){throw new ArgumentException(newFile);}System.IO.File.Copy(orignFile, newFile, true);}/// <summary>/// 删除文件/// </summary>/// <param name="path">路径</param>public static void FileDel(string path){if (string.IsNullOrEmpty(path)){throw new ArgumentException(path);}System.IO.File.Delete(path);}/// <summary>/// 移动文件/// </summary>/// <param name="orignFile">原始路径</param>/// <param name="newFile">新路径</param>public static void FileMove(string orignFile, string newFile){if (string.IsNullOrEmpty(orignFile)){throw new ArgumentException(orignFile);}if (string.IsNullOrEmpty(newFile)){throw new ArgumentException(newFile);}System.IO.File.Move(orignFile, newFile);}
2.目录常规操作:
/// <summary>/// 在当前目录下创建目录/// </summary>/// <param name="orignFolder">当前目录</param>/// <param name="newFloder">新目录</param>public static void FolderCreate(string orignFolder, string newFloder){if (string.IsNullOrEmpty(orignFolder)){throw new ArgumentException(orignFolder);}if (string.IsNullOrEmpty(newFloder)){throw new ArgumentException(newFloder);}Directory.SetCurrentDirectory(orignFolder);Directory.CreateDirectory(newFloder);}/// <summary>/// 创建文件夹/// </summary>/// <param name="path"></param>public static void FolderCreate(string path){if (string.IsNullOrEmpty(path)){throw new ArgumentException(path);}if (!Directory.Exists(path)){Directory.CreateDirectory(path);}}public static void FileCreate(string path){if (string.IsNullOrEmpty(path)){throw new ArgumentException(path);}var createFile = new FileInfo(path);if (createFile.Exists) return;var fs = createFile.Create();fs.Close();fs.Dispose();}/// <summary>/// 递归删除文件夹目录及文件/// </summary>/// <param name="dir"></param>/// <returns></returns>public static void DeleteFolder(string dir){if (string.IsNullOrEmpty(dir)){throw new ArgumentException(dir);}if (!Directory.Exists(dir)) return;foreach (var d in Directory.GetFileSystemEntries(dir)){if (System.IO.File.Exists(d)){//直接删除其中的文件System.IO.File.Delete(d);}else{//递归删除子文件夹DeleteFolder(d);}}//删除已空文件夹Directory.Delete(dir, true);}/// <summary>/// 指定文件夹下面的所有内容copy到目标文件夹下面/// </summary>/// <param name="srcPath">原始路径</param>/// <param name="aimPath">目标文件夹</param>public static void CopyDir(string srcPath, string aimPath){if (string.IsNullOrEmpty(srcPath)){throw new ArgumentNullException(srcPath);}if (string.IsNullOrEmpty(aimPath)){throw new ArgumentNullException(aimPath);}try{if (aimPath[aimPath.Length - ] != Path.DirectorySeparatorChar){aimPath += Path.DirectorySeparatorChar;}if (!Directory.Exists(aimPath)){Directory.CreateDirectory(aimPath);}var fileList = Directory.GetFileSystemEntries(srcPath);foreach (var file in fileList){if (Directory.Exists(file)){CopyDir(file, aimPath + Path.GetFileName(file));}else{System.IO.File.Copy(file, aimPath + Path.GetFileName(file), true);}}}catch (IOException ioex){throw new IOException(ioex.Message);}catch (Exception ee){throw new Exception(ee.ToString());}}/// <summary>/// 获取指定文件夹下所有子目录及文件/// </summary>/// <param name="path">详细路径</param>public static string GetFoldAll(string path){if (string.IsNullOrEmpty(path)){throw new ArgumentNullException(path);}var str =string.Empty;var thisOne = new DirectoryInfo(path);str = ListTreeShow(thisOne, , str);return str;}/// <summary>/// 获取指定文件夹下所有子目录及文件函数/// </summary>/// <param name="theDir">指定目录</param>/// <param name="nLevel">默认起始值,调用时,一般为0</param>/// <param name="rn">用于迭加的传入值,一般为空</param>/// <returns></returns>public static string ListTreeShow(DirectoryInfo theDir, int nLevel, string rn){if (theDir == null){throw new ArgumentNullException("theDir");}//获得目录DirectoryInfo[] subDirectories = theDir.GetDirectories();foreach (DirectoryInfo dirinfo in subDirectories){if (nLevel == ){rn += "├";}else{var s =string.Empty;for (int i = ; i <= nLevel; i++){s += "│ ";}rn += s + "├";}rn += "<b>" + dirinfo.Name + "</b><br />";//目录下的文件var fileInfo = dirinfo.GetFiles();foreach (FileInfo fInfo in fileInfo){if (nLevel == ){rn += "│ ├";}else{var f = string.Empty;for (int i = ; i <= nLevel; i++){f += "│ ";}rn += f + "│ ├";}rn += fInfo.Name.ToString() + " <br />";}rn = ListTreeShow(dirinfo, nLevel + , rn);}return rn;}/// <summary>/// 获取指定文件夹下所有子目录及文件(下拉框形)/// </summary>/// <param name="path">详细路径</param>///<param name="dropName">下拉列表名称</param>///<param name="tplPath">默认选择模板名称</param>public static string GetFoldAll(string path, string dropName, string tplPath){if (string.IsNullOrEmpty(path)){throw new ArgumentNullException(path);}if (string.IsNullOrEmpty(tplPath)){throw new ArgumentNullException(tplPath);}var strDrop = "<select name=\"" + dropName + "\" id=\"" + dropName + "\"><option value=\"\">--请选择详细模板--</option>";var str =string.Empty;DirectoryInfo thisOne = new DirectoryInfo(path);str = ListTreeShow(thisOne, , str, tplPath);return strDrop + str + "</select>";}/// <summary>/// 获取指定文件夹下所有子目录及文件函数/// </summary>/// <param name="theDir">指定目录</param>/// <param name="nLevel">默认起始值,调用时,一般为0</param>/// <param name="rn">用于迭加的传入值,一般为空</param>/// <param name="tplPath">默认选择模板名称</param>/// <returns></returns>public static string ListTreeShow(DirectoryInfo theDir, int nLevel, string rn, string tplPath){if (theDir == null){throw new ArgumentNullException("theDir");}//获得目录DirectoryInfo[] subDirectories = theDir.GetDirectories();foreach (DirectoryInfo dirinfo in subDirectories){rn += "<option value=\"" + dirinfo.Name + "\"";if (string.Equals(tplPath, dirinfo.Name, StringComparison.CurrentCultureIgnoreCase)){rn += " selected ";}rn += ">";if (nLevel == ){rn += "┣";}else{string s = string.Empty;for (int i = ; i <= nLevel; i++){s += "│ ";}rn += s + "┣";}rn += "" + dirinfo.Name + "</option>";//目录下的文件FileInfo[] fileInfo = dirinfo.GetFiles();foreach (FileInfo fInfo in fileInfo){rn += "<option value=\"" + dirinfo.Name + "/" + fInfo.Name + "\"";if (string.Equals(tplPath, fInfo.Name, StringComparison.CurrentCultureIgnoreCase)){rn += " selected ";}rn += ">";if (nLevel == ){rn += "│ ├";}else{string f = string.Empty;for (int i = ; i <= nLevel; i++){f += "│ ";}rn += f + "│ ├";}rn += fInfo.Name + "</option>";}rn = ListTreeShow(dirinfo, nLevel + , rn, tplPath);}return rn;}/// <summary>/// 获取文件夹大小/// </summary>/// <param name="dirPath">文件夹路径</param>/// <returns></returns>public static long GetDirectoryLength(string dirPath){if (string.IsNullOrEmpty(dirPath)){throw new ArgumentNullException(dirPath);}if (!Directory.Exists(dirPath)){return ;}long len = ;DirectoryInfo di = new DirectoryInfo(dirPath);foreach (FileInfo fi in di.GetFiles()){len += fi.Length;}DirectoryInfo[] dis = di.GetDirectories();if (dis.Length > ){for (int i = ; i < dis.Length; i++){len += GetDirectoryLength(dis[i].FullName);}}return len;}/// <summary>/// 获取指定文件详细属性/// </summary>/// <param name="filePath">文件详细路径</param>/// <returns></returns>public static string GetFileAttibe(string filePath){if (string.IsNullOrEmpty(filePath)){throw new ArgumentNullException(filePath);}var str = string.Empty;FileInfo objFi = new FileInfo(filePath);str += "详细路径:" + objFi.FullName + "<br>文件名称:" + objFi.Name + "<br>文件长度:" + objFi.Length + "字节<br>创建时间" + objFi.CreationTime.ToString() + "<br>最后访问时间:" + objFi.LastAccessTime.ToString() + "<br>修改时间:" + objFi.LastWriteTime.ToString() + "<br>所在目录:" + objFi.DirectoryName + "<br>扩展名:" + objFi.Extension;return str;}
二.DotNet文件目录访问管理:
1.文件目录权限概述:
提到权限这个概念,这对于每一个开发者都是再熟悉不过的,因为我们在开发项目时,都会考虑用户权限管理等等,但是文件的权限操作呢?这里我们就简单的介绍一下.NET中对文件访问权限的访问和设置。文件权限中的访问控制列表: 自由访问控制列表(DACL):Microsoft Windows NT和更高版本用于保护资源的机制;系统访问控制列表(SACL):一种控制与资源关联的审核消息的机制。System.Security.AccessControl命名空间通过一些类提供对访问控制列表的访问。DiectorySecurity:该类指定目录的访问控制和审核安全。指定系统目录的访问权限以及访问尝试的审核方式。FileSecurity:该类指定系统文件的访问权限以及如何审核访问尝试。
下面介绍一下文件权限操作的类和方法:
(1).FileStream类GetAccessControl():检索文件的安全对象:
[SecuritySafeCritical]
public FileSecurity GetAccessControl()
{if (this._handle.IsClosed){__Error.FileNotOpen();}return new FileSecurity(this._handle, this._fileName, AccessControlSections.Group | AccessControlSections.Owner | AccessControlSections.Access);
}
[SecurityCritical, SecurityPermission(SecurityAction.Assert, UnmanagedCode=true)]
internal FileSecurity(SafeFileHandle handle, string fullPath, AccessControlSections includeSections) : base(false, handle, includeSections, false)
{if (fullPath != null){new FileIOPermission(FileIOPermissionAccess.NoAccess, AccessControlActions.View, fullPath).Demand();}else{new FileIOPermission(PermissionState.Unrestricted).Demand();}
}
(2).FileStream类SetAccessControl():保存设置。
[SecuritySafeCritical]
public void SetAccessControl(FileSecurity fileSecurity)
{if (fileSecurity == null){throw new ArgumentNullException("fileSecurity");}if (this._handle.IsClosed){__Error.FileNotOpen();}fileSecurity.Persist(this._handle, this._fileName);
}
2.文件共享操作实例:
/// <summary>/// 共享文档操作/// </summary>public class FileSharingOperationHelper{public static bool ConnectState(string path){if (string.IsNullOrEmpty(path)){throw new ArgumentNullException(path);}return ConnectState(path, "", "");}/// <summary>/// 连接远程共享文件夹/// </summary>/// <param name="path">远程共享文件夹的路径</param>/// <param name="userName">用户名</param>/// <param name="passWord">密码</param>/// <returns></returns>public static bool ConnectState(string path, string userName, string passWord){var proc = new Process();try{proc.StartInfo.FileName = "cmd.exe";proc.StartInfo.UseShellExecute = false;proc.StartInfo.RedirectStandardInput = true;proc.StartInfo.RedirectStandardOutput = true;proc.StartInfo.RedirectStandardError = true;proc.StartInfo.CreateNoWindow = true;proc.Start();var dosLine = "net use " + path + " " + passWord + " /user:" + userName;proc.StandardInput.WriteLine(dosLine);proc.StandardInput.WriteLine("exit");while (!proc.HasExited){proc.WaitForExit();}var errormsg = proc.StandardError.ReadToEnd();proc.StandardError.Close();if (!string.IsNullOrEmpty(errormsg)){throw new Exception(errormsg);}}catch (Exception ex){throw new Exception(ex.Message);}finally{proc.Close();proc.Dispose();}return true;}/// <summary>/// 向远程文件夹保存本地内容,或者从远程文件夹下载文件到本地/// </summary>/// <param name="src">要保存的文件的路径,如果保存文件到共享文件夹,这个路径就是本地文件路径如:@"D:\1.avi"</param>/// <param name="dst">保存文件的路径,不含名称及扩展名</param>/// <param name="fileName">保存文件的名称以及扩展名</param>public static void Transport(string src, string dst, string fileName){if (string.IsNullOrEmpty(src)){throw new ArgumentNullException(src);}if (string.IsNullOrEmpty(dst)){throw new ArgumentNullException(dst);}if (string.IsNullOrEmpty(fileName)){throw new ArgumentNullException(fileName);}FileStream inFileStream = null;FileStream outFileStream = null;try{inFileStream = new FileStream(src, FileMode.Open);if (!Directory.Exists(dst)){Directory.CreateDirectory(dst);}dst = dst + fileName;outFileStream = new FileStream(dst, FileMode.OpenOrCreate);var buf = new byte[inFileStream.Length];int byteCount;while ((byteCount = inFileStream.Read(buf, , buf.Length)) > ){outFileStream.Write(buf, , byteCount);}}catch (IOException ioex){throw new IOException(ioex.Message);}catch (Exception ex){throw new Exception(ex.Message);}finally{if (inFileStream != null){inFileStream.Flush();inFileStream.Close();}if (outFileStream != null){outFileStream.Flush();outFileStream.Close();}}}}
文件权限的规则:容器的访问规则可能被配置为不仅应用于对象本身,而且还应用于它的子对象、子容器或这两者。每个访问规则不是显示的就是继承的。DACL可以有对象的所有者任意修改,还可以由所有者已经给予其梗概DACL权限的任何更改。对象的安全描述包含另一个规则列表,称为系统访问权限列表(SACL),该列表将控制系统对对象执行哪个类型的审核。审核是一种具有安全敏感性的操作。在windows中,审核只能由本地安全机构(LSA)生成,LSA是唯一允许向安全事件日志中写入的组件。
三.DotNet彻底删除文件操作:
1.文件彻底删除概述:
看到文件删除,可能有人会问,前面不是已经介绍过文件的删除操作吗?为什么这里还需要详细的介绍。不错,上面的确介绍了文件和目录的删除方法,但是这里是介绍如何彻底的删除文件。我们常规的删除文件和文件格式化,一般是可以被恢复的。我们在操作删除的时候,只是将文件的索引给删除了,并没有删除实际的内容。文件的索引记录了文件在磁盘中的位置信息,当执行删除操作时,只是从文件分配聊表中删除了目录。
那么可能会有人问,怎么讲文件彻底的删除呢?文件的粉碎,其实就是在删除文件分配列表的同时,把文件在磁盘上占用的所有扇区数据置为0。
在.NET中提供了两种文件彻底的方法:
(1).调用系统API来完成这样的“粉碎”操作。
(2).在删除文件之前先删除文件的所有内容,然后在执行删除操作,被称为“假粉碎”。(此方法可以被人恢复文件,但是恢复的数据只是文件中的0)
为了文件安全,可以采用多轮粉碎的方式:第一轮,通过文件操作Windows API,找到原始文件的铭文在存储器上所载区域,逐字符逐位进行完全填充,全部填充为0。第二轮,通过磁盘操作WindowsAPI找到原始文件或目录在FAT表中的位置,将原始文件或目录在FAT表中项清零。第三轮,通过磁盘操作WindowsAPI,找到原始文件或目录在备份FAT表的位置,将原始文件或目录在备份FAT表中的表项清零。
2.文件彻底删除实例:
/// <summary>/// 粉碎文件操作/// </summary>public class KillFileHelper{/// <summary>/// 强力粉碎文件,文件如果被打开,很难粉碎/// </summary>/// <param name="filename">文件全路径</param>/// <param name="deleteCount">删除次数</param>/// <param name="randomData">随机数据填充文件,默认true</param>/// <param name="blanks">空白填充文件,默认false</param>/// <returns>true:粉碎成功,false:粉碎失败</returns>public static bool KillFile(string filename, int deleteCount, bool randomData = true, bool blanks = false){if (string.IsNullOrEmpty(filename)){throw new ArgumentNullException(filename);}const int bufferLength = ;var ret = true;try{using (var stream = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)){var f = new FileInfo(filename);var count = f.Length;long offset = ;var rowDataBuffer = new byte[bufferLength];while (count >= ){var iNumOfDataRead = stream.Read(rowDataBuffer, , bufferLength);if (iNumOfDataRead == ){break;}if (randomData){var randombyte = new Random();randombyte.NextBytes(rowDataBuffer);}else if (blanks){for (var i = ; i < iNumOfDataRead; i++)rowDataBuffer[i] = ;}else{for (var i = ; i < iNumOfDataRead; i++)rowDataBuffer[i] = Convert.ToByte(Convert.ToChar(deleteCount));}// 写新内容到文件。for (var i = ; i < deleteCount; i++){stream.Seek(offset, SeekOrigin.Begin);stream.Write(rowDataBuffer, , iNumOfDataRead);}offset += iNumOfDataRead;count -= iNumOfDataRead;}}//每一个文件名字符代替随机数从0到9。var newName = "";do{var random = new Random();var cleanName = Path.GetFileName(filename);var dirName = Path.GetDirectoryName(filename);var iMoreRandomLetters = random.Next();// 为了更安全,不要只使用原文件名的大小,添加一些随机字母。for (var i = ; i < cleanName.Length + iMoreRandomLetters; i++){newName += random.Next().ToString();}newName = dirName + "\\" + newName;} while (File.Exists(newName));// 重命名文件的新的随机的名字。File.Move(filename, newName);File.Delete(newName);}catch{//可能其他原因删除失败了,使用我们自己的方法强制删除var matchPattern = @"(?<=\s+pid:\s+)\b(\d+)\b(?=\s+)";try{//要检查被那个进程占用的文件var fileName = filename;var tool = new Process { StartInfo = { FileName = "handle.exe", Arguments = fileName + " /accepteula", UseShellExecute = false, RedirectStandardOutput = true } };tool.Start();tool.WaitForExit();var outputTool = tool.StandardOutput.ReadToEnd();foreach (Match match in Regex.Matches(outputTool, matchPattern)){//结束掉所有正在使用这个文件的程序Process.GetProcessById(int.Parse(match.Value)).Kill();}File.Delete(fileName);}catch{ret = false;}}return ret;}}
四.DotNet文件加密解密操作:
上面介绍了文件的基本操作,文件权限操作,文件的删除操作,最后介绍一下文件的加密和解密操作。File和FileInfo类对文件加密进行了进一步的封装,提供了Encrypt和Decrypt方法用来对文件加密和解密。这两种方法要求文件系统必须为NFTS系统,对操作系统版本也要求必须是NT以上版本,使用该方法加密的文件,必须由同一用户才能进行解密。
具体看一下该方法的实现代码:
1.Encrypt():文件加密操作。
[SecuritySafeCritical]
public static void Encrypt(string path)
{if (path == null){throw new ArgumentNullException("path");}string fullPathInternal = Path.GetFullPathInternal(path);new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, new string[] { fullPathInternal }, false, false).Demand();if (!Win32Native.EncryptFile(fullPathInternal)){int errorCode = Marshal.GetLastWin32Error();if (errorCode == ){DriveInfo info = new DriveInfo(Path.GetPathRoot(fullPathInternal));if (!string.Equals("NTFS", info.DriveFormat)){throw new NotSupportedException(Environment.GetResourceString("NotSupported_EncryptionNeedsNTFS"));}}__Error.WinIOError(errorCode, fullPathInternal);}
}
2.Decrypt():文件解密操作。
[SecuritySafeCritical]
public static void Decrypt(string path)
{if (path == null){throw new ArgumentNullException("path");}string fullPathInternal = Path.GetFullPathInternal(path);new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, new string[] { fullPathInternal }, false, false).Demand();if (!Win32Native.DecryptFile(fullPathInternal, )){int errorCode = Marshal.GetLastWin32Error();if (errorCode == ){DriveInfo info = new DriveInfo(Path.GetPathRoot(fullPathInternal));if (!string.Equals("NTFS", info.DriveFormat)){throw new NotSupportedException(Environment.GetResourceString("NotSupported_EncryptionNeedsNTFS"));}}__Error.WinIOError(errorCode, fullPathInternal);}
}
五.总结:
以上简单的介绍了文件的操作和文件的权限管理方法,如果需要更加深入的了解这些操作方法,可以查看msdn,或者查看.NET的“垫片”,查看相应的接口。在当代社会中,数据安全和文件安全都是很重要的,我们应该更加深入的去学习安全知识,提高系统的稳定性。
相关文章:

C#文件安全管理解析
在实际的项目开发中,我们经常需要使用到文件的I/O操作,主要包含对文件的增改删查等操作,这些基本的操作我们都是很熟悉,但是较少的人去考虑文件的安全和操作的管理等方面,例如文件的访问权限管理,文件数据的…...

基于Dubbo分布式学校信息管理系统设计与实现
一、引言 1.1 课题背景 随着时代的发展与进步,计算机网络也随之日益完善,渐渐覆盖了我们生活的各个方面。在信息化和数字化的时代背景下,使用计算机管理学校信息来提升教育工作的质量和效率,是大势所趋,所以近年来,随着网络技术的不断发展,使用信息管理系统的学校越来…...

oracle面试问题和笔记整理
oracle面试笔记 ORACLE 面试问题-技术篇(2) 如何判断数据库的时区? 解答:SELECT DBTIMEZONE FROM DUAL; 解释GLOBAL_NAMES设为TRUE的用途 解答:GLOBAL_NAMES指明联接数据库的方式。如果这个参数设置为TRUE, 在建立数据库链接时就必须用相同的名字连结远程数据库 23。如何…...

Hadoop_Yarn实践 (三) => (Yarn的基础架构、原理、容量/公平调度器、Tool接口、Yarn常用命令、核心参数)
目录 Hadoop_HDFS、Hadoop_MapReduce、Hadoop_Yarn 实践 (三)一、Hadoop_HDFS二、Hadoop_MapReduce三、Hadoop_Yarn1、Yarn资源调度1.1、基础架构1.2、Yarn的工作调度机制(Job提交过程)1.3、Yarn 调度器和调度算法1.3.1、先进先出调度器(FIFO…...

postgresql 从应用角度看快照snapshot使用,事务隔离控制不再神密
专栏内容:postgresql内核源码分析 个人主页:我的主页 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物. 快照使用 快照是事务中使用,配合事务的隔离级别,体现出不同的可见性。…...

mysql(mariadb)读写分离部署
目录 一、原理 二、准备环境 三、部署mysql主从复制 1.五台服务器下载mariadb 2.修改master配置文件,重启数据库 3.登录mysql创建replication 4.从服务器登录验证 5.获得master服务器 DB的相关信息 6.备份master原有数据 7.修改slave1、slave2配置 8. 进入…...

ES-工作原理
前言 搜索引擎是对数据的检索,而数据总体分为两种:结构化数据和非结构化数据。而对于结构化数据,因为他们具有特定的结构,所以一般都是可以通过关系型数据库MySQL/oracle的二维表的方式存储和搜索,也可以建立索引。…...

C++小结(4)
C 字符串 C 提供了两种类型的字符串表示形式: C 风格字符串C 引入的 string 类类型 C 风格字符串 C 风格的字符串起源于 C 语言,并在 C 中继续得到支持。字符串实际上是使用 null 字符 \0 终止的一维字符数组。因此,一个以 null 结尾的字…...

Java框架之spring 的 messaging
写在前面 本文看下spring message相关的内容。 1:Message?Messaging? Message是消息的意思,是一个名词。而Messaging是一个动名词,是将消息发送出去的意思,因此,我们的消息系统是messaging s…...

linux使用grep命令查询nginx的进程情况时总是出现 grep --color=auto nginx
问题: 每次使用ps aux | grep 服务名 命令查询某个服务的进程时,总会出现一条grep --colorauto 服务名 例如: ps aux | grep nginx # 会出现图片中的情况解答: 这是因为grep 也是一条命令,它在输出时,会…...

FFmpeg音视频开发知识点(二)
系列文章目录 FFmpeg音视频开发知识点(一) 文章目录 系列文章目录前言一、AAC音频编码1. ffmpeg编译第三方的libfdk_aac2. S16重采样FLTP 二、AAC音频解码总结 前言 该篇讲解一下,音频编解码中的难点,以及开发过程中遇到问题&am…...

【Java可执行命令】(十)JAR文件签名工具 jarsigner:通过数字签名及验证保证代码信任与安全,深入解析 Java的 jarsigner命令~
Java可执行命令之jarsigner 1️⃣ 概念2️⃣ 优势和缺点3️⃣ 使用3.1 语法3.1.1 可选参数:jarsigner -keystore < url>3.1.2 可选参数:jarsigner -storepass <口令>3.1.3 可选参数:jarsigner -keypass <口令>3.1.4 可选参…...

c#调用c++ dll,Release版本内存访问错误
最近遇到个比较经典的案例,在c#中调用yara进行文件检测,yara是c编写的一个非常强大库,github有个大佬用c#对其进行了封装,使其能在跨平台下,只需编译yara的so或dll就能直接跑。但总是在Release版本下时不时就崩溃&…...

内网安全:Cobalt Strike 与 MSF 联动( 会话 相互转移 )
内网安全:Cobalt Strike 与 MSF 联动( 会话 相互转移 ) 在渗透中,有时候 Cobalt Strike 会话可能会受限制,所以我们需要把 Cobalt Strike 会话转移到 MSF 上进行后面的渗透。也有的时候会话在 MSF 上,但是…...

性能测试讲解超详细Jmeter
目录 什么是性能 性能测试的目的 功能测试和性能测试 基准测试 负载测试 稳定性测试 压力测试 并发测试 总结 性能测试指标 响应时间 并发数 吞吐量 点击数 错误率 资源使用率 总结 性能测试流程 性能测试需求分析 性能测试计划和方案 编辑性能测试用例编辑 性…...

微服务 – Spring Cloud – Nacos 配置中心
微服务 – Spring Cloud – Nacos 配置中心 文章目录 微服务 – Spring Cloud – Nacos 配置中心打开nacos面板新建配置引入依赖配置文件启动类业务类打开nacos面板新建配置 Data ID: nacos-config-client-dev.yaml Group: DEV-CLOUD2023 config:info: config info lalalal …...

超细,设计一个“完美“的测试用例,用户登录模块实例...
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 好的测试用例一定…...

【C#】文件拖拽,获取文件路径
系列文章 【C#】编号生成器(定义单号规则、固定字符、流水号、业务单号) 本文链接:https://blog.csdn.net/youcheng_ge/article/details/129129787 【C#】日期范围生成器(开始日期、结束日期) 本文链接:h…...

SAP PI/PO初步了解 2023.07.03
SAP PI/PO 是SAP 提供的一种集成中间件解决方案,用于在组织内部或不同组织之间实现系统的无缝通信和数据交换。它使企业能够以统一高效的方式集成各种应用和系统,无论这些系统的技术平台或数据格式如何。 以下是关于SAP PI/PO的简要概述: 1…...

Java中生产者消费者模型
在Java中,生产者消费者模型是一种常见的多线程编程模型,用于解决生产者和消费者之间的数据交互问题。 简介 生产者(Producer)负责生成数据,并将数据放入共享的缓冲区(队列)中。消费者…...

测试Hyperledger Fabric环境
首先进入fabric-samples目录中的first-networked 子目录 cd fabric-samples/first-network 在first-network目录下有一个自动化脚本byfn.sh,可以使用-help参数查看相应的可 用命令,在命令提示符中输入如下命令: ./byfn.sh --help命令执行成功后&#…...

ClickHouse查询sql长度超超过最大限制
ClickHouse查询sql长度超超过最大限制 Max query size exceeded ClickHouse exception, message: Code: 62. DB::Exception: Syntax error: failed at position 262102 (‘fwm00ud6a3ynu0kaxr.ya0eyemkbzdvrxkhwgchccll’) (line 10406, col 17): fwm00ud6a3ynu0kaxr.ya0eyemk…...

【Axure教程】拖动调整行高列宽的表格
表格是在系统软件中非常常用的工具。表格通常由行和列组成,用于以结构化的方式显示和组织数据。它们在各种场景中都有广泛的应用,包括数据分析、数据录入、报表生成、项目管理和数据可视化等领域。 今天作者就教大家如何在Axure里制作一个能通过鼠标拖动…...

中间件-netty(1)
netty 前言篇 文章目录 一、IO基础篇1.概念1.1 阻塞(Block)和非阻塞(Non-Block)1.2 同步(Synchronization)和异步(Asynchronous)1.3 BIO 与 NIO 对比1.3.1 面向流与面向缓冲1.3.2 阻塞与非阻塞1.3.3 选择器的问世 2.NIO 和 BIO 如何影响应用程序的设计2.1 API调用2.2 数据处理2…...

【方法】想把PDF文档转换成PPT,如何操作?
很多小伙伴在工作中,会使用PDF或者PPT来展示内容。那如果需要把PDF转换成PPT,要如何操作呢? 我们知道,PPT转换成PDF很容易操作,只需通过PPT的【导出】选项,就可以直接转换成PDF;还可以通过“另…...

Linux--设置目录或文件的默认权限:umask权限掩码
目录起始权限是从777,普通文件起始权限从666 为何我们创建一个目录或文件,默认权限是你所看到的样子? 因为凡是在umask中出现的权限,都不应该在最终权限中出现! 最终权限起始权限&(~umask)…...

C++实现websocket单server单client全双工通信(基于boost!!!)
自身环境:ubuntu18.04gcc7.5.0boost1.7,3 环境配置 gcc或者g一般都有,这里主要介绍一下boost的配置方法 执行如下代码: wget https://boostorg.jfrog.io/artifactory/main/release/1.73.0/source/boost_1_73_0.tar.bz2 --no-check-cert…...

好用的网址5
搜番神器:https://trace.moe/ Online converter:Online converter - convert video, images, audio and documents for free 格式转换 GIF Explode:https://gif-explode.com/ SongDonkey:SongDonkey - AI Online Audio Split…...

做项目去实习到底做的什么?
300万字!全网最全大数据学习面试社区等你来! 今天是手机编辑的文章,说说做项目/实习这回事。 我之前发过一些视频,讲校招四要素的,其中一个很重要的部分就是实习。 对社招同学来说,就简单了,面试…...

VSC++: 验证身份证
缘由https://ask.csdn.net/questions/1082358 void 验证身份证() {//缘由https://ask.csdn.net/questions/1082358int 权重[] { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 }, 个 0, j 0, a 0, he 0;char M[] "10X98765432", 身份号[100][20]{};//…...