Як отримати довжину файлу в Go?


80

Я шукав golang.org/pkg/os/#File , але досі не маю уявлення. Здається, немає можливості отримати довжину файлу, я щось пропустив?

Як отримати довжину файлу в Go?

Відповіді:


126

(*os.File).Stat()повертає os.FileInfoзначення, яке, у свою чергу, має Size()метод. Отже, якщо взяти файл f, код буде схожий на

fi, err := f.Stat()
if err != nil {
  // Could not obtain stat, handle error
}

fmt.Printf("The file is %d bytes long", fi.Size())

68

Якщо ви не хочете відкривати файл, os.Statзамість цього можна зателефонувати безпосередньо .

fi, err := os.Stat("/path/to/file")
if err != nil {
    return err
}
// get the size
size := fi.Size()

13

Трохи більш багатослівна відповідь:

file, err := os.Open( filepath ) 
if err != nil {
    log.Fatal(err)
}
fi, err := file.Stat()
if err != nil {
    log.Fatal(err)
}
fmt.Println( fi.Size() )

8
Може, а defer file.Close()до Stat()?
Timmmm

1
@Timmmm так - але оскільки це фрагмент коду, ми не можемо припустити, що fiio.Reader не передається в іншому місці, тому закриття може бути зухвалим.
colm.anseo

3

Виклик os.Stat, як сказав @shebaw (принаймні в ОС UNIX), є більш ефективним, причиною stat() is a Unix system call that returns file attributes about an inodeі немає необхідності мати справу з відкриттям файлу.

ПРИМІТКА . Використання іншого методу може призвести до роботи too many open files в багатопотоковому / паралельному додатку через те, що ви відкриваєте файл для запиту статистики

Ось еталон

func GetFileSize1(filepath string) (int64, error) {
    fi, err := os.Stat(filepath)
    if err != nil {
        return 0, err
    }
    // get the size
    return fi.Size(), nil
}

func GetFileSize2(filepath string) (int64, error) {
    f, err := os.Open(filepath)
    if err != nil {
        return 0, err
    }
    defer f.Close()
    fi, err := f.Stat()
    if err != nil {
        return 0, err
    }
    return fi.Size(), nil
}
BenchmarkGetFileSize1-8           704618              1662 ns/op
BenchmarkGetFileSize2-8           199461              5668 ns/op
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.