zoukankan      html  css  js  c++  java
  • Go之获取Windows下文件是否隐藏

    起初,做了个小程序,用来检测磁盘中所有的文件

    package main
    import(
      "fmt"
      "io/ioutil"
      "os"
    )
    var dirpath ="D:\"
    func main(){
      CheckDir(dirpath)
    }
    func CheckDir(dirpath string){
      dirs, err := ioutil.ReadDir(dirpath)
      if err !=nil{
        panic("目录输入有误!")
      }
      for _, dir := range dirs {
        if dir.IsDir(){
        if dir.Name()=="System Volume Information"{
          fmt.Println("检测目录:", dirpath+"\"+dir.Name(),"sys", dir.Sys())
          return
        }
        fmt.Println("检测目录:", dirpath+"\"+dir.Name(),"sys", dir.Sys())
          CheckDir(dirpath +"\"+ dir.Name())
        }else{
            fmt.Println("文件:", dirpath+"\"+dir.Name(),"大小:", dir.Size())
            if dir.Size()==0{
            fmt.Println("删除文件:", dirpath+"\"+dir.Name(), dir.Size())
           }
        }
      }
    }
    
     
    输出结果为:

    文件: D:\My DocumentsDownloadswcftestclient_exe.rar 大小: 110608

    检测目录: D:\SoftDown sys &{16 {2081520578 30419524} {1134116594 30422735} {1134116594 30422735} 0 0}

    文件: D:\SoftDownSublime Text Build 3012 Setup.exe 大小: 7051120

    检测目录: D:\SoftDownVice.2015.720p.WEB-DL.DD5.1.H.264-PLAYNOW sys &{16 {753370423 30421925} {753410426 30421925} {753420426 30421925} 0 0}

    文件: D:\SoftDownVice.2015.720p.WEB-DL.DD5.1.H.264-PLAYNOWVice.2015.720p.WEB-DL.DD5.1.H.264-PLAYNOW.mkv.tdl 大小: 3255167129

    文件: D:\SoftDownVice.2015.720p.WEB-DL.DD5.1.H.264-PLAYNOWf7a8aa8e2082c4ebe28f2c26cf16e4b08a27d5c1.torrent 大小: 31751

    文件: D:\SoftDownVice.2015.720p.WEB-DL.DD5.1.H.264-PLAYNOW.qud.cfg 大小: 556

    文件: D:\SoftDown[iPlaySoft.com]VS2013_RTM_ULT_CHS.iso 大小: 3077509120

    检测目录: D:\System Volume Information sys &{22 {1206047926 30310737} {1206983927 30310737} {1206983927 30310737} 0 0}

     

    panic: 目录输入有误!

     

    goroutine 1 [running]:

    main.CheckDir(0xc0820585c0, 0x1d)

    F:/goproj/GitTest.git/trunk/src/WebSite/main.go:22 +0xde

    main.CheckDir(0x4f3890, 0x3)

    F:/goproj/GitTest.git/trunk/src/WebSite/main.go:28 +0x46a

    main.main()

    F:/goproj/GitTest.git/trunk/src/WebSite/main.go:15 +0xfc

     

    这里会报一个异常

    D:\System Volume Information Microsoft的解答

    本文介绍如何访问 System Volume Information 文件夹。System Volume Information 文件夹是一个隐藏的系统文件夹,系统还原工具使用此文件夹来存储它的信息和还原点。计算机的每个分区上都有一个 System Volume Information 文件夹。为了进行故障排除,可能需要访问此文件夹。

     

    于是就要判断文件是否是隐藏文件,但是Golang api中并未直接给出这个IsHidden属性

    调式源码得知:

      os.Stat方法可以获取到一个FileInfo,于是写了如下代码

          fileinfo, _ := os.Stat(dirpath)

          sysifno := fileinfo.Sys()

          fmt.Println(sysifno)

      1. os.Stat
      2. os包中的func Lstat(name string) (fi FileInfo, err error)
      3. 通过fs,err:=&fileStat{name: basename(name)}这个初始化得到了一个FileInfo对象
              type fileStat struct{
                  name string
                  sys syscall.Win32FileAttributeData
                  // used to implement SameFile
                  sync.Mutex
                  path string
                  vol uint32
                  idxhi uint32
                  idxlo uint32
                }
              type Win32FileAttributeDatastruct{
                  FileAttributes uint32
                  CreationTimeFiletime
                  LastAccessTimeFiletime
                  LastWriteTimeFiletime
                  FileSizeHigh uint32
                  FileSizeLow uint32
                }
    • 然后调用syscall.GetFileAttributesEx(namep, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fs.sys))) 将第3步中的fs传入次方法中,调用kernel32.dll的GetFileAttributes方法获取了文件属性
    • kernel32.dll的GetFileAttributes方法返回值如下
      1. MSDN中,文件总共有15种属性,根据磁盘的分区格式不同,文件的属性也会不同。
      2. 现在针对GetFileAttributes函数的返回值做以下整理
      3. 返回字段
      4. 返回值
      5. 属性类型
      6. FILE_ATTRIBUTE_READONLY 1 只读
      7. FILE_ATTRIBUTE_HIDDEN 2     隐藏
      8. FILE_ATTRIBUTE_SYSTEM     4 系统
      9. FILE_ATTRIBUTE_DIRECTORY 16 目录
      10. FILE_ATTRIBUTE_ARCHIVE 32 存档
      11. FILE_ATTRIBUTE_DEVICE 64 保留
      12. FILE_ATTRIBUTE_NORMAL 128 正常
      13. FILE_ATTRIBUTE_TEMPORARY 256 临时
      14. FILE_ATTRIBUTE_SPARSE_FILE 512 稀疏文件
      15. FILE_ATTRIBUTE_REPARSE_POINT1024 超链接或快捷方式
      16. FILE_ATTRIBUTE_COMPRESSED 2048 压缩
      17. FILE_ATTRIBUTE_OFFLINE 4096 脱机
      18. FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 8192 索引
      19. FILE_ATTRIBUTE_ENCRYPTED 16384 加密
      20. FILE_ATTRIBUTE_VIRTUAL 65536 虚拟
      21. 橙色标记的属性为Windows系统中文件的公有属性,其中“只读”、“隐藏”、“系统”、“存档”为文件的四种基本属性。compressed,content_indexed,encrypted只存在于NTFS分区中。
      22. 文件去掉全部属性后(四种基本属性),将自动标记为normal。同时具有systemhidden属性的文件会在系统中彻底隐形,这也是病毒常用的伎俩。
      23. commpressedencrypted不能共存。默认情况下文件都有content_indexed属性

    这里就能够理解这里输出的

    FileAttributes = 22

    检测目录:D:\System Volume Information sys &{22 {1206047926 30310737} {1206983927 30310737} {1206983927 30310737} 0 0}

    22代表的是也就是

    1 0 0 0 0 16 目录

    1 0 0 4 系统

    & 1 0 2 隐藏

    ------------

    1 0 1 1 0 =22

    代表此文件是隐藏文件

    检测目录: D:\SoftDownVice.2015.720p.WEB-DL.DD5.1.H.264-PLAYNOW sys &{16 {753370423 30421925} {753410426 30421925} {753420426 30421925} 0 0}

            16 目录
    这样就很明确了:也就是说如果二进制中倒数第二位为1,代表是隐藏目录(文件
    如此就能进行判断了
    package main
    import(
        "fmt"
        "io/ioutil"
        "os"
        "reflect"
        "strconv"
    )
    var dirpath ="D:\"
    func main(){
        CheckDir(dirpath)
    }
    func CheckDir(dirpath string){
      dirs, err := ioutil.ReadDir(dirpath)
      if err !=nil{
          panic("目录输入有误!")
      }
      for _, dir := range dirs {
        if dir.IsDir(){
          if!CheckIsHidden(dir){
            fmt.Println("检测目录:", dirpath+"\"+dir.Name())
            CheckDir(dirpath +"\"+ dir.Name())
          }
        }else{
          fmt.Println("文件:", dirpath+"\"+dir.Name(),"大小:", dir.Size())
          if dir.Size()==0{
            fmt.Println("删除文件:", dirpath+"\"+dir.Name(), dir.Size())
          }
        }
      }
    }
    func CheckIsHidden(file os.FileInfo)bool{
    //"通过反射来获取Win32FileAttributeData的FileAttributes
        fa := reflect.ValueOf(file.Sys()).Elem().FieldByName("FileAttributes").Uint()
        bytefa :=[]byte(strconv.FormatUint(fa,2))
        if bytefa[len(bytefa)-2]=='1'{
          fmt.Println("隐藏目录:", file.Name())
          return true
        }
        return false
    }
     
    
  • 相关阅读:
    Spring MVC(1)Spring MVC的初始化和流程以及SSM的实现
    Spring(四)Spring与数据库编程
    MyBatis(4)-- 动态SQL
    MyBatis(3)-- Mapper映射器
    MyBatis(2)-- MyBatis配置mybatis-config.xml
    MyBatis(1)-- MyBatis介绍
    计算机网络(2)-- URL、HTTP、HTTPS、HTML
    计算机网络(1)- TCP
    Shell脚本编程
    和为定值的多个数
  • 原文地址:https://www.cnblogs.com/anbylau2130/p/4262118.html
Copyright © 2011-2022 走看看