গো-র স্ট্যান্ডার্ড লাইব্রেরিতে কোনও ফাইল উপস্থিত রয়েছে কি না (তা পাইথনের মতো os.path.exists
) যাচাই করে বাছাই করার উদ্দেশ্যে কেবল কোনও ফাংশন নেই । এটি করার মূর্তিমান পদ্ধতি কী ?
গো-র স্ট্যান্ডার্ড লাইব্রেরিতে কোনও ফাইল উপস্থিত রয়েছে কি না (তা পাইথনের মতো os.path.exists
) যাচাই করে বাছাই করার উদ্দেশ্যে কেবল কোনও ফাংশন নেই । এটি করার মূর্তিমান পদ্ধতি কী ?
উত্তর:
ফাইল উপস্থিত নেই কিনা তা পরীক্ষা করতে পাইথনের সমতুল্য if not os.path.exists(filename)
:
if _, err := os.Stat("/path/to/whatever"); os.IsNotExist(err) {
// path/to/whatever does not exist
}
কোনও ফাইল রয়েছে কিনা তা পরীক্ষা করতে পাইথনের সমতুল্য if os.path.exists(filename)
:
সম্পাদিত: সাম্প্রতিক মন্তব্যসমূহ অনুসারে
if _, err := os.Stat("/path/to/whatever"); err == nil {
// path/to/whatever exists
} else if os.IsNotExist(err) {
// path/to/whatever does *not* exist
} else {
// Schrodinger: file may or may not exist. See err for details.
// Therefore, do *NOT* use !os.IsNotExist(err) to test for file existence
}
NOTEXIST
, উদাহরণস্বরূপ, যদি /etc/bashrc
উপস্থিত থাকে তবে /etc/bashrc/foobar
ফিরে আসবেENOTDIR
!os.IsNotExist(err)
। ফাইলটি বিদ্যমান থাকতে পারে তবে os.Stat
অন্যান্য কারণে ব্যর্থ হয় (যেমন অনুমতি, ব্যর্থ ডিস্ক)। err == nil
শর্ত হিসাবে ব্যবহার করে এই ধরনের ব্যর্থতাকে "ফাইলটির অস্তিত্ব নেই" হিসাবে ভুলভাবে শ্রেণিবদ্ধ করে।
গালটস মেলিং তালিকায় পোস্ট করা কালেব স্পেরের উত্তর ।
[...] এটি আসলে খুব বেশি প্রয়োজন হয় না এবং [...]
os.Stat
যে ক্ষেত্রে এটি প্রয়োজন হয় সেখানে ব্যবহার করা যথেষ্ট সহজ।[...] উদাহরণস্বরূপ: আপনি যদি ফাইলটি খুলতে চলেছেন তবে এটি আগে বিদ্যমান কিনা তা খতিয়ে দেখার কোনও কারণ নেই। ফাইলটি পরীক্ষা এবং খোলার মধ্যে অদৃশ্য হয়ে যেতে পারে এবং যাইহোক আপনার
os.Open
ত্রুটি নির্বিশেষে পরীক্ষা করতে হবে। সুতরাং আপনিos.IsNotExist(err)
ফাইলটি খোলার চেষ্টা করার পরে কেবল কল করুন এবং সেখানে এর অস্তিত্বকে মোকাবেলা করুন (যদি এর জন্য বিশেষ হ্যান্ডলিং প্রয়োজন হয়)।[...] আপনার কোনও অবস্থাতেই পাথগুলি পরীক্ষা করার প্রয়োজন নেই (এবং আপনারও হওয়া উচিত নয়)।
os.MkdirAll
পথগুলি ইতিমধ্যে বিদ্যমান কিনা তা কাজ করে। (এছাড়াও আপনাকে সেই কলটি থেকে ত্রুটিটি পরীক্ষা করা দরকার))ব্যবহার করার পরিবর্তে
os.Create
, আপনার ব্যবহার করা উচিতos.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
। এই ফাইলটি ইতিমধ্যে উপস্থিত থাকলে আপনি একটি ত্রুটি পাবেন। এছাড়াও এটির আগে থেকে অস্তিত্বের জন্য যাচাই করা আপনার সংস্করণটি পৃথক করে অন্য কিছু ফাইল তৈরির সাথে রেসের শর্ত নেই।
থেকে নেওয়া: https://groups.google.com/forum/#!msg/golang-nuts/Ayx-BMNdMFo/4rL8FFHr8v4J
নিম্নলিখিত উদাহরণগুলির মতো আপনার os.Stat()
এবং os.IsNotExist()
ফাংশনগুলি ব্যবহার করা উচিত :
// Exists reports whether the named file or directory exists.
func Exists(name string) bool {
if _, err := os.Stat(name); err != nil {
if os.IsNotExist(err) {
return false
}
}
return true
}
ব্যবহারকারী 11617 এর উদাহরণটি ভুল; এটি রিপোর্ট করবে যে ফাইলটি এমন ক্ষেত্রেও উপস্থিত রয়েছে যেখানে এটি না ঘটে তবে অন্য কোনও ধরণের ত্রুটি ছিল।
স্বাক্ষরটি বিদ্যমান (স্ট্রিং) (বুল, ত্রুটি) হওয়া উচিত। এবং তারপরে, যেমনটি ঘটে, কল সাইটগুলি এর চেয়ে ভাল are
তাঁর রচিত কোডটি আরও ভাল হবে:
func Exists(name string) bool {
_, err := os.Stat(name)
return !os.IsNotExist(err)
}
তবে আমি পরিবর্তে এটির পরামর্শ দিচ্ছি:
func Exists(name string) (bool, error) {
_, err := os.Stat(name)
if os.IsNotExist(err) {
return false, nil
}
return err != nil, err
}
err != nil
পরিবর্তে ফিরে আসবে কেন err == nil
? যদি কোনও ত্রুটি থাকে তবে ফাইলটি সম্ভবত উপস্থিত নেই?
অন্যান্য উত্তরগুলি কী মিস করেছে, তা হ'ল ফাংশনে প্রদত্ত পথটি আসলে একটি ডিরেক্টরি হতে পারে। নিম্নলিখিত ফাংশনটি নিশ্চিত করে তোলে, যে পথটি আসলেই একটি ফাইল।
func fileExists(filename string) bool {
info, err := os.Stat(filename)
if os.IsNotExist(err) {
return false
}
return !info.IsDir()
}
আরেকটি বিষয় উল্লেখ করতে হবে: এই কোডটি এখনও রেসের শর্তের দিকে নিয়ে যেতে পারে, যেখানে অন্য একটি থ্রেড বা প্রক্রিয়া নির্দিষ্ট ফাইলটিকে মুছে ফেলা বা তৈরি করে, যখন ফাইলএক্সিস্ট ফাংশন চলমান থাকে।
আপনি যদি এই সম্পর্কে উদ্বিগ্ন হন তবে আপনার থ্রেডগুলিতে একটি লক ব্যবহার করুন, এই ফাংশনে অ্যাক্সেসটিকে সিরিয়ালাইজ করুন বা একাধিক অ্যাপ্লিকেশন জড়িত থাকলে একটি আন্ত-প্রক্রিয়া সেমফোর ব্যবহার করুন। আপনারা নিয়ন্ত্রণের বাইরে যদি অন্য অ্যাপ্লিকেশনগুলি জড়িত থাকে তবে আপনার ভাগ্য খুব খারাপ,
ফাংশন উদাহরণ:
func file_is_exists(f string) bool {
_, err := os.Stat(f)
if os.IsNotExist(err) {
return false
}
return err == nil
}
প্রথমে কয়েকটি দিক বিবেচনা করা যাক, os
প্যাকেজের প্যাকেজ দ্বারা প্রদত্ত ফাংশন উভয়ই golang
ইউটিলিটিস নয় বরং ত্রুটি যাচাইকারী, এর অর্থ আমি কী বলতে চাইছি যে তারা ক্রস প্ল্যাটফর্মের ত্রুটিগুলি পরিচালনা করার জন্য কেবল একটি মোড়ক।
সুতরাং মূলত যদি os.Stat
এই ফাংশনটি যদি কোনও ত্রুটি না দেয় তবে এর অর্থ ফাইলটি বিদ্যমান রয়েছে যদি এটির কী ধরণের ত্রুটি রয়েছে তা যাচাই করা দরকার হয় তবে এখানে এই দুটি ফাংশন os.IsNotExist
এবং ব্যবহারটি আসে os.IsExist
।
এটি Stat
ফাইল নিক্ষেপ ত্রুটির হিসাবে বোঝা যায় কারণ এটি বিদ্যমান নেই বা এটি ত্রুটি নিক্ষেপ করছে কারণ এটি বিদ্যমান এবং এটিতে কিছু সমস্যা রয়েছে।
এই ফাংশনগুলি যে পরামিতিগুলি নেয় সেগুলি ধরণের error
, যদিও আপনি nil
এটিতে সক্ষম হতে পারেন তবে এটি কোনও অর্থবোধ করে না।
এটি এটিকেও নির্দেশ করে যে IsExist is not same as !IsNotExist
, তারা উপায় দুটি ভিন্ন জিনিস।
সুতরাং এখন যদি আপনি জানতে চান যে কোনও প্রদত্ত ফাইলের অস্তিত্ব রয়েছে কিনা, তবে আমি সবচেয়ে ভাল উপায়টি পছন্দ করব:
if _, err := os.Stat(path/to/file); !os.IsNotExist(err){
//TODO
}
অন্যান্য উত্তরে উল্লিখিত হিসাবে, বিভিন্ন পতাকা ব্যবহার করে প্রয়োজনীয় আচরণ / ত্রুটিগুলি তৈরি করা সম্ভব os.OpenFile
। আসলে os.Create
এটি করার জন্য কেবল বুদ্ধিমান-খেলাপি শর্টহ্যান্ড:
// Create creates or truncates the named file. If the file already exists,
// it is truncated. If the file does not exist, it is created with mode 0666
// (before umask). If successful, methods on the returned File can
// be used for I/O; the associated file descriptor has mode O_RDWR.
// If there is an error, it will be of type *PathError.
func Create(name string) (*File, error) {
return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
}
আপনার আগ্রহী আচরণটি পেতে আপনার এই পতাকাগুলি একত্রিত করতে হবে:
// Flags to OpenFile wrapping those of the underlying system. Not all
// flags may be implemented on a given system.
const (
// Exactly one of O_RDONLY, O_WRONLY, or O_RDWR must be specified.
O_RDONLY int = syscall.O_RDONLY // open the file read-only.
O_WRONLY int = syscall.O_WRONLY // open the file write-only.
O_RDWR int = syscall.O_RDWR // open the file read-write.
// The remaining values may be or'ed in to control behavior.
O_APPEND int = syscall.O_APPEND // append data to the file when writing.
O_CREATE int = syscall.O_CREAT // create a new file if none exists.
O_EXCL int = syscall.O_EXCL // used with O_CREATE, file must not exist.
O_SYNC int = syscall.O_SYNC // open for synchronous I/O.
O_TRUNC int = syscall.O_TRUNC // truncate regular writable file when opened.
)
আপনি কী বেছে নেবেন তার উপর নির্ভর করে আপনি বিভিন্ন ত্রুটি পাবেন।
এখানে একটি উদাহরণ রয়েছে যেখানে আমি লেখার জন্য কোনও ফাইল খুলতে চাই, তবে ব্যবহারকারী কেবল ঠিক আছে বলে যদি আমি কেবল একটি বিদ্যমান ফাইল কেটে দেব:
var f *os.File
if truncateWhenExists {
// O_TRUNC - truncate regular writable file when opened.
if f, err = os.OpenFile(filepath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644); err != nil {
log.Fatalln("failed to force-open file, err:", err)
}
} else {
// O_EXCL - used with O_CREATE, file must not exist
if f, err = os.OpenFile(filepath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0644); err != nil {
log.Fatalln("failed to open file, err:", err)
}
}