ফাইল সিস্টেম স্ক্যানিং কিভাবে করবেন


104
  1. আমাকে একটি ফাংশন লিখতে হবে যা যখন কোনও ফোল্ডারের পাথ দেওয়া হয় তখন সেই ফোল্ডারে থাকা ফাইলগুলিকে স্ক্যান করে।
  2. এবং তারপরে আমাকে সেই ফোল্ডারে ডিরেক্টরি কাঠামো প্রদর্শন করতে হবে।

আমি কীভাবে 2 টি জানি (এটি ব্রাউজারে প্রদর্শন করার জন্য আমি jstree ব্যবহার করতে যাচ্ছি)।


2
ডিরেক্টরি গাছটি পুনরাবৃত্তভাবে যেতে আপনার কী দরকার?
newacct

উত্তর:


194

সম্পাদনা করুন : এখনও যথেষ্ট লোকেরা এই উত্তরটিকে আঘাত করে, আমি ভেবেছিলাম যে আমি এটি Go1 API এর জন্য আপডেট করব। এটি ফাইলপথের একটি কার্যকরী উদাহরণ working ওয়ালক () । মূলটি নীচে রয়েছে।

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)
}

অনুগ্রহ করে নোট করুন যে ফাইলপথ। ওয়াক ডিরেক্টরি ট্রিটিকে পুনরাবৃত্তভাবে হাঁটাচ্ছে।

এটি একটি উদাহরণ চালানো:

$ 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>

মূল উত্তরটি অনুসরণ করুন: ফাইল পাথের হাঁটার জন্য ইন্টারফেসটি সাপ্তাহিক ২০১১-০৯-১-16 হিসাবে পরিবর্তিত হয়েছে, দেখুন http://groups.google.com/group/golang-nuts/msg/e304dd9cf196a218 । নীচের কোডটি অদূর ভবিষ্যতে জিওর প্রকাশ সংস্করণগুলির জন্য কাজ করবে না।

কেবলমাত্র এর জন্য স্ট্যান্ডার্ড লিবে একটি ফাংশন রয়েছে: ফাইলপথ.ওয়াল্ক

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উপায় দ্বারা symlinks অনুসরণ করে না।
0xcaff

3
@ ফ্রেঞ্চসোপাসা 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")
        }
    }
}

@ পেটারসো: রিডডির (-1) এর অর্থ কী? রিডডিয়ার কেবল স্ট্রিং টাইপ গ্রহণ করে, এবং এপিআই ডকুমেন্টেশনের উপর ভিত্তি করে স্ট্রিংটি কেবল নুল, এবং অন্য কোনও সীমাবদ্ধতা হতে পারে না .. এবং কীভাবে আসে রেডডিরের "ফাই" এর রিটার্ন টাইপ কী? (এটি কোনও মানচিত্র?) ..
সতেয়াম

@ হাই: আমার সংশোধিত উত্তর দেখুন, এতে এখন এপিআই ডকুমেন্টেশন অন্তর্ভুক্ত রয়েছে। আপনি দেখতে পাচ্ছেন, Readdirপদ্ধতি পরামিতিটি nএকটি int। যদি n <= 0, ডিরেক্টরি থেকে Readdirসমস্ত FileInfoএকক টুকরোতে ফেরত দেয় ।
পিটারসো

@ রিকস্মিথ: প্যাকেজ দেখুন os func (FileMode) IsRegular
পিটারসো

1
পছন্দসই হতে হবে না তবে ত্রুটি পরীক্ষার আগে আপনার মুলতুবি বন্ধ হওয়া উচিত।
জানভেন

13

সমস্ত ফাইল এবং ডিরেক্টরি পুনরাবৃত্তভাবে লুপ করার জন্য এখানে একটি উদাহরণ is মনে রাখবেন যে আপনি যে পথটি সংযোজন করছেন সেটি ডিরেক্টরি কিনা তা জানতে চাইলে কেবল "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)args এবং আপনার সাথে কিছু করতে প্রয়োজন 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) ব্যবহার করে বেস নাম দ্বারা ফাইলগুলি বাছাই করা হয় । ডিপস লোক হিসাবে, আমি সাধারণত বিপরীত সংখ্যার তুলনা করে দির নামগুলি বাছাই করি (উদাহরণস্বরূপ সর্বশেষতম বিল্ড)। যদি এটিও আপনার ক্ষেত্রে হয় তবে ওএস.ডাডডিরকে সরাসরি কল করা ভাল ( 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
           }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.