বর্তমানে চলমান ফাইলের ডিরেক্টরি কীভাবে পাবেন?


239

নোডেজে আমি __ ডিরেক্টরি ব্যবহার করি । গোলাঙে এর সমতুল্য কী?

আমি এই নিবন্ধটি googled এবং খুঁজে পেয়েছি http://andrewbrookins.com/tech/golang-get-directory-of-the-current-file/ । যেখানে তিনি নীচের কোড ব্যবহার করেন

_, filename, _, _ := runtime.Caller(1)
f, err := os.Open(path.Join(path.Dir(filename), "data.csv"))

তবে গোলাংয়ে কি সঠিক উপায়ে বা প্রতিমা হিসাবে কাজ করা যায়?


এটি আপনার প্রশ্নের কোনও উত্তর নয় তবে আপনি বিশ্বব্যাপী (আপনার ফাইলের অবস্থান চলমান চলাকালীন পরিবর্তন করা যায় না) যাওয়ার পথটি ক্যাশে করতে পারেন) আপনার কোডটি বারবার চালিত হয়ে ওএস.পেন চালানো না
oguzalb

আপনি পাস করা উচিত 0, না 1, যাও runtime.Caller()
ফায়াতজাফ

4
runtime.Caller(0)আপনার উত্স ফাইলটির পথ দেবে, যেমন $GOPATH/src/packagename/main.go। এই থ্রেডের অন্যান্য উত্তরগুলি এক্সিকিউটেবলের (যেমন $GOPATH/bin/packagename) পথ ফেরানোর চেষ্টা করছে ।
ফিয়াটজাফ

আপনি ধরে
নিচ্ছেন

উত্তর:


221

এটি করা উচিত:

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

func main() {
    dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
    if err != nil {
            log.Fatal(err)
    }
    fmt.Println(dir)
}

2
এখানে কি ত্রুটি হওয়া সম্ভব? যদি তাই হয় তবে কী ত্রুটি হবে, কৌতুহলের বাইরে?
জেফ এসকালান্ট

4
কাজ আমার জন্য না করে play.golang.org/p/c8fe-Zm_bH অগত্যা ABS পথ ধারণ করে না os.Args [0] -।
zupa

5
এটি কার্যত কার্যকর হয় এমনকি যদি OS.Args [0] এ অ্যাবস পাথ না থাকে। খেলার মাঠের ফলাফলটি আপনি যেটা প্রত্যাশা করেছিলেন তা নয় কারণ এটি একটি স্যান্ডবক্সের ভিতরে রয়েছে।
গুস্তাভো নেইমায়ার

37
এটি একটি নির্ভরযোগ্য উপায় নয় , osext ব্যবহার সম্পর্কে উত্তরটি দেখুন কারণ এটি বাস্তবায়ন যা বিভিন্ন ওএসে আমাদের সমস্ত ক্লায়েন্টের সাথে কাজ করেছিল। আমি এই পদ্ধতিটি ব্যবহার করে কোডটি প্রয়োগ করেছি তবে এটি খুব নির্ভরযোগ্য বলে মনে হচ্ছে না এবং অনেক ব্যবহারকারী বাগের অভিযোগ করেছেন যা এই পদ্ধতি দ্বারা কার্যকর করার জন্য ভুল পথ বেছে নিয়েছিল।
জেডি ডি

5
উইন্ডোজে গো 1.6 ব্যবহার করে ইম্রার একই ফলাফল পেয়েছেন (উত্স ফাইল ফোল্ডারের পরিবর্তে টেম্প ফোল্ডারের পথ পেয়েছে)। কোনও বাহ্যিক নির্ভরতা ব্যবহার না করেই আপনার উত্স ফাইলের ফোল্ডারের পথটি পেতে, ওপি কোডের একটি স্বল্প সংস্করণ ব্যবহার করুন: _, currentFilePath, _, _ := runtime.Caller(0) dirpath := path.Dir(currentFilePath)(এর runtime.Caller(0)পরিবর্তে নোট করুন runtime.Caller(1))
টাঙ্গুইপি

295

সম্পাদনা: Go 1.8 হিসাবে (ফেব্রুয়ারী 2017 প্রকাশিত) এর করার প্রস্তাবিত উপায়টি এর সাথে রয়েছে os.Executable:

func Executable() (string, error)

এক্সিকিউটেবল কার্যকর প্রক্রিয়া শুরু করে এমন এক্সিকিউটেবলের জন্য পাথের নাম ফেরত দেয়। কোনও গ্যারান্টি নেই যে পথটি এখনও সঠিক সম্পাদনযোগ্যকে নির্দেশ করছে। অপারেটিং সিস্টেমের উপর নির্ভর করে যদি প্রক্রিয়া শুরু করতে কোনও সিমলিংক ব্যবহার করা হয়, তবে ফলাফলটি হতে পারে সিমলিংক বা এটি যে পথটি নির্দেশ করেছে। যদি কোনও স্থিতিশীল ফলাফলের প্রয়োজন হয় তবে পথ / ফাইলপথ Eএলসিমলিংকগুলি সহায়তা করতে পারে।

এক্সিকিউটেবলের কেবল ডিরেক্টরি পেতে আপনি ব্যবহার করতে পারেন path/filepath.Dir

উদাহরণ :

package main

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

func main() {
    ex, err := os.Executable()
    if err != nil {
        panic(err)
    }
    exPath := filepath.Dir(ex)
    fmt.Println(exPath)
}

পুরানো উত্তর:

আপনি ব্যবহার করতে সক্ষম হওয়া উচিত os.Getwd

func Getwd() (pwd string, err error)

Getwd বর্তমান ডিরেক্টরি অনুসারে একটি মূলের নাম দেয়। যদি বর্তমান ডিরেক্টরিটি একাধিক পাথের মাধ্যমে পৌঁছানো যায় (প্রতীকী লিঙ্কের কারণে), গেটউইড তাদের যে কোনও একটিই দিতে পারে।

উদাহরণ স্বরূপ:

package main

import (
    "fmt"
    "os"
)

func main() {
    pwd, err := os.Getwd()
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
    fmt.Println(pwd)
}

3
এটি বর্তমান প্রসেস ওয়ার্কিং ডিরেক্টরি। Nodejs এটা process.cwd সমতূল্য () হল nodejs.org/api/process.html#process_process_cwd
একান্ন হতেই আজ

2
ঠিক আছে, আমি পার্থক্য দেখতে পাচ্ছি। আপনার মধ্যে ফাইলসাইমে বাইনারিটির অবস্থানের পরে (বর্তমান কার্যনির্বাহী ডিরেক্টরিটির চেয়ে বেশি) আমি মনে করি runtime.Callerএটিই আপনি সবচেয়ে কাছের "
আইডেম্যাটিক

3
'মুক্তি পেয়েছে ফেব্রুয়ারী 2017'? মনে হচ্ছে টাইম মেশিনটি উদ্ভাবিত হয়েছে এবং ভবিষ্যতে আমাদের সদস্যরা পোস্ট করছেন। ভবিষ্যতের সংস্করণে নির্ভরযোগ্য ক্রস প্ল্যাটফর্ম পদ্ধতি থাকবে তা জেনে রাখা ভাল, এরই মধ্যে আমাদের বর্তমানে উপলব্ধ সমাধানগুলিতে আটকে থাকতে হবে।
ljgww

1
@ljgww দুঃখিত, আমি আমার ডিলোরিয়ানকে নিয়ে বাড়িতে চলে যাব :-) আমি আমার উত্তরটি আগেই আপডেট করেছি কারণ আমি কেবলমাত্র আসন্ন বৈশিষ্ট্যটি দেখেছি এবং অনুমান করেছি যে উত্তরটি পরে আপডেট করতে ভুলে গিয়েছি।
ইন্টারমারনেট

1
সম্পাদনা করা হয়েছে path/filepath.Dirকারণ path.Dirকেবল ডিরেক্টরি বিভাজক হিসাবে কেবল ফরোয়ার্ড স্ল্যাশ (ইউনিক্স শৈলী) নিয়ে কাজ করে।
জোসলিন

63

প্যাকেজ osext ব্যবহার করুন

এটি এমন ফাংশন সরবরাহ করে ExecutableFolder()যা বর্তমানে চলমান প্রোগ্রামের এক্সিকিউটেবল থাকার জায়গা (ক্রোন কাজের জন্য দরকারী) ফোল্ডারে একটি নিখুঁত পথ ফেরায়। এটি ক্রস প্ল্যাটফর্ম।

অনলাইন ডকুমেন্টেশন

package main

import (
    "github.com/kardianos/osext"
    "fmt"
    "log"
)

func main() {
    folderPath, err := osext.ExecutableFolder()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(folderPath)
}

13
এটিই কেবলমাত্র উত্তর যা উইন্ডোজ এবং লিনাক্স উভয় ক্ষেত্রেই আমার জন্য প্রত্যাশিত ফলাফল তৈরি করেছিল।
ড্যানিবি

3
আপনি এটি go run main.goস্থানীয় বিকাশের জন্য ব্যবহার করতে না আসা পর্যন্ত এটি কাজ করে । আগে যতক্ষণ না প্রতিটি সময় কার্যকর করার যোগ্য নির্মাণ না করে তার পক্ষে কতটা ভাল তা নিশ্চিত না।
ডেরেক ডোলিং

1
দুঃখিত, আমি এটির সাথে কীভাবে কাজ করব তা জানি না go run। এই বাইনারিগুলি প্রতিবার অস্থায়ী ফোল্ডারে রাখা হয়।
ডব্রোসোয়া আয়েবোর্ট

2
@ ডেরেকডওল করার উপায় প্রথমে একটি কাজ করা go install, তারপরে দৌড়ানো go build -v *.go && ./main-vআপনাকে বলতে হবে যা ফাইল নির্মিত হচ্ছে। সাধারণত, আমি খুঁজে পেয়েছি যে আমি ইতিমধ্যে চালিয়েছি সময়ের মধ্যে সময় আলাদা go runএবং go buildসহনীয় go install। পাওয়ারশেলের উইন্ডোজ ব্যবহারকারীদের জন্য, কমান্ডটি হবেgo build -v {*}.go && ./main.exe
কুমারহর্ষস

যেহেতু এটি ফিরে আসবে $GOPATH/bin/, কেন ব্যবহার $GOPATH/bin/করবেন না ?
ফায়াতজাফ

10
filepath.Abs("./")

Abs পথের নিখুঁত প্রতিনিধিত্ব করে। পথটি যদি নিরঙ্কুশ না হয় তবে এটি বর্তমান কর্মনির্দেশক ডিরেক্টরিটির সাথে এটি একটি নিখুঁত পথে পরিণত করার সাথে যুক্ত হবে।

মন্তব্যে যেমন বলা হয়েছে, এটি সেই ডিরেক্টরিটি ফিরিয়ে দেয় যা বর্তমানে সক্রিয় রয়েছে।


8
এটি বর্তমান ডিরেক্টরিটি দেয়, বর্তমান ফাইলের ডিরেক্টরি নয়। উদাহরণস্বরূপ, এক্সিকিউটেবলকে অন্য কোনও পথ থেকে কল করা হলে এটি আলাদা হবে।
ফুজি

8

আপনি যদি এইভাবে ব্যবহার করেন:

dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
if err != nil {
    log.Fatal(err)
}
fmt.Println(dir)

GoLang এর মতো কিছু আইডিই ব্যবহার করে আপনি যখন প্রোগ্রামটি চালাচ্ছেন আপনি / টিএমপি পাথ পাবেন কারণ এক্সিকিউটেবল / টেম্পিপি থেকে সংরক্ষণ করবে এবং চালাবে

আমি মনে করি বর্তমান ওয়ার্কিং ডিরেক্টরি বা '' পাওয়ার সেরা উপায়। হ'ল:

import(
  "os" 
  "fmt"
  "log"
)

func main() {
  dir, err := os.Getwd()
    if err != nil {
        log.Fatal(err)
    }
  fmt.Println(dir)
}

os.Getwd () ফাংশন সাম্প্রতিক কাজ করা ফিরে আসবে। এবং এটি সমস্ত কোনও বাহ্যিক গ্রন্থাগার ব্যবহার না করে: ডি


এটি সঠিক নয়। এটি প্রক্রিয়াটি সম্পাদনকারী ব্যবহারকারীর কার্যকরী ডিরেক্টরি ফিরিয়ে দেয় এবং ফাইলের ডিরেক্টরি নয়। Filepath.abs ব্যবহার করুন।
পডটেক.ইও

1
এটি চলমান এক্সিকিউটেবল ফাইলের কার্যকারী ডিরেক্টরিটি প্রদান করে। তারপরে যদি আপনি গোল্যান্ডের মতো আইডিই ব্যবহার করেন এবং বিল্ড অপশনগুলিতে ওয়ার্কিং ডিরেক্টরিের জন্য কোনও কনফিগারেশন না থাকে তবে এটি / tmp থেকে চালানো হবে, তবে আপনার জন্য কী ব্যবহার / tmp আছে! ?? তবে আপনি যদি ওএস ব্যবহার করেন তবে এটি ব্যবহার করুন (এটি) .exe বা এলফ এক্সিকিউটেবল ফাইল পাথ ফেরত দেয়। not / tmp।
বিট

@ বিট যেমন কোনও আইডিইতে ডিবাগিংয়ের বেস টেম্পলেট ব্যবহার করে হ্যাঁ আপনাকে তা দিন, তবে কেবল 'সম্পাদনা কনফিগারেশন' চাপুন এবং 'আউটপুট ডিরেক্টরি' পূরণ করুন, যাতে আপনি 'ওএস.আরগস [0]' পাথটি চান যা আপনি চান
ϻαϻɾΣɀО -মামেরেজো

5

আপনি যদি কার্ডিয়ানোস দ্বারা প্যাকেজ ওসেক্সট ব্যবহার করেন এবং আপনার স্থানীয়ভাবে পরীক্ষা করা দরকার যেমন ডেরেক ডওলিং মন্তব্য করেছিলেন:

আপনি স্থানীয় বিকাশের জন্য go main.go দিয়ে এটি ব্যবহার করতে না আসা পর্যন্ত এটি দুর্দান্ত কাজ করে। আগে যতক্ষণ না প্রতিটি সময় কার্যকর করার যোগ্য নির্মাণ না করে তার পক্ষে কতটা ভাল তা নিশ্চিত না।

এর সমাধান হ'ল Go রান ব্যবহার না করে একটি gorun.exe ইউটিলিটি তৈরি করা। Gorun.exe ইউটিলিটি প্রকল্পটি "Go build" ব্যবহার করে সংকলন করবে, তারপরে আপনার প্রকল্পের সাধারণ ডিরেক্টরিতে চালিয়ে যাবে।

আমি অন্যান্য সংকলকগুলির সাথে এই সমস্যাটি পেয়েছি এবং নিজেকে এই ইউটিলিটিগুলি তৈরি করছিলাম যেহেতু সেগুলি সংকলকটি প্রেরণ করা হচ্ছে না ... এটি বিশেষত সি এর মতো সরঞ্জামগুলির সাথে আরকেন যেখানে আপনাকে সংকলন করতে হবে এবং লিঙ্ক করতে হবে এবং তারপরে এটি চালাতে হবে (খুব বেশি কাজ)।

কেউ যদি আমার gorun.exe (বা এলিফ) ধারণাটি পছন্দ করে তবে আমি শীঘ্রই এটি গিথুবে আপলোড করব ..

দুঃখিত, এই উত্তরটি একটি মন্তব্য হিসাবে বোঝানো হয়েছে, তবে এখনও আমার যথেষ্ট খ্যাতি না থাকার কারণে আমি মন্তব্য করতে পারি না।

বিকল্পভাবে, অস্থায়ী ডিরেক্টরিতে প্রোগ্রামটি চালনা না করার জন্য "গো রান-নোটেম্প" এর মতো একটি প্যারামিটার রাখতে "গো রান" পরিবর্তন করা যেতে পারে (যদি এটি ইতিমধ্যে এই বৈশিষ্ট্যটি না থাকে)। তবে আমি কেবল গোরুন বা "গোর" টাইপ করতে পছন্দ করব কারণ এটি সংশ্লেষিত প্যারামিটারের চেয়ে কম। Gorun.exe বা gor.exe আপনার যান সংকলক হিসাবে একই ডিরেক্টরিতে ইনস্টল করা প্রয়োজন

Gorun.exe (বা gor.exe) প্রয়োগ করা তুচ্ছ হবে, কারণ আমি কোডের কয়েকটি লাইনে অন্য সংকলকগুলির সাথে এটি করেছি ... (বিখ্যাত শেষ শব্দ ;-)


3
যদি আপনি এটি "গো রান" এবং নির্বাহযোগ্য বিল্ট উভয়ের সাথে কাজ করতে চান তবে কেবল তার _, callerFile, _, _ := runtime.Caller(0) executablePath := filepath.Dir(callerFile)পরিবর্তে ব্যবহার করুন
জোসলিন

@ জোসলিন, আপনার মন্তব্যটি এত দুর্দান্ত যে আপনার এটির পুরো উত্তর দেওয়া উচিত! এটি অবশ্যই আমার জন্য কৌশলটি করেছে - আমার নিজের সেটআপে, আমার কাছে ম্যাকোজে পরিবেশের স্থানীয় একটি অনুলিপি রয়েছে, যা আমি বেশিরভাগটি সিনট্যাক্স ত্রুটিগুলি ব্যবহার করতে ব্যবহার করি (এবং কয়েকটি শব্দার্থিক); তারপরে আমি কোডটি ডিপ্লোয়মেন্ট সার্ভারে সিঙ্ক করব যা উবুন্টু লিনাক্সের অধীনে চলে এবং পরিবেশ অবশ্যই সম্পূর্ণ আলাদা ... সুতরাং ফাইলের পাথগুলি সঠিকভাবে টেমপ্লেট, কনফিগারেশন ফাইল, স্থিতিশীল লোড করার জন্য যেখানে ফাইল পাথ রয়েছে তা নির্ধারণ করার দরকার আছে real ফাইল, ইত্যাদি ...
গ্যুইনথ ল্লেওলিন

4

os.Executable: https://tip.golang.org/pkg/os/#Executable

filepath.EvalSymlinks: https://golang.org/pkg/path/filepath/#EvalSymlinks

পূর্ণ ডেমো:

package main

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

func main() {
    var dirAbsPath string
    ex, err := os.Executable()
    if err == nil {
        dirAbsPath = filepath.Dir(ex)
        fmt.Println(dirAbsPath)
        return
    }

    exReal, err := filepath.EvalSymlinks(ex)
    if err != nil {
        panic(err)
    }
    dirAbsPath = filepath.Dir(exReal)
    fmt.Println(dirAbsPath)
}


0

গুস্তাভো নিমিমিয়ার উত্তর দুর্দান্ত। তবে উইন্ডোজে রানটাইম প্রোক বেশিরভাগ ক্ষেত্রে অন্য দিরের মতো থাকে:

"C:\Users\XXX\AppData\Local\Temp"

আপনি যদি আপেক্ষিক ফাইল পাথ ব্যবহার করেন, যেমন "/config/api.yaml", এটি আপনার প্রকল্পের পথটি ব্যবহার করবে যেখানে আপনার কোড বিদ্যমান।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.