फ़ाइल सिस्टम स्कैनिंग कैसे करें


104
  1. मुझे एक फ़ंक्शन लिखने की ज़रूरत है, जब किसी फ़ोल्डर का पथ उस फ़ोल्डर में निहित फ़ाइलों को स्कैन करता है।
  2. और फिर मुझे उस फ़ोल्डर में निर्देशिका संरचना प्रदर्शित करने की आवश्यकता है।

मुझे पता है कि 2 कैसे करना है (मैं इसे ब्राउज़र में प्रदर्शित करने के लिए jstree का उपयोग करने जा रहा हूं)।


2
क्या आपको निर्देशिका ट्री से पुनरावर्ती रूप से जाने की आवश्यकता है?
newacct

जवाबों:


194

संपादित करें : अभी भी बहुत से लोगों ने इस उत्तर को मारा है, मुझे लगा कि मैं इसे गो 1 एपीआई के लिए अपडेट करूंगा। यह filepath.Walk () का एक कार्यशील उदाहरण है । मूल नीचे है।

package main

import (
  "path/filepath"
  "os"
  "flag"
  "fmt"
)

func visit(path string, f os.FileInfo, err error) error {
  fmt.Printf("Visited: %s\n", path)
  return nil
} 


func main() {
  flag.Parse()
  root := flag.Arg(0)
  err := filepath.Walk(root, visit)
  fmt.Printf("filepath.Walk() returned %v\n", err)
}

कृपया ध्यान दें कि filepath.Walk निर्देशिका ट्री को पुनरावर्ती रूप से चलाता है।

यह एक उदाहरण रन है:

$ mkdir -p dir1/dir2
$ touch dir1/file1 dir1/dir2/file2
$ go run walk.go dir1
Visited: dir1
Visited: dir1/dir2
Visited: dir1/dir2/file2
Visited: dir1/file1
filepath.Walk() returned <nil>

मूल ANSWER FOLLOWS: पैदल चलने वाले फ़ाइल रास्तों के इंटरफ़ेस को साप्ताहिक 2015-09-09 के अनुसार बदल दिया गया है, http://groups.google.com/group/golang-nuts/msg/e304dd9cf19aa218 देखें । नीचे दिए गए कोड निकट भविष्य में GO के रिलीज़ संस्करणों के लिए काम नहीं करेंगे।

वहाँ वास्तव में सिर्फ इसके लिए मानक lib में एक समारोह है: filepath.Walk

package main

import (
    "path/filepath"
    "os"
    "flag"
)

type visitor int

// THIS CODE NO LONGER WORKS, PLEASE SEE ABOVE
func (v visitor) VisitDir(path string, f *os.FileInfo) bool {
    println(path)
    return true
} 

func (v visitor) VisitFile(path string, f *os.FileInfo) {
    println(path)
}

func main() {
    root := flag.Arg(0)
    filepath.Walk(root, visitor(0), nil)
}

1
filepath.Walkरास्ते से सिम्लिंक का पालन नहीं करता है।
0xcaff

3
@FrancescoPasa filepath.Walkकॉलबैक को सिमिलिंक (फ़ाइल और निर्देशिका दोनों) पर ट्रिगर किया जाएगा। हां, यह उनका अनुसरण नहीं करेगा , लेकिन कॉलबैक एक सिम्लिंक को पहचानता है और आगे की कार्रवाई करता है यानी एक अनुवर्ती filepath.Walkसुनिश्चित करता है कि पथ पहले से ही नहीं देखा गया है।
colm.anseo

15

यहां निर्देशिका में फ़ाइलों के लिए फ़ाइल जानकारी प्राप्त करने का एक तरीका है।

package main

import (
    "fmt"
    "os"
    "path/filepath"
)

func main() {
    dirname := "." + string(filepath.Separator)
    d, err := os.Open(dirname)
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
    defer d.Close()
    fi, err := d.Readdir(-1)
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
    for _, fi := range fi {
        if fi.Mode().IsRegular() {
            fmt.Println(fi.Name(), fi.Size(), "bytes")
        }
    }
}

@peterSO: रेड्डी (-1) का क्या अर्थ है? Readdir के रूप में केवल स्ट्रिंग प्रकार को स्वीकार करते हैं, और API प्रलेखन के आधार पर, एक स्ट्रिंग केवल NUL नहीं हो सकती है, और कोई अन्य सीमा नहीं है .. और Readdir में "फाई" का वापसी प्रकार क्या है, इसके माध्यम से कैसे चला जा सकता है (यह एक नक्शा है?) ..
सत्यम

@ हाइक: मेरा संशोधित उत्तर देखें, जिसमें अब एपीआई प्रलेखन शामिल है। जैसा कि आप देख सकते हैं, Readdirविधि पैरामीटर nएक है int। यदि n <= 0, एक ही स्लाइस में निर्देशिका से Readdirसभी रिटर्न FileInfo
पेट्रो

@ रिकस्मिथ: पैकेज देखें os func (FileMode) IsRegular
पीटरो

1
पिकी नहीं होना चाहिए, लेकिन त्रुटि जाँच से पहले आपका डिफर पास होना चाहिए।
ज़ानवेन

13

यहाँ सभी फ़ाइलों और निर्देशिकाओं के माध्यम से पुनरावृत्ति करने के लिए एक उदाहरण है। ध्यान दें कि यदि आप यह जानना चाहते हैं कि क्या आप जिस रास्ते पर चल रहे हैं वह एक निर्देशिका है तो बस "f.IsDir ()" की जाँच करें।

package main

import (
    "fmt"
    "os"
    "path/filepath"
)

func main() {
    searchDir := "c:/path/to/dir"

    fileList := []string{}
    err := filepath.Walk(searchDir, func(path string, f os.FileInfo, err error) error {
        fileList = append(fileList, path)
        return nil
    })

    for _, file := range fileList {
        fmt.Println(file)
    }
}

क्या आपने किसी फ़ंक्शन को कॉपी और पेस्ट किया है? mainविधि नहीं होना चाहिए ([]string, error)आर्ग और आप के साथ कुछ करने की ज़रूरत है err। जब तक जवाब देने के समय यह मान्य नहीं था? निश्चित रूप से अधिक हाल के संस्करणों में एक संकलन त्रुटि। अन्यथा, बहुत उपयोगी है, धन्यवाद।
स्टीव


4

ioutilउदाहरण के लिए नीचे दिए गए मामले को देखने के लिए गो स्टैंडर्ड पैकेज को फंक्शन में बनाया गया है

func searchFiles(dir string) { // dir is the parent directory you what to search
    files, err := ioutil.ReadDir(dir)
    if err != nil {
        log.Fatal(err)
    }

    for _, file := range files {
        fmt.Println(file.Name())
    }
}

1

ध्यान दें कि "वॉक प्रतीकात्मक लिंक का पालन नहीं करता है" इसलिए यदि आप एक फ़ंक्शन लिखना चाहते हैं जो ऐसा करता है कि मैं ioutil की सलाह देता हूंReadDir । मेरे स्वयं के बेंचमार्क परीक्षण से पता चला कि यह फ़ाइलपथ की तुलना में तेज़ और कम मेमोरी वाला है ।

इसके अतिरिक्त, ioutil.ReadDirबुनियादी स्ट्रिंग तुलना ( strA > strB) का उपयोग करके बेसनेम द्वारा फाइलों को छांटना है । एक देव पुरुष के रूप में, मैं आम तौर पर रिवर्स न्यूमेरिकल तुलना (उदाहरण के लिए नवीनतम निर्माण) करके दिर नामों को क्रमबद्ध करता हूं। अगर वह भी आपका मामला है, तो सीधे os.ReadDir पर कॉल करना बेहतर है ( ioutil.ReadDirयह कवर के तहत इसे कॉल कर रहा है) और अपने आप को सॉर्ट करना।

यहाँ ReadDirन्यूमेरिकल सॉर्ट वाले भाग का एक उदाहरण है :

// ReadDirNumSort - Same as ioutil/ReadDir but uses returns a Numerically
// Sorted file list.
//
// Taken from https://golang.org/src/io/ioutil/ioutil.go
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
// Modified Sort method to use Numerically sorted names instead.
// It also allows reverse sorting.
func ReadDirNumSort(dirname string, reverse bool) ([]os.FileInfo, error) {
    f, err := os.Open(dirname)
    if err != nil {
        return nil, err
    }
    list, err := f.Readdir(-1)
    f.Close()
    if err != nil {
        return nil, err
    }
    if reverse {
        sort.Sort(sort.Reverse(byName(list)))
    } else {
        sort.Sort(byName(list))
    }
    return list, nil
}

// byName implements sort.Interface.
type byName []os.FileInfo

func (f byName) Len() int      { return len(f) }
func (f byName) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
func (f byName) Less(i, j int) bool {
    nai, err := strconv.Atoi(f[i].Name())
    if err != nil {
        return f[i].Name() < f[j].Name()
    }
    naj, err := strconv.Atoi(f[j].Name())
    if err != nil {
        return f[i].Name() < f[j].Name()
    }
    return nai < naj
}

0

आप यहां फ़ंक्शन करी करना चाहते हैं, ताकि आप खोज का पूरी तरह से उपयोग कर सकें

func visit(files *[]string) filepath.WalkFunc {
    return func (path string, info os.FileInfo, err error) error {
               // maybe do this in some if block
               *files = append(*files, path)
               return nil
           }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.