楠山烟酒 發表於 2020-8-5 15:52:00

GO语言获取文件的大小

<p>在项目中,我们可能会需要获取一个文件的大小,在Go语言中,有很多方法来获取一个文件的大小</p>
<h3 id="read字节方式">Read字节方式</h3>
<pre><code>func main() {
    file,err:=os.Open("water")
    if err ==nil {
      sum := 0
      buf:=make([]byte,2014)
      for{
            n,err:=file.Read(buf)
            sum+=n
            if err==io.EOF {
                break
            }
      }
      fmt.Println("file size is ",sum)
    }
}

</code></pre>
<p>这种方式需要打开文件,通过for循环读取文件的字节内容,然后算出文件的大小,这样时也是最不能用的办法,因为效率低,代码量大。</p>
<h3 id="ioutil方式">ioutil方式</h3>
<p>上面的代码比较啰嗦,这时候我们可能想到了使用ioutil包的ReadFile来代替,直接获得文件的内容,进而计算出文件的大小。</p>
<pre><code>func main() {
    content,err:=ioutil.ReadFile("water")
    if err == nil {
      fmt.Println("file size is ",len(content))
    }
}
</code></pre>
<p>通过ioutil.ReadFile函数,我们三行代码就可以搞定,的确方便很多,但是效率慢的问题依然,存在,如果是个很大的文件呢?</p>
<h3 id="stat方法">Stat方法</h3>
<p>继续再进一步,我们不读取文件的内容来计算了,我们通过文件的信息</p>
<pre><code>func main() {
    file,err:=os.Open("water")

    if err == nil {
      fi,_:=file.Stat()
      fmt.Println("file size is ",fi.Size())
    }
}
</code></pre>
<p>这种方式不会再读取文件的内容,而是通过Stat方法直接获取,速度会非常快,尤其对于大文件尤其有用。但是它还不是我们今天要讲的终极办法,因为它还是会打开文件,会占用它</p>
<h3 id="终极方案-osstat">终极方案 os.Stat()</h3>
<pre><code>func main() {
    fi,err:=os.Stat("water")
    if err ==nil {
      fmt.Println("file size is ",fi.Size(),err)
    }
}
</code></pre>
<p>是的,也只需要三行代码即可实现,这里使用的是os.Stat,通过他可以获得文件的元数据信息,现在我们看看它能获取到哪些信息。</p>
<h4 id="获取文件信息">获取文件信息</h4>
<p>通过os.Stat方法,我们可以获取文件的信息,比如文件大小、名字等。</p>
<pre><code>func main() {
    fi,err:=os.Stat("water")
    if err ==nil {
      fmt.Println("name:",fi.Name())
      fmt.Println("size:",fi.Size())
      fmt.Println("is dir:",fi.IsDir())
      fmt.Println("mode::",fi.Mode())
      fmt.Println("modTime:",fi.ModTime())
    }
}
</code></pre>
<p>运行这段代码看下结果:</p>
<pre><code>name: water
size: 403
is dir: false
mode:: -rw-r--r--
modTime: 2018-05-06 18:52:07 +0800 CST
</code></pre>
<p>以上就是可以获取到的文件信息,还包括判断是否是目录,权限模式和修改时间。所以我们对于文件的信息获取要使用os.Stat函数,它可以在不打开文件的情况下,高效获取文件信息。</p>
<h4 id="判断文件是否存在">判断文件是否存在</h4>
<p>os.Stat函数有两个返回值,一个是文件信息,一个是err,通过err我们可以判断文件是否存在。</p>
<p>首先,err==nil的时候,文件肯定是存在的;其次err!=nil的时候也不代表不存在,这时候我们就需要进行严密的判断。</p>
<pre><code>func main() {
    _,err:=os.Stat(".")
    if err ==nil {
      fmt.Println("file exist")
    }else if os.IsNotExist(err){
      fmt.Println("file not exist")
    }else{
      fmt.Println(err)
    }
}
</code></pre>
<p>通过os.IsNotExist来判断一个文件不存在。最后else的可能性比较少,这个时候可以看下具体的错误是什么,再根据错误来判断文件是否存在。os.Stat是一个非常好的函数,可以让我们非常高效的获取文件信息,所以在项目中尽可能的使用它。</p>
<h4 id="osstat方法用于获取文件属性示例如下">os.Stat()方法用于获取文件属性,示例如下</h4>
<pre><code>
import (
    "fmt"
    "os"
)

func main() {
        fileInfo, err := os.Stat(`C:\Users\Administrator\Desktop\应用商店.txt`)
        if err != nil {
                fmt.Println(err)
        }
        fmt.Println(fileInfo.Name())    //应用商店.txt
        fmt.Println(fileInfo.IsDir())   //false判断是否是目录
        fmt.Println(fileInfo.ModTime()) //2019-12-05 16:59:36.8832788 +0800 CST   文件的修改时间
        fmt.Println(fileInfo.Size())    //3097文件大小
    fmt.Println(fileInfo.Mode())    // -rw-rw-rw-读写属性
        fmt.Println(fileInfo.Sys())   //&amp;{32 {2160608986 30778972} {2160608986 30778972} {1375605524 30780234} 0 3097}
}
</code></pre>
<p>终端执行命令: go run demo.go e:\face.jpg</p>
<pre><code>name = face.jpg
size = 178154                  //Size()是按Byte字节进行计算大小.
mode = -rw-rw-rw-
modtime = 2019-02-20 21:02:58.0055166 +0800 CST
isDir = false
sys = &amp;{32 {1739327783 30722332} {2624535810 30722332} {2583200894 30722332} 0 178154}
</code></pre>
<h4 id="ps其fileinfo源码">PS其fileInfo源码</h4>
<pre><code>type FileInfo interface {
    Name() string       // 文件的名字(不含扩展名)
    Size() int64      // 普通文件返回值表示其大小;其他文件的返回值含义各系统不同
    Mode() FileMode   // 文件的模式位
    ModTime() time.Time // 文件的修改时间
    IsDir() bool      // 等价于Mode().IsDir()
    Sys() interface{}   // 底层数据来源(可以返回nil)
}
</code></pre><br><br>
来源:https://www.cnblogs.com/juice-e/p/13440418.html
頁: [1]
查看完整版本: GO语言获取文件的大小