কোনও গো প্রোগ্রামে স্থির সংস্থানগুলি বান্ডিল করার সর্বোত্তম উপায় কী? [বন্ধ]


102

আমি গোতে একটি ছোট ওয়েব অ্যাপ্লিকেশন নিয়ে কাজ করছি যার অর্থ বিকাশকারীর মেশিনে তাদের অ্যাপ্লিকেশন / ওয়েব পরিষেবাদিগুলি ডিবাগ করার জন্য একটি সরঞ্জাম হিসাবে ব্যবহৃত হবে। প্রোগ্রামটির ইন্টারফেসটি একটি ওয়েব পৃষ্ঠা যা কেবল এইচটিএমএল নয়, কিছু জাভাস্ক্রিপ্ট (কার্যকারিতার জন্য), চিত্র এবং সিএসএস (স্টাইলিংয়ের জন্য) অন্তর্ভুক্ত করে। আমি এই অ্যাপ্লিকেশনটিকে ওপেন সোর্সিংয়ের বিষয়ে পরিকল্পনা করছি, সুতরাং ব্যবহারকারীরা কেবল একটি মেকফিল চালাতে সক্ষম হন এবং সমস্ত সংস্থান যেখানে তাদের যেতে হবে সেখানে যেতে হবে। তবে, আমি খুব সহজেই যতটা সম্ভব ফাইল / নির্ভরতা সহ একটি এক্সিকিউটেবল বিতরণ করতে সক্ষম হতে চাই। এক্সিকিউটেবলের সাথে এইচটিএমএল / সিএসএস / জেএস বান্ডিল করার কি কোনও ভাল উপায় আছে, সুতরাং ব্যবহারকারীদের কেবল একটি ফাইল ডাউনলোড এবং উদ্বেগ করতে হবে?


এই মুহুর্তে, আমার অ্যাপ্লিকেশনটিতে, একটি স্ট্যাটিক ফাইল পরিবেশন করা কিছুটা দেখতে এইরকম দেখাচ্ছে:

// called via http.ListenAndServe
func switchboard(w http.ResponseWriter, r *http.Request) {

    // snipped dynamic routing...

    // look for static resource
    uri := r.URL.RequestURI()
    if fp, err := os.Open("static" + uri); err == nil {
        defer fp.Close()
        staticHandler(w, r, fp)
        return
    }

    // snipped blackhole route
}

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

এটি করার ভাল উপায় না থাকলে বা আমি এটি করার চেষ্টা করে ভুল গাছটি ছাঁটাই করছি, আমাকে জানান। আমি সবেমাত্র শেষ ব্যবহারকারীটি পরিচালনা করতে যতটা সম্ভব ফাইলের প্রশংসা করব ured

এর চেয়ে বেশি যদি উপযুক্ত ট্যাগ থাকে , দয়া করে বিনা দ্বিধায় এগুলি যুক্ত করুন বা আমাকে জানান।



আমি আসলে ঠিক আজ একই প্রশ্নটি ভেবেছিলাম। আমি যে সমাধানটি অন্বেষণ করতে পারি তা হ'ল কোডটিতে ভেরিয়েবল হিসাবে এমবেড go generateকরা ফাইলগুলিকে টুকরোতে রূপান্তর করতে একটি ছোট কমান্ড-লাইন ইউটিলিটি (আমার উত্স কোডের সাথে প্যাকেজড) ব্যবহার করা হয় ( ব্লগ.গোংআর.আর্গ. দেখুন ) / উত্পন্ন )। []bytestringer
রাল্ফ

উত্তর:


77

গো-বিনতা প্যাকেজটি দেখে মনে হচ্ছে এটি আপনার আগ্রহী হতে পারে।

https://github.com/go-bindata/go-bindata

এটি আপনাকে কোনও স্থিতিশীল ফাইলকে কোনও ফাংশন কলে রূপান্তর করতে অনুমতি দেবে যা আপনার কোডে এম্বেড করা যাবে এবং কল করার সময় ফাইলের সামগ্রীর বাইট স্লাইস ফিরে আসবে।


8
এটিকে উত্থাপন করা আমার ক্ষেত্রে অদ্ভুতভাবে স্ব-পরিবেশন করা বলে মনে হচ্ছে তবে আমি তা যাইহোক করব: p যদিও রেকর্ডের জন্য এটি কোনও প্যাকেজ নয়, একটি কমান্ড-লাইন সরঞ্জাম।
জিমট

কেবল রেকর্ডের জন্য, আমি এই প্রকল্পটি আমার প্রকল্পের সাথে নিয়েছি। কিছু সময়ে @ জিম্ট জিনিসগুলিকে আরও ব্যবহারকারী-বান্ধব করে তুলতে কিছু নতুন বৈশিষ্ট্য প্রবর্তন করেছে তবে আমার প্রয়োজনীয় গ্রানুলিটিটি আর সরবরাহ করে না, তাই আমি আমার নিজস্ব সরঞ্জামটি লিখেছিলাম যার বৈশিষ্ট্যগুলি কম তবে আমার ব্যবহারের জন্য ডিজাইন করা হয়েছে (আমি এই সরঞ্জামটিকে সাজানোর মতো হিসাবে ব্যবহার করি) বিল্ডিং প্রক্রিয়াটির উপস্থাপিত
জিমি সাওজুক

40

এম্বেড করা পাঠ্য ফাইল

যদি আমরা পাঠ্য ফাইলগুলির বিষয়ে কথা বলি তবে সেগুলি সহজেই সোর্স কোডে এম্বেড করা যায়। stringআক্ষরিক ঘোষণার জন্য কেবল পিছনের উদ্ধৃতিগুলি ব্যবহার করুন :

const html = `
<html>
<body>Example embedded HTML content.</body>
</html>
`

// Sending it:
w.Write([]byte(html))  // w is an io.Writer

অপ্টিমাইজেশন টিপ:

যেহেতু বেশিরভাগ সময় আপনাকে কেবল একটিতে সংস্থান লিখতে হবে io.Writer, আপনি কোনও []byteরূপান্তরের ফলাফলও সংরক্ষণ করতে পারেন :

var html = []byte(`
<html><body>Example...</body></html>
`)

// Sending it:
w.Write(html)  // w is an io.Writer

কেবলমাত্র আপনাকে যে বিষয় সম্পর্কে যত্নবান হতে হবে তা হ'ল কাঁচা স্ট্রিং লিটারেলগুলিতে ব্যাক কোট অক্ষর (`) থাকতে পারে না। কাঁচা স্ট্রিং লিটারেলগুলিতে সিক্যুয়েন্স থাকতে পারে না (ব্যাখ্যা করা স্ট্রিং লিটারালগুলির বিপরীতে), সুতরাং আপনি যে পাঠ্যটি এম্বেড করতে চান তা যদি পিছনের উদ্ধৃতিগুলিতে থাকে তবে আপনাকে কাঁচা স্ট্রিং আক্ষরিক ভাঙতে হবে এবং ব্যাক স্ট্রিটকে ব্যাখ্যামূলক স্ট্রিং লিটারাল হিসাবে চিহ্নিত করতে হবে, যেমন এই উদাহরণটির মতো:

var html = `<p>This is a back quote followed by a dot: ` + "`" + `.</p>`

পারফরম্যান্স প্রভাবিত হয় না, কারণ এই সংক্ষেপণগুলি সংকলক দ্বারা কার্যকর করা হবে।

বাইনারি ফাইল এম্বেড করা হচ্ছে

বাইট স্লাইস হিসাবে সংরক্ষণ করা

বাইনারি ফাইলগুলির জন্য (যেমন চিত্রগুলি) সর্বাধিক কমপ্যাক্ট (ফলস্বরূপ নেটিভ বাইনারি সম্পর্কিত) এবং সর্বাধিক দক্ষ হ'ল []byteআপনার সোর্স কোডে ফাইলটির সামগ্রী থাকতে পারে । এটি গো-বিনতার মতো তৃতীয় পক্ষের টূস / লাইব্রেরি দ্বারা উত্পাদিত হতে পারে ।

আপনি যদি এর জন্য কোনও তৃতীয় পক্ষের লাইব্রেরিটি ব্যবহার করতে না চান, তবে এখানে একটি সাধারণ কোড স্নিপেট রয়েছে যা বাইনারি ফাইল পড়ে এবং আউটপুট গো সোর্স কোড দেয় যা বিভিন্ন ধরণের ভেরিয়েবল ঘোষণা করে []byteযা ফাইলের সঠিক বিষয়বস্তু দিয়ে শুরু করা হবে:

imgdata, err := ioutil.ReadFile("someimage.png")
if err != nil {
    panic(err)
}

fmt.Print("var imgdata = []byte{")
for i, v := range imgdata {
    if i > 0 {
        fmt.Print(", ")
    }
    fmt.Print(v)
}
fmt.Println("}")

আউটপুট উদাহরণস্বরূপ যদি ফাইলটিতে 0 থেকে 16 পর্যন্ত বাইট থাকে (এটি খেলার খেলার মাঠে চেষ্টা করুন ):

var imgdata = []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}

বেস 64 হিসাবে সংরক্ষণ করা হচ্ছে string

যদি ফাইলটি "খুব বড়" না হয় (বেশিরভাগ চিত্র / আইকনগুলি যোগ্য হয়) তবে অন্যান্য কার্যকর বিকল্পও রয়েছে। আপনি ফাইলের সামগ্রীটি একটি বেস 64 এ রূপান্তর করতে পারেন stringএবং এটি আপনার উত্স কোডে সঞ্চয় করতে পারেন। অ্যাপ্লিকেশন শুরুতে ( func init()) বা যখন প্রয়োজন হয়, আপনি এটিকে মূল []byteবিষয়বস্তুতে ডিকোড করতে পারেন । encoding/base64প্যাকেজে বেস 64 এনকোডিংয়ের জন্য গো সমর্থন করুন ।

একটি (বাইনারি) ফাইলকে বেস 64 তে রূপান্তর stringকরা যেমন সহজ:

data, err := ioutil.ReadFile("someimage.png")
if err != nil {
    panic(err)
}
fmt.Println(base64.StdEncoding.EncodeToString(data))

আপনার উৎস কোডের, যেমন একটি হিসাবে ফলাফলের করুন Base64- স্ট্রিং সঞ্চয় করুন const

এটিকে ডিকোডিং করা কেবল একটি ফাংশন কল:

const imgBase64 = "<insert base64 string here>"

data, err := base64.StdEncoding.DecodeString(imgBase64) // data is of type []byte

উদ্ধৃত হিসাবে সংরক্ষণ করা string

বেস 64 হিসাবে সংরক্ষণের চেয়ে আরও দক্ষ, তবে উত্স কোডে দীর্ঘতর হতে পারে বাইনারি ডেটার উদ্ধৃত স্ট্রিং আক্ষরিক সংরক্ষণ করে । আমরা strconv.Quote()ফাংশনটি ব্যবহার করে যে কোনও স্ট্রিংয়ের উদ্ধৃত ফর্মটি পেতে পারি :

data, err := ioutil.ReadFile("someimage.png")
if err != nil {
    panic(err)
}
fmt.Println(strconv.Quote(string(data))

0 থেকে 64 অবধি মানযুক্ত বাইনারি ডেটাগুলির জন্য আউটপুটটি কেমন দেখাচ্ছে ( গো খেলার মাঠে এটি চেষ্টা করুন ):

"\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?"

(নোট করুন যে strconv.Quote()এটিতে একটি উদ্ধৃতি চিহ্ন সংযোজন এবং সংযোজন করা হয়েছে))

আপনি সরাসরি আপনার উত্স কোডে এই উদ্ধৃত স্ট্রিংটি ব্যবহার করতে পারেন, উদাহরণস্বরূপ:

const imgdata = "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?"

এটি ব্যবহারের জন্য প্রস্তুত, এটি ডিকোড করার প্রয়োজন নেই; আনকোটিংটি সংকলনের সময় গো সংকলক দ্বারা সম্পন্ন হয়।

আপনি এটি বাইট স্লাইস হিসাবে এটির মতো আপনার প্রয়োজন হওয়া উচিত need

var imgdata = []byte("\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?")

shএক্সিকিউটেবলের সাথে ফাইল বাঁধতে কোনও উপায় আছে কি?
কাসুন সিয়ামম্বলাপিতিয়া

আমার ধারণা, "বাইট স্লাইস হিসাবে সংরক্ষণ করা" বিভাগের অধীনে প্রথম কোড স্নিপেটে ডেটা ইমগডেটা করা উচিত।
যৌক্তিক x 2

4
@ ডিউজেক্সমাছিনা ঠিক বলেছেন, ঠিক করেছেন। খেলার মাঠের কোডটি ইতিমধ্যে সঠিক ছিল।
আইজজা

2

এছাড়াও কিছু বিদেশি উপায় রয়েছে - আমি GoLang প্রকল্পগুলি নির্মাণের জন্য maven প্লাগইন ব্যবহার করি এবং এটি বাইনারি ব্লক এবং পাঠ্য ফাইলগুলিকে উত্সগুলিতে এম্বেড করতে JCP প্রিপ্রসেসর ব্যবহার করতে দেয় । ক্ষেত্রে কোডটি নীচের লাইনের মতো দেখতে ( এবং কিছু উদাহরণ এখানে পাওয়া যাবে )

var imageArray = []uint8{/*$binfile("./image.png","uint8[]")$*/}

@ shউপরের মতো এক্সিকিউটেবলের মতো কোনও ডিরেক্টরিকে বাঁধাই সম্ভব
কাসুন সিয়ামবলপিতিয়া

@ কাসুনসিয়াম্বলপিতি একটি ডিরেক্টরি বাঁধুন? একটি shফাইল বাঁধাই ? আপনি কি বোঝাতে চেয়েছেন তা নিশ্চিত না। আপনি যদি কোনও ডিরেক্টরিতে থাকা সমস্ত কিছু এম্বেড করাতে চান তবে এটি আমি দিয়ে কিছু করেছি go-bindata। উদাহরণস্বরূপ, যদি আমি //go:generate $GOPATH/bin/go-bindata -prefix=data/ -pkg=$GOPACKAGE data/একটি (অ-উত্পন্ন) গো ফাইলটি go generate ./...রাখি, তবে প্যাকেজের ডিয়ারে গো-বিনতাটা চালিত হবে, যা ডেটা সাবডিরের মধ্যে সবকিছু এম্বেড করে তবে 'ডেটা /' উপসর্গটি মুছে ফেলা হয়।
চিহ্নিত করুন

1

go-bindataঅন্য উত্তরে উল্লিখিত একটি জনপ্রিয় বিকল্প হিসাবে , এমজিবসন / এসকেও স্বেচ্ছাসেবী ফাইল এম্বেড করে তবে বিশেষত সুবিধামত ডিরেক্টরি গাছগুলি পরিচালনা করে।

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