当前位置: 首页 > 编程日记 > 正文

C#使用WIN32API来高效率的遍历文件和目录(转)

我们有时需要遍历某个目录下的文件和子目录,可以使用System.IO.DirectoryInfo.GetDirectories或 GetFiles来获得目录下的所有的文件和子目录,当这个目录下的内容比较多时,这个操作就比较耗时间,有时我们仅仅需要知道某个目录下是否有子目录, 这样的操作显然是浪费时间的。此时我们很容易想到三个Win32API函数 FindFirstFile,FindNextFile和FindClose。这三个API搭配使用就能遍历文件和子目录了,而且可以遍历的时候随时中 止,避免无谓的操作。

C#中可以使用foreach来遍历某个序列,遍历使用的对象必须实现 System.Collections.IEnumeable接口,而内部调用的遍历器则必须实现 System.Collections.IEnumerator , 为了使用方便,我们在使用FindFirstFile等API函数时封装为 IEnumerator,而且实际上是有条件封装的。

这里很多人就会提到C#调用API的执行效率问题,认为应当用C,C++调用API才是正道,使用C#调用则有些鸡肋。但在我个人编程经历中,也有 不少调用API的,经验发现其实效率问题不大,可以省略。我只是做常规的运行在PC机上面的软件,CPU通常超过1GHZ,而且无需考虑高实时性和高效 率。若过于考虑效率问题会加大软件开发消耗。从工程开发管理方面看是不合理的。我应当解决比较突出的效率问题,不突出的影响不大的效率问题有时间才去解 决。使用C#封装Win32API必然会降低执行效率,但是封装后使用方便快捷,综合考虑认为这是正确的。

这里说一下“技术镀金”这个问题,所谓技术镀金就是开发人员在项目软件开发中过于追求技术的完美性,试图在技术上镀上一层完美的金壳,导致软件开发 工作量加大,项目时间拉长,有可能导致项目的失败。我吃过“技术镀金”的苦头,现在我内心是追求完美的,但实际开发时经常有意压制追求完美的心思。

现在继续探讨封装大计,本次封装重点在于实现IEnumerator,而IEnumeable只是IEnumerator的一个包装。 IEnumerator实现方法 Reset , MoveNext 和属性 Current,Reset方法用于重新设置遍历器,MoveNext用于查找下一个文件或目录,而Current返回当前文件或目录。

这个遍历器还得注意FindClose的调用,必须在遍历完毕没有找到文件或子目录后调用,若不调用该API函数则会造成内存泄漏。

根据上述设计,我写出如下代码,这段代码功能单一,希望有人能用得上

/// <summary>
/// 文件或目录遍历器,本类型为 FileDirectoryEnumerator 的一个包装
/// </summary>
/// <remarks>
/// 
/// 编写 袁永福 ( http://www.xdesigner.cn )2006-12-8
/// 
/// 以下代码演示使用这个文件目录遍历器
/// 
/// FileDirectoryEnumerable e = new FileDirectoryEnumerable();
/// e.SearchPath = @"c:"";
/// e.ReturnStringType = true ;
/// e.SearchPattern = "*.exe";
/// e.SearchDirectory = false ;
/// e.SearchFile = true;
/// foreach (object name in e)
/// {
///     System.Console.WriteLine(name);
/// }
/// System.Console.ReadLine();
/// 
///</remarks>
public class FileDirectoryEnumerable : System.Collections.IEnumerable
{
    
private bool bolReturnStringType = true;
    
/// <summary>
    
/// 是否以字符串方式返回查询结果,若返回true则当前对象返回为字符串,
    
/// 否则返回 System.IO.FileInfo或System.IO.DirectoryInfo类型
    
/// </summary>
    public bool ReturnStringType
    {
        
get { return bolReturnStringType; }
        
set { bolReturnStringType = value; }
    }

    
private string strSearchPattern = "*";
    
/// <summary>
    
/// 文件或目录名的通配符
    
/// </summary>
    public string SearchPattern
    {
        
get { return strSearchPattern; }
        
set { strSearchPattern = value; }
    }
    
private string strSearchPath = null;
    
/// <summary>
    
/// 搜索路径,必须为绝对路径
    
/// </summary>
    public string SearchPath
    {
        
get { return strSearchPath; }
        
set { strSearchPath = value; }
    }

    
private bool bolSearchForFile = true;
    
/// <summary>
    
/// 是否查找文件
    
/// </summary>
    public bool SearchForFile
    {
        
get { return bolSearchForFile; }
        
set { bolSearchForFile = value; }
    }
    
private bool bolSearchForDirectory = true;
    
/// <summary>
    
/// 是否查找子目录
    
/// </summary>
    public bool SearchForDirectory
    {
        
get { return bolSearchForDirectory; }
        
set { bolSearchForDirectory = value; }
    }

    
private bool bolThrowIOException = true;
    
/// <summary>
    
/// 发生IO错误时是否抛出异常
    
/// </summary>
    public bool ThrowIOException
    {
        
get { return this.bolThrowIOException; }
        
set { this.bolThrowIOException = value; }
    }
    
/// <summary>
    
/// 返回内置的文件和目录遍历器
    
/// </summary>
    
/// <returns>遍历器对象</returns>
    public System.Collections.IEnumerator GetEnumerator()
    {
        FileDirectoryEnumerator e 
= new FileDirectoryEnumerator();
        e.ReturnStringType 
= this.bolReturnStringType;
        e.SearchForDirectory 
= this.bolSearchForDirectory;
        e.SearchForFile 
= this.bolSearchForFile;
        e.SearchPath 
= this.strSearchPath;
        e.SearchPattern 
= this.strSearchPattern;
        e.ThrowIOException 
= this.bolThrowIOException;
        myList.Add(e);
        
return e;
    }
    
/// <summary>
    
/// 关闭对象
    
/// </summary>
    public void Close()
    {
        
foreach (FileDirectoryEnumerator e in myList)
        {
            e.Close();
        }
        myList.Clear();
    }

    
private System.Collections.ArrayList myList = new System.Collections.ArrayList();

}
//public class FileDirectoryEnumerable : System.Collections.IEnumerable

/// <summary>
/// 文件和目录的遍历器
/// </summary>
/// <remarks>本对象为Win32API函数 FindFirstFile , FindNextFile 
/// 和 FindClose 的一个包装
/// 
/// 以下代码演示使用了 FileDirectoryEnumerator 
/// 
/// FileDirectoryEnumerator e = new FileDirectoryEnumerator();
/// e.SearchPath = @"c:"";
/// e.Reset();
/// e.ReturnStringType = true ;
/// while (e.MoveNext())
/// {
///     System.Console.WriteLine
///         ( e.LastAccessTime.ToString("yyyy-MM-dd HH:mm:ss")
///         + "   " + e.FileLength + "  "t" + e.Name );
/// }
/// e.Close();
/// System.Console.ReadLine();
/// 
/// 编写 袁永福 ( http://www.xdesigner.cn )2006-12-8</remarks>
public class FileDirectoryEnumerator : System.Collections.IEnumerator
{
    
    
#region 表示对象当前状态的数据和属性 **********************************

    
/// <summary>
    
/// 当前对象
    
/// </summary>
    private object objCurrentObject = null;

    
private bool bolIsEmpty = false;
    
/// <summary>
    
/// 该目录为空
    
/// </summary>
    public bool IsEmpty
    {
        
get { return bolIsEmpty; }
    }
    
private int intSearchedCount = 0;
    
/// <summary>
    
/// 已找到的对象的个数
    
/// </summary>
    public int SearchedCount
    {
        
get { return intSearchedCount; }
    }
    
private bool bolIsFile = true;
    
/// <summary>
    
/// 当前对象是否为文件,若为true则当前对象为文件,否则为目录
    
/// </summary>
    public bool IsFile
    {
        
get { return bolIsFile; }
    }
    
private int intLastErrorCode = 0;
    
/// <summary>
    
/// 最后一次操作的Win32错误代码
    
/// </summary>
    public int LastErrorCode
    {
        
get { return intLastErrorCode; }
    }
    
/// <summary>
    
/// 当前对象的名称
    
/// </summary>
    public string Name
    {
        
get
        {
            
if (this.objCurrentObject != null)
            {
                
if (objCurrentObject is string)
                    
return (string)this.objCurrentObject;
                
else
                    
return ((System.IO.FileSystemInfo)this.objCurrentObject).Name;
            }
            
return null;
        }
    }
    
/// <summary>
    
/// 当前对象属性
    
/// </summary>
    public System.IO.FileAttributes Attributes
    {
        
get { return (System.IO.FileAttributes)myData.dwFileAttributes; }
    }
    
/// <summary>
    
/// 当前对象创建时间
    
/// </summary>
    public System.DateTime CreationTime
    {
        
get
        {
            
long time = ToLong(myData.ftCreationTime_dwHighDateTime, myData.ftCreationTime_dwLowDateTime);
            System.DateTime dtm 
= System.DateTime.FromFileTimeUtc(time);
            
return dtm.ToLocalTime();
        }
    }
    
/// <summary>
    
/// 当前对象最后访问时间
    
/// </summary>
    public System.DateTime LastAccessTime
    {
        
get
        {
            
long time = ToLong(myData.ftLastAccessTime_dwHighDateTime, myData.ftLastAccessTime_dwLowDateTime);
            System.DateTime dtm 
= System.DateTime.FromFileTimeUtc(time);
            
return dtm.ToLocalTime();
        }
    }
    
/// <summary>
    
/// 当前对象最后保存时间
    
/// </summary>
    public System.DateTime LastWriteTime
    {
        
get
        {
            
long time = ToLong(myData.ftLastWriteTime_dwHighDateTime, myData.ftLastWriteTime_dwLowDateTime);
            System.DateTime dtm 
= System.DateTime.FromFileTimeUtc(time);
            
return dtm.ToLocalTime();
        }
    }
    
/// <summary>
    
/// 当前文件长度,若为当前对象为文件则返回文件长度,若当前对象为目录则返回0
    
/// </summary>
    public long FileLength
    {
        
get
        {
            
if (this.bolIsFile)
                
return ToLong(myData.nFileSizeHigh, myData.nFileSizeLow);
            
else
                
return 0;
        }
    }

    
#endregion

    
#region 控制对象特性的一些属性 ****************************************

    
private bool bolThrowIOException = true;
    
/// <summary>
    
/// 发生IO错误时是否抛出异常
    
/// </summary>
    public bool ThrowIOException
    {
        
get { return this.bolThrowIOException; }
        
set { this.bolThrowIOException = value; }
    }
    
private bool bolReturnStringType = true;
    
/// <summary>
    
/// 是否以字符串方式返回查询结果,若返回true则当前对象返回为字符串,
    
/// 否则返回 System.IO.FileInfo或System.IO.DirectoryInfo类型
    
/// </summary>
    public bool ReturnStringType
    {
        
get { return bolReturnStringType; }
        
set { bolReturnStringType = value; }
    }
    
    
private string strSearchPattern = "*";
    
/// <summary>
    
/// 要匹配的文件或目录名,支持通配符
    
/// </summary>
    public string SearchPattern
    {
        
get { return strSearchPattern; }
        
set { strSearchPattern = value; }
    }
    
private string strSearchPath = null;
    
/// <summary>
    
/// 搜索的父目录,必须为绝对路径,不得有通配符,该目录必须存在
    
/// </summary>
    public string SearchPath
    {
        
get { return strSearchPath; }
        
set { strSearchPath = value; }
    }

    
private bool bolSearchForFile = true;
    
/// <summary>
    
/// 是否查找文件
    
/// </summary>
    public bool SearchForFile
    {
        
get { return bolSearchForFile; }
        
set { bolSearchForFile = value; }
    }
    
private bool bolSearchForDirectory = true;
    
/// <summary>
    
/// 是否查找子目录
    
/// </summary>
    public bool SearchForDirectory
    {
        
get { return bolSearchForDirectory; }
        
set { bolSearchForDirectory = value; }
    }

    
#endregion

    
/// <summary>
    
/// 关闭对象,停止搜索
    
/// </summary>
    public void Close()
    {
        
this.CloseHandler();
    }

    
#region IEnumerator 成员 **********************************************

    
/// <summary>
    
/// 返回当前对象
    
/// </summary>
    public object Current
    {
        
get { return objCurrentObject ; }
    }
    
/// <summary>
    
/// 找到下一个文件或目录
    
/// </summary>
    
/// <returns>操作是否成功</returns>
    public bool MoveNext()
    {
        
bool success = false;
        
while (true)
        {
            
if (this.bolStartSearchFlag)
                success 
= this.SearchNext();
            
else
                success 
= this.StartSearch();
            
if (success)
            {
                
if (this.UpdateCurrentObject())
                    
return true;
            }
            
else
            {
                
this.objCurrentObject = null;
                
return false;
            }
        }
    }

    
/// <summary>
    
/// 重新设置对象
    
/// </summary>
    public void Reset()
    {
        
if (this.strSearchPath == null)
            
throw new System.ArgumentNullException("SearchPath can not null");
        
if (this.strSearchPattern == null || this.strSearchPattern.Length == 0)
            
this.strSearchPattern = "*";

        
this.intSearchedCount = 0;
        
this.objCurrentObject = null;
        
this.CloseHandler();
        
this.bolStartSearchFlag = false;
        
this.bolIsEmpty = false;
        
this.intLastErrorCode = 0;
    }

    
#endregion

    
#region 声明WIN32API函数以及结构 **************************************

    [Serializable,
    System.Runtime.InteropServices.StructLayout
        (System.Runtime.InteropServices.LayoutKind.Sequential,
        CharSet 
= System.Runtime.InteropServices.CharSet.Auto
        ),
    System.Runtime.InteropServices.BestFitMapping(
false)]
    
private struct WIN32_FIND_DATA
    {
        
public int dwFileAttributes;
        
public int ftCreationTime_dwLowDateTime;
        
public int ftCreationTime_dwHighDateTime;
        
public int ftLastAccessTime_dwLowDateTime;
        
public int ftLastAccessTime_dwHighDateTime;
        
public int ftLastWriteTime_dwLowDateTime;
        
public int ftLastWriteTime_dwHighDateTime;
        
public int nFileSizeHigh;
        
public int nFileSizeLow;
        
public int dwReserved0;
        
public int dwReserved1;
        [System.Runtime.InteropServices.MarshalAs
            (System.Runtime.InteropServices.UnmanagedType.ByValTStr,
            SizeConst 
= 260)]
        
public string cFileName;
        [System.Runtime.InteropServices.MarshalAs
            (System.Runtime.InteropServices.UnmanagedType.ByValTStr,
            SizeConst 
= 14)]
        
public string cAlternateFileName;
    }

    [System.Runtime.InteropServices.DllImport
        (
"kernel32.dll",
        CharSet 
= System.Runtime.InteropServices.CharSet.Auto,
        SetLastError 
= true)]
    
private static extern IntPtr FindFirstFile(string pFileName, ref WIN32_FIND_DATA pFindFileData);

    [System.Runtime.InteropServices.DllImport
        (
"kernel32.dll",
       CharSet 
= System.Runtime.InteropServices.CharSet.Auto,
        SetLastError 
= true)]
    
private static extern bool FindNextFile(IntPtr hndFindFile, ref WIN32_FIND_DATA lpFindFileData);

    [System.Runtime.InteropServices.DllImport(
"kernel32.dll", SetLastError = true)]
    
private static extern bool FindClose(IntPtr hndFindFile);

    
private static long ToLong( int height , int low)
    {
        
long v = ( uint ) height ;
        v 
= v << 0x20;
        v 
= v | ( ( uint )low );
        
return v;
    }

    
private static void WinIOError(int errorCode, string str)
    {
        
switch (errorCode)
        {
            
case 80:
                
throw new System.IO.IOException("IO_FileExists :" + str);
            
case 0x57:
                
throw new System.IO.IOException("IOError:" + MakeHRFromErrorCode(errorCode));
            
case 0xce:
                
throw new System.IO.PathTooLongException("PathTooLong:" + str );
            
case 2:
                
throw new System.IO.FileNotFoundException("FileNotFound:" + str);
            
case 3:
                
throw new System.IO.DirectoryNotFoundException("PathNotFound:" + str);
            
case 5:
                
throw new UnauthorizedAccessException("UnauthorizedAccess:" + str);
            
case 0x20:
                
throw new System.IO.IOException("IO_SharingViolation:" + str);
        }
        
throw new System.IO.IOException("IOError:" + MakeHRFromErrorCode(errorCode));
    }

    
private static int MakeHRFromErrorCode(int errorCode)
    {
        
return (-2147024896 | errorCode);
    }

    
#endregion

    
#region 内部代码群 ****************************************************

    
private static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
    
/// <summary>
    
/// 查找处理的底层句柄
    
/// </summary>
    private System.IntPtr intSearchHandler = INVALID_HANDLE_VALUE;

    
private WIN32_FIND_DATA myData = new WIN32_FIND_DATA();
    
/// <summary>
    
/// 开始搜索标志
    
/// </summary>
    private bool bolStartSearchFlag = false;
    
/// <summary>
    
/// 关闭内部句柄
    
/// </summary>
    private void CloseHandler()
    {
        
if (this.intSearchHandler != INVALID_HANDLE_VALUE)
        {
            FindClose(
this.intSearchHandler);
            
this.intSearchHandler = INVALID_HANDLE_VALUE;
        }
    }
    
/// <summary>
    
/// 开始搜索
    
/// </summary>
    
/// <returns>操作是否成功</returns>
    private bool StartSearch()
    {
        bolStartSearchFlag 
= true;
        bolIsEmpty 
= false;
        objCurrentObject 
= null;
        intLastErrorCode 
= 0;

        
string strPath = System.IO.Path.Combine(strSearchPath, this.strSearchPattern);
        
this.CloseHandler();
        intSearchHandler 
= FindFirstFile(strPath, ref myData);
        
if (intSearchHandler == INVALID_HANDLE_VALUE)
        {
            intLastErrorCode 
= System.Runtime.InteropServices.Marshal.GetLastWin32Error();
            
if (intLastErrorCode == 2)
            {
                bolIsEmpty 
= true;
                
return false;
            }
            
ifthis.bolThrowIOException )
                WinIOError( intLastErrorCode , strSearchPath);
            
else
                
return false;
        }
        
return true;
    }
    
/// <summary>
    
/// 搜索下一个
    
/// </summary>
    
/// <returns>操作是否成功</returns>
    private bool SearchNext()
    {
        
if (bolStartSearchFlag == false)
            
return false;
        
if (bolIsEmpty)
            
return false;
        
if (intSearchHandler == INVALID_HANDLE_VALUE)
            
return false;
        intLastErrorCode 
= 0 ;
        
if (FindNextFile(intSearchHandler, ref myData) == false)
        {
            intLastErrorCode 
= System.Runtime.InteropServices.Marshal.GetLastWin32Error();
            
this.CloseHandler();
            
if (intLastErrorCode != 0 && intLastErrorCode != 0x12)
            {
                
if (this.bolThrowIOException)
                    WinIOError(intLastErrorCode , strSearchPath);
                
else
                    
return false;
            }
            
return false;
        }
        
return true;
    }
//private bool SearchNext()

    
/// <summary>
    
/// 更新当前对象
    
/// </summary>
    
/// <returns>操作是否成功</returns>
    private bool UpdateCurrentObject()
    {
        
if (intSearchHandler == INVALID_HANDLE_VALUE)
            
return false;
        
bool Result = false;
        
this.objCurrentObject = null;
        
if ((myData.dwFileAttributes & 0x10== 0)
        {
            
// 当前对象为文件
            this.bolIsFile = true;
            
if (this.bolSearchForFile)
                Result 
= true;
        }
        
else 
        {
            
// 当前对象为目录
            this.bolIsFile = false;
            
if (this.bolSearchForDirectory)
            {
                
if (myData.cFileName == "." || myData.cFileName == "..")
                    Result 
= false;
                
else
                    Result 
= true;
            }
        }
        
if (Result)
        {
            
if (this.bolReturnStringType)
                
this.objCurrentObject = myData.cFileName;
            
else
            {
                
string p = System.IO.Path.Combine(this.strSearchPath, myData.cFileName);
                
if (this.bolIsFile)
                {
                    
this.objCurrentObject = new System.IO.FileInfo(p);
                }
                
else
                {
                    
this.objCurrentObject = new System.IO.DirectoryInfo(p);
                }
            }
            
this.intSearchedCount++;
        }
        
return Result;
    }
//private bool UpdateCurrentObject()

    
#endregion

}
//public class FileDirectoryEnumerator : System.Collections.IEnumerator

转载于:https://www.cnblogs.com/alexusli/archive/2008/10/07/1305548.html

相关文章:

c语言1变A,c语言那些细节之a+1和a+1的区别

首先a是一个数组名&#xff0c;当看到这个a与&a时&#xff0c;一般我们的理解都是这个数组的首地址。没错&#xff0c;如果加上打印的话&#xff0c;确实两个值是一样的。不过&a是整个数组的首地址&#xff0c;a则是数组首元素的地址&#xff0c;虽然值一样&#xff0c…

【收藏清单】AI学习资料汇总——你想要的AI资源,这里都有

本文汇总了TinyMind站内AI资料类热门文章TOP10&#xff0c;欢迎大家各取所需。来源&#xff1a;https://www.tinymind.cn/ 1、【AI入门者必看】——人工智能技术人才成长路线图 入门AI的两大方式与进阶AI的十大路线&#xff0c;吐血之作&#xff0c;人手必备。路线图可在文末…

25,000,000行的代码就问你敢不敢动?!

你经历过绝望吗&#xff1f;近日&#xff0c;Hacker News 上发起了一个名为“你见过最糟糕的代码是什么&#xff1f;”&#xff08;https://news.ycombinator.com/item?id18442637&#xff09;的话题&#xff0c;引发了无数网友回忆讨论&#xff0c;甚至还再次让软件巨头 Orac…

c语言规定预处理命令必须以什么开头,C语言规定预处理命令必须以___________开头...

在定温定容下&#xff0c;语言规开反应NH4Cl (s) NH3 (g) HCl (g)达平衡&#xff0c;加入惰性气体平衡不移动05580041&#xff1a;定预若a、b均为int型变量,且a100,则for (b100;a!b;a,b) printf(----\n)是死循环。()处理05710012&#xff1a;以下正确的描述是( )。命令成年早期…

MySQL 微秒慢查询补丁

作/译者&#xff1a;叶金荣&#xff08;Email: &#xff09;&#xff0c;来源&#xff1a;http://imysql.cn&#xff0c;转载请注明作/译者和出处&#xff0c;并且不能用于商业用途&#xff0c;违者必究。原文出自&#xff1a;The new cool MySQL patch has landed! Check your…

Win10 15063 开始运行不保存历史记录原因和解决方法

在Win10 1703的时候你也许会发现开始运行以后&#xff0c;再次打开就没有任何历史记录了&#xff0c;常规方法是桌面-右键-个性化-开始-显示最常用的应用..可是打开是灰色的不可选.. 其实这个问题很好解决&#xff0c;在win10 15063隐私里面有一个设置的原因&#xff0c;请跟随…

CCNA培训课总结笔记--交换机的基本配置(十三)

实验目的:熟悉交换机的基本配置,学会在交换机上划分VLAN及如何将接口划分到指定的VLAN.本实验主要是用模拟器DynamipsGUI及3640的IOS文件做的实验,所以配置的命令有些会有出入.实验设备:3640交换机系列实验内容:其实交换机的基本操作包括设置特权登陆密码,设置控制台的密码等都…

TensorFlow 2.0发布在即,高级API变化抢先看

作者 | Sandeep Gupta, Josh Gordon, and Karmel Allison整理 | 非主流、Jane出品 | AI科技大本营【导语】早在今年 8 月的时候&#xff0c;谷歌开源战略师 Edd Wilder-James 在一封公开邮件中表示正在研发 TensorFlow 2.0&#xff0c;并将于今年晚些时候发布预览版。在 2018 年…

mp4 android自动播放,Android 使用VideoView播放MP4的简单实现

使用VideoView播放MP4播放示例实现简单的播放功能&#xff0c;播放手机本地的MP4文件。不依赖任何第三方框架&#xff0c;不添加任何防腐剂。添加一个系统自带的控制条。申请权限读取存储中的MP4文件准备布局文件在frag_video_view.xml中放置VideoView&#xff1b;为了让内容居…

Sublime-text theme 颜色主题

主题文件下载&#xff1a;Monokai.rar 替换办法&#xff1a; Preferences -> Browser packages -> Color Scheme - DefalutPreferences -> Browser packages -> Color Scheme - Defalut 覆盖 文件物理位置(win7)&#xff1a; C:\Users\用户名\AppData\Roaming\S…

android 自定义radiobutton 样式,RadioButton自定义点击时的背景颜色

一、应用场景&#xff1a;在使用 RadioButton 时&#xff0c;有时我们会需要自定义点击时改变背景颜色的效果。效果图&#xff1a;RadioButton自定义背景颜色.jpg二、实现步骤&#xff1a;1、新建一组 RadioButton &#xff1a;android:layout_width"match_parent"an…

如何让网页不受电信114劫持

每当出现输入网页错误时&#xff0c;电信总会把你劫持到他所在的网页下&#xff0c;如下&#xff1a;[url]http://game1.zj.vnet.cn/url1.php?MTwww.dsdsddsds.com[/url]看了这张老脸就觉得浑身不舒服。能不能想个办法不让他出现呢&#xff1f;嘿嘿&#xff0c;其实很简单&…

“男医生,女护士?”消除偏见,Google有大招

编译整理 | 若奇出品 | AI科技大本营如何消除 AI 带来的性别偏见是个令人头疼的问题&#xff0c;那究竟有没有方法去解决&#xff1f;12 月 6 日&#xff0c;Google 宣布他们迈出了减少 Google 翻译中性别偏见的第一步&#xff0c;并且还详细介绍了如何为 Google 翻译上的性别中…

Web Developer中文版下载

Web Developer是一款非常优秀的网页调试工具。Web Developer有IE和Firefox两个版本&#xff0c;主要功能表现在几个重要的方面&#xff1a;对页面中的文本、图像、媒体文件进行控制&#xff0c;对网页所应用的CSS文件的id与class辅助查看&#xff0c;表格辅助查看&#xff0c;可…

位置服务与地图应用

位置服务与地图应用: 位置服务&#xff08;Location Based Services,LBS&#xff09;又称为服务或基于位置的服务。Andorid平台支持提供位置服务的API&#xff0c;在开发过程中主要用到LocationManager 和LocationProviders对象。 为开发能够提供位置服务&#xff0c;首先需要得…

20分钟教你搞懂Git!

Git 是最流行的版本管理工具&#xff0c;也是程序员必备的技能之一。本文就来教你 20 分钟搞懂 Git&#xff01;以下为译文&#xff1a;尽管每天你都会用到Git&#xff0c;但也有可能搞不懂它的工作原理。为什么Git可以管理版本&#xff1f;基本命令git add和git commit到底在干…

android 长按赋值功能,android实现WebView中长按选中复制文本操作

啥都不说了&#xff0c;老司机直接移步GITHUB看源码吧&#xff1a;https://github.com/deaboway/AndroidWebViewTextSelect万一不work&#xff0c;一定不是代码的问题&#xff0c;你可以自查链接中的如下情况CSS控制页面文字不能被选中user-select:none;body{-moz-user-select:…

如何找回丢失的Vista系统“休眠”菜单

如何让Vista系统“休眠”菜单重见天日一些使用Windows Vista的朋友为了节省磁盘空间&#xff0c;在命令提示符下使用命令关闭休眠功能。但是如果再用相同的方法打开休眠功能时&#xff0c;就会发现&#xff0c;即使恢复了功能&#xff0c;“休眠”菜单还是看不见&#xff0c;这…

go3--常量和类型转换

/* Go中不存在隐式转换&#xff0c;所有类型转换必须显式声明 转换只能发生在两种相互兼容的类型之间 类型转换的格式&#xff1a;<ValueA> [:] <TypeOfValueA>(<ValueB>)全局变量可以使用var&#xff08;&#xff09;的形式&#xff0c;局部变量不可以使用v…

android倒计时实现方法,Android实现倒计时方法汇总

Android开发中经常会有倒计时的功能&#xff0c;下面将总结出常见的集中实现方式。1.直接使用Handler的消息机制来实现xml布局中文件如下&#xff1a;android:layout_width"match_parent"android:layout_height"match_parent"android:orientation"hor…

今晚8点直播 | 详讲NLP的经典应用实践——文本分类

文本分类问题是企业在 NLP 领域中处理文本数据时经常会遇到的一个问题&#xff0c;很多时候&#xff0c;我们需要将文本信息进行分类&#xff0c;或提相关的接口以供外部进行文本上传&#xff0c;在针对于用户所上传的文档信息就需要进行文档内容的分类&#xff0c;那么针对于这…

谈论 嵌入式系统

引用 嵌入式系统嵌入式系统http://www.lumit.org/index.htm嵌入式相关的网站http://www.mcu123.com/news/Article/web/uc/200611/3939.html转载于:https://www.cnblogs.com/stoneresearch/archive/2008/10/21/4336381.html

SharePoint Server 2013 之四:部署SharePoint企业版

在上篇文章我们完成了SharePointServer 2013 必备的组件&#xff0c;用户可根据自己需求联网安装或离线安装。接下来我们进入SharePoint 企业版的部署。 运行SharePointServer 2013 SP1 安装程序&#xff0c;点击“安装SharePoint Server”如下图&#xff1a; 企业版安装是需要…

android 监测内存泄漏工具,LeakCanary:Android内存泄漏检测工具

LeakCanaryA memory leak detection library for Android and Java.“A small leak will sink a great ship.” - Benjamin FranklinGetting startedIn your build.gradle:dependencies {debugImplementation com.squareup.leakcanary:leakcanary-android:1.6.1releaseImplemen…

为什么说可视化编程是糟糕的想法?

可视化编程语言可以让程序员通过操纵图形元素来创建程序&#xff0c;而无需键入文本命令。众所周知的例子是 Scratch&#xff0c;这是一种麻省理工学院开发的可视化编程语言&#xff0c;用来教孩子们学编程。该语言的优势在于新手和普通用户可以更容易接触编程。二十世纪九十年…

7年增长16倍,清华AI+ML课程学生数暴增 | AI Index 2018

整理 | 非主流出品 | AI科技大本营用数据解读 AI。昨日&#xff0c;来自斯坦福大学、MIT、哈佛、OpenAI 等高校与企业的多位专家正式发布了 2018 年度 AI Index 报告&#xff0c;用一系列数据全面回顾了过去几年里 AI 领域的全球发展。营长挑了一些重点内容&#xff0c;为大家解…

RunTime的使用-Category改变整个项目全部字体

在项目比较成熟的基础上&#xff0c;遇到了这样一个需求&#xff0c;应用中需要引入新的字体&#xff0c;需要更换所有Label的默认字体&#xff0c;但是同时&#xff0c;对于一些特殊设置了字体的label又不需要更换。乍看起来&#xff0c;这个问题确实十分棘手&#xff0c;首先…

android 耳机红外线,红外线耳机制作方法

本文介绍的语音红外转发器具有结构简单、易于制作、无干扰、低噪声的特点。工作原理&#xff1a;转发器由发射和接收两部分组成。见附图1。鉴频后的伴音(音频)信号经三极管V放大后推动红外发射管。由于发射管的发光强度与通过的电流成正比&#xff0c;所以D1、D2所发出的红外光…

解决load cycle count的一个偏方,告别硬盘卡卡响

load cycle count猛增&#xff0c;笔记本电脑硬盘喀嚓喀嚓响&#xff0c;我倒不担心硬盘寿命&#xff0c;但是实在烦人那声音&#xff0c;系统也时常被卡一下。我曾使用了hdparm -B 254 /dev/sda 的方法&#xff0c;但是硬盘升温太明显&#xff0c;右掌托烫得忍无可忍。苦寻方法…

AI工程的实践者:普元积极将场景落地,为企业提供智能化解决方案

作者 | Jane出品 | AI科技大本营11 月 8-9 日&#xff0c;CSDN 和 AICamp 联合举办的 AI 开发者大会在北京顺利举行。普元移动产品线总经理郝振明发表了《基于机器学习的工程实践》的主题演讲&#xff0c;并接受了 AI科技大本营的专访。以下内容为郝振明的演讲与采访总结&#…