1. অপারেটিং সিস্টেম লাইব্রেরির মৌলিক বিষয়

Golang-এ os প্যাকেজটি অপারেটিং সিস্টেম ফাংশনগুলির জন্য একটি প্ল্যাটফর্ম বিনিময়যোগ্য ইন্টারফেস সরবরাহ করে। পরবর্তীতে, আমরা আলোচনা করব যেভাবে os প্যাকেজ ব্যবহার করে ফাইল খোলা, বন্ধ করা, পড়া, লিখা, এবং ফাইলের গুণাবলী পেতে এবং সেট করতে।

1.1 ফাইল খোলা এবং বন্ধ করা

Go ভাষায়, আপনি os.Open ফাংশন ব্যবহার করে ফাইল খোলতে পারেন, যা একটি *os.File অবজেক্ট এবং একটি ত্রুটি ফেরত দেবে। একবার ফাইলটি খোলা হলে, আপনি পড়া, লিখা, এবং অন্যান্য অপারেশন করতে পারেন। অপারেশন সম্পাদিত হলে, আপনাকে file.Close কল করে ফাইলটি বন্ধ করতে এবং সম্পর্কিত সহবাসনি মুক্ত করতে হবে।

নিচে একটি ফাইল খোলার উদাহরণ:

package main

import (
    "fmt"
    "os"
)

func main() {
    // বর্তমান ডিরেক্টরিতে test.txt নামে ফাইল খোলা
    file, err := os.Open("test.txt")
    if err != nil {
        // ফাইল খোলার ত্রুটি হ্যান্ডেল করুন
        fmt.Println("ত্রুটি ফাইল খোলার সময়:", err)
        return
    }
    // ফাইলটি শেষে বন্ধ করার জন্য defer বিবৃতি ব্যবহার করুন
    defer file.Close()

    // ফাইল হ্যান্ডলিং অপারেশন...

    fmt.Println("ফাইল সফলভাবে খোলা হয়েছে")
}

উপরের কোডে, আমরা defer বিবৃতি ব্যবহার করে নিশ্চিত করতে, যে file.Close যথায়বধি সম্পাদিত হবে। এটি রিসোর্স বিনিয়োগের জন্য Go ভাষায় একটি সাধারণ অনুশাসন।

1.2 ফাইল পড়া এবং লিখা অপারেশন

os.File ধরনের Read এবং Write মেথড রয়েছে, যা ফাইল পড়া এবং লেখা অপারেশনের জন্য ব্যবহার করা যেতে পারে। Read মেথড ডেটা ফাইল থেকে একটি বাইট স্লাইসে পড়ে, এবং Write মেথড একটি বাইট স্লাইসের ডেটা ফাইলে লিখে।

নিচের উদাহরণে দেখানো হয় যেভাবে ফাইল থেকে পড়া এবং লেখার অপারেশন করতে হয়:

package main

import (
    "fmt"
    "os"
)

func main() {
    // ফাইলটি খোলা
    file, err := os.OpenFile("test.txt", os.O_RDWR, 0644)
    if err != nil {
        fmt.Println("ত্রুটি ফাইল খোলার সময়:", err)
        return
    }
    defer file.Close()

    // ফাইলের বিষয় লিখুন
    message := []byte("হ্যালো, গোফারস!")
    _, writeErr := file.Write(message)
    if writeErr != nil {
        fmt.Println("ফাইলে লিখার সময় ত্রুটি:", writeErr)
        return
    }

    // শুরু থেকে ফাইল পড়ুন
    file.Seek(0, 0)
    buffer := make([]byte, len(message))
    _, readErr := file.Read(buffer)
    if readErr != nil {
        fmt.Println("ফাইল পড়ার সময় ত্রুটি:", readErr)
        return
    }

    fmt.Println("ফাইলের বিষয়:", string(buffer))
}

এই উদাহরণে, আমরা os.OpenFile ব্যবহার করে os.Open ব্যবহার না করেই। os.OpenFile ফাংশনটি ফাইল খোলার সময় ব্যবহার করা সময় মোড এবং অনুমতি নির্ধারণ করতে দেয়। উপরের উদাহরণে, os.O_RDWR পতাকা ব্যবহার করা হয়, অর্থাৎ ফাইলটি পড়া-লিখার মোডে খোলা হবে।

1.3 ফাইল সম্পত্তি এবং অনুমতি

আপনি os প্যাকেজ থেকে ফাইল স্থিতি সম্পর্কিত তথ্যে অ্যাক্সেস এবং পরিবর্তন করতে পারেন। os.Stat বা os.Lstat ব্যবহার করে os.FileInfo ইন্টারফেস প্রাপ্ত করতে পারেন, যা ফাইলের মাধ্যমে আয়াতন, অনুমতি, পরিবর্তন সময়, এবং আরো ধারণা সরবরাহ করে।

এখানে ফাইল স্থিতি অর্জনের উদাহরণ:

package main

import (
    "fmt"
    "os"
)

func main() {
    fileInfo, err := os.Stat("test.txt")
    if err != nil {
        fmt.Println("ফাইল তথ্য পেতে সমস্যা:", err)
        return
    }

    // ফাইলের আয়াতন প্রিন্ট করুন
    fmt.Printf("ফাইলের আয়াতন: %d বাইট\n", fileInfo.Size())

    // ফাইলের অনুমতি প্রিন্ট করুন
    fmt.Printf("ফাইলের অনুমতি: %s\n", fileInfo.Mode())
}

যদি আপনার ফাইলের নাম পরিবর্তন করতে বা ফাইলের অনুমতি পরিবর্তন করতে চান, তবে আপনি os.Rename ব্যবহার করে ফাইলের নাম পরিবর্তন করতে পারেন অথবা os.Chmod ব্যবহার করে ফাইলের অনুমতি পরিবর্তন করতে পারেন।

package main

import (
    "fmt"
    "os"
)

func main() {
    // ফাইলের অনুমতি পড়ায় পরিবর্তন করুন
    err := os.Chmod("test.txt", 0444)
    if err != nil {
        fmt.Println("ফাইলের অনুমতি পরিবর্তনে সমস্যা হয়েছে:", err)
        return
    }

    // ফাইলের নাম পরিবর্তন করুন
    renameErr := os.Rename("test.txt", "renamed.txt")
    if renameErr != nil {
        fmt.Println("ফাইলের নাম পরিবর্তনে সমস্যা হয়েছে:", renameErr)
        return
    }
    
    fmt.Println("ফাইল সফলভাবে অপারেশন হয়েছে")
}

এখানে, আমরা test.txt ফাইলের অনুমতিকে শুধুমাত্র পড়ায় পরিবর্তন করেছি এবং তারপরে ফাইলটির নামকরণ করেছি renamed.txt। অনুমতি নির্ধারণ করা অযত্ন সেটিং অনুমতি অপ্রাপ্ত করে অপ্রাপ্ত ফাইলে পৌঁছতে পারে এমনটি মনে রাখবেন।

2. আইও লাইব্রেরির মৌলিক ব্যবহার

Go ভাষায়, io লাইব্রেরি আই/ও প্রাইমিটিভ (ইনপুট/আউটপুট অপারেশন) এর জন্য মৌলিক ইন্টারফেস সরবরাহ করে। io লাইব্রেরির ডিজাইনটি সাধারণত সরলতা এবং একরূপতা ইন্টারফেসের নীতিকে অনুসরণ করে, যা ফাইল পড়া/লেখা, নেটওয়ার্ক যোগাযোগ, ডেটা বাফারিং, এবং আরও প্রকারের ইনপুট/আউটপুট অপারেশনের মৌলিক সাপোর্ট সরবরাহ করে।

2.2 রিডার এবং রাইটার ইন্টারফেস ব্যবহার

io.Reader এবং io.Writer দুটি মৌলিক ইন্টারফেস যা একটি অবজেক্টের রিড এবং রাইট অপারেশন নির্দিষ্ট করতে ব্যবহৃত হয়। এগুলি ফাইল, নেটওয়ার্ক সংযোগ, এবং বাফারের মতো বিভিন্ন ধরণের অবজেক্ট দ্বারা প্রয়োগ করা হয়।

io.Reader

io.Reader ইন্টারফেসে একটি Read মেথড থাকে:

Read(p []byte) (n int, err error)

এই মেথড p থেকে সর্বাধিক len(p) বাইট ডেটা io.Reader থেকে p এ পড়ে। এটি পড়া বাইটের সংখ্যা n (0 <= n <= len(p)) এবং প্রাপ্ত কোনও ত্রুটির প্রেক্ষিতে ফিরে।

উদাহরণ কোড:

package main

import (
    "fmt"
    "io"
    "strings"
)

func main() {
    r := strings.NewReader("Hello, World!")

    buf := make([]byte, 4)
    for {
        n, err := r.Read(buf)
        if err == io.EOF {
            break
        }
        fmt.Printf("পড়া বাইট: %d, কনটেন্ট: %s\n", n, buf[:n])
    }
}

এই উদাহরণে, আমরা একটি স্ট্রিং থেকে ডেটা পড়তে strings.NewReader তৈরি করেছি এবং তারপর পড়ো ডেটা চার-বাইট চাঙ্কে পড়বে।

io.Writer

io.Writer ইন্টারফেসে একটি Write মেথড থাকে:

Write(p []byte) (n int, err error)

এই মেথড p থেকে ডেটা আন্ডারলাইনিং ডেটা স্ট্রিমে লেখা করে, প্রাপ্ত কোনও ত্রুটির সাথে লেখা হওয়া বাইটের সংখ্যা এবং ফিরে।

উদাহরণ কোড:

package main

import (
    "fmt"
    "os"
)

func main() {
    data := []byte("Hello, World!\n")
    n, err := os.Stdout.Write(data)
    if err != nil {
        panic(err)
    }
    fmt.Printf("লিখিত বাইট: %d\n", n)
}

এই উদাহরণে, একটি সাধারণ স্ট্রিংকে স্ট্যান্ডার্ড আউটপুট os.Stdout এ লিখে। যা io.Writer এর একটি ইমপ্লিমেন্টেশন হিসাবে কাজ করে।

2.3 উন্নত পড়া/লেখা ফাংশন

io প্যাকেজটি কিছু উন্নত ফাংশন সরবরাহ করে, যা সাধারণ কাজগুলি সহজে করতে সাহায্য করে, যেমন ডেটা কপি করা এবং নির্দিষ্ট পরিমাণ ডেটা পড়া ইত্যাদি।

কপি ফাংশন

io.Copy হল একটি সুবিধাজনক পদ্ধতি যা ইন্টারমিডিয়েট বাফার ছাড়াই ডেটা কপি করতে সহায়ক।

উদাহরণ কোড:

package main

import (
    "io"
    "os"
    "strings"
)

func main() {
    r := strings.NewReader("সাধারণ কপি অপারেশনের উদাহরণ")
    _, err := io.Copy(os.Stdout, r)
    if err != nil {
        panic(err)
    }
}

এই উদাহরণে, আমরা সরাসরি একটি স্ট্রিংকে মানচিত্রে কপি করছি।

ReadAtLeast ফাংশন

io.ReadAtLeast ফাংশনটি ব্যবহার করা হয় একটি io.Reader থেকে কমপক্ষে নির্ধারিত পরিমাণ ডেটা পড়ে পেতে আগে নিজেরা দেখে নেয়ার জন্য।

func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error)

উদাহরণ কোড:

package main

import (
    "fmt"
    "io"
    "strings"
)

func main() {
    r := strings.NewReader("গো ভাষা চীনা ওয়েবসাইট")
    buf := make([]byte, 14)
    n, err := io.ReadAtLeast(r, buf, 14)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Printf("%s\n", buf[:n])
}

এই উদাহরণে, io.ReadAtLeast প্রয়াস করছে ন্যান্যতম 14 বাইট ডেটা দ্রুত বাফারে পড়ার জন্য।

এই উন্নত পড়া/লেখা ফাংশনগুলি আপনাকে আই/ও-সংবন্ধীয় কাজগুলি পরিচালনা করতে অনুমতি দেয় এবং আরও জটিল প্রোগ্রাম লজিক তৈরির জন্য একটি প্রতিষ্ঠিত ভিত্তি প্রদান করে।