この記事は、Golang1.16 で embed を使用して静的ファイルをロードする方法を紹介する go 言語 チュートリアル コラムによって提供されています。
#embed とは
embed は Go 1.16 で追加された新しいパッケージです。 //go:embed
ディレクティブを使用して、コンパイル段階で静的リソース ファイルをコンパイル済みプログラムにパッケージ化し、これらのファイルにアクセスできるようにします。
埋め込みが必要な理由
過去には、他の言語から Go 言語に切り替えた多くの友人が尋ねたり、踏み込んだりしていました。ピット : Go 言語によってパッケージ化されたバイナリ ファイルには、構成ファイルの共同コンパイルとパッケージ化が含まれることが想定されています。
その結果、バイナリ ファイルが移動されると、静的ファイルのリソースを読み取ることができないため、アプリケーションを実行できなくなります。
静的リソースをコンパイルしてバイナリ ファイルにパッケージ化できない場合、通常は 2 つの解決策があります。
- 1 つ目は、そのような静的リソースを特定し、プログラムに従う必要があるかどうかを確認することです。
- 2 つ目は、バイナリ ファイルにパッケージ化することです。
2 番目のケースでは、Go は以前はこれをサポートしていなかったので、誰もが次のようなさまざまな派手なオープン ソース ライブラリを使用することになります。 しかし、Go1.16 以降、Go 言語自体がこの機能を正式にサポートしています。
これには次の利点があります。
- 静的リソースをバイナリ パッケージにパッケージ化でき、デプロイメント プロセスがより簡単になります。
- 従来のデプロイメントでは、コンパイルされたプログラムとともに静的リソースをパッケージ化してアップロードするか、docker と
dockerfile
を使用して前者を自動化する必要がありますが、これは非常に面倒です。 プログラムの整合性を確保します - 。動作中の静的リソースの損傷または損失は、通常、プログラムの通常の動作に影響を与えます。 静的リソースへのアクセスには IO 操作はなく、速度は非常に高速になります。
embed の基本的な使用法公式ドキュメントを通じて、文字列、バイト、FS (ファイル システム) という 3 つの埋め込み方法がわかります。このうち、
string 型と []byte
型は 1 つのファイルのみに一致するため、複数のファイルまたはディレクトリに一致させたい場合は、embed.FS# を使用する必要があります。 ## タイプ。
特記事項: 埋め込みパッケージをインポートする必要があります。インポートを使用しない場合は、_ を使用してインポートしてください。
1. として埋め込みます。文字列
たとえば、現在のファイルの下にファイル hello.txt があり、ファイルの内容は
hello,world!です。
go:embed 命令により、コンパイル後、次のプログラムの s 変数の値は
hello,world! になります。
package mainimport ( _ "embed" "fmt")//go:embed hello.txtvar s stringfunc main() { fmt.Println(s)}
2. バイト スライスとして埋め込む単一ファイルの内容をバイトのスライス (バイト配列) として埋め込むこともできます。
package mainimport ( _ "embed" "fmt")//go:embed hello.txtvar b []bytefunc main() { fmt.Println(b)}
3. fs.FS
として埋め込む ファイル システムとして埋め込むこともでき、複数のファイルを埋め込む場合に非常に便利です。
たとえば、ファイルを埋め込みます:
package mainimport ( "embed" "fmt")//go:embed hello.txtvar f embed.FSfunc main() { data, _ := f.ReadFile("hello.txt") fmt.Println(string(data))}別のローカル ファイル hello2.txt を埋め込み、同じ変数に対する複数の
go:embed
命令をサポートします (文字列または A として埋め込みます)バイト スライスには複数のgo:embed 命令を含めることはできません):
package mainimport ( "embed" "fmt")//go:embed hello.txt//go:embed hello2.txtvar f embed.FSfunc main() { data, _ := f.ReadFile("hello.txt") fmt.Println(string(data)) data, _ = f.ReadFile("hello2.txt") fmt.Println(string(data))}
現在繰り返されている
go:embed 命令の embed.FS への埋め込みがサポートされています。
package mainimport ( "embed" "fmt")//go:embed hello.txt//go:embed hello.txtvar f embed.FSfunc main() { data, _ := f.ReadFile("hello.txt") fmt.Println(string(data))}
サブフォルダーにファイルを埋め込むこともできます:
package mainimport ( "embed" "fmt")//go:embed p/hello.txt//go:embed p/hello2.txtvar f embed.FSfunc main() { data, _ := f.ReadFile("p/hello.txt") fmt.Println(string(data)) data, _ = f.ReadFile("p/hello2.txt") fmt.Println(string(data))}embed高度な使用法
Go1.16 を embed ## にサポートするには# は新しいパッケージ
io/fs にも追加されました。 2 つを結合すると、以前の通常のファイルと同じように操作できます。 1. 読み取り専用
埋め込まれたコンテンツは読み取り専用です。つまり、コンパイル時の埋め込みファイルの内容は何か、次に実行時の内容は何かということです。 FS ファイル システムの値は、オープンおよび読み取りのメソッドを提供しますが、書き込みメソッドはありません。これは、FS インスタンスがスレッドセーフであり、複数の goroutine を同時に使用できることを意味します。
embed.FS 構造には、主に次の 3 つの外部メソッドがあります:
// Open 打开要读取的文件,并返回文件的fs.File结构.func (f FS) Open(name string) (fs.File, error)// ReadDir 读取并返回整个命名目录func (f FS) ReadDir(name string) ([]fs.DirEntry, error)// ReadFile 读取并返回name文件的内容.func (f FS) ReadFile(name string) ([]byte, error)
2. 複数のファイルを埋め込む
package mainimport (
"embed"
"fmt")//go:embed hello.txt hello2.txtvar f embed.FSfunc main() {
data, _ := f.ReadFile("hello.txt")
fmt.Println(string(data))
data, _ = f.ReadFile("hello2.txt")
fmt.Println(string(data))}
もちろん、前の例のように複数行を記述することもできます go:embed
:package mainimport ( "embed" "fmt")//go:embed hello.txt//go:embed hello2.txtvar f embed.FSfunc main() { data, _ := f.ReadFile("hello.txt") fmt.Println(string(data)) data, _ = f.ReadFile("hello2.txt") fmt.Println(string(data))}
3. フォルダー分離のサポート
文字は使用しますスラッシュ /
、Windows システムでもこのパターンが使用されます。package mainimport ( "embed" "fmt")//go:embed pvar f embed.FSfunc main() { data, _ := f.ReadFile("p/hello.txt") fmt.Println(string(data)) data, _ = f.ReadFile("p/hello2.txt") fmt.Println(string(data))}
应用
在我们的项目中,是将应用的常用的一些配置写在了.env的一个文件上,所以我们在这里就可以使用go:embed
指令。
main.go
文件:
//go:embed ".env" "v1d0/.env"var FS embed.FSfunc main(){ setting.InitSetting(FS) manager.InitManager() cron.InitCron() routersInit := routers.InitRouter() readTimeout := setting.ServerSetting.ReadTimeout writeTimeout := setting.ServerSetting.WriteTimeout endPoint := fmt.Sprintf(":%d", setting.ServerSetting.HttpPort) maxHeaderBytes := 1 <p><code>setting.go</code>文件:</p><pre class="brush:php;toolbar:false">func InitSetting(FS embed.FS) { // 总配置处理 var err error data, err := FS.ReadFile(".env") if err != nil { log.Fatalf("Fail to parse '.env': %v", err) } cfg, err = ini.Load(data) if err != nil { log.Fatal(err) } mapTo("server", ServerSetting) ServerSetting.ReadTimeout = ServerSetting.ReadTimeout * time.Second ServerSetting.WriteTimeout = ServerSetting.WriteTimeout * time.Second // 分版本配置引入 v1d0Setting.InitSetting(FS)}
以上が埋め込みとは何ですか? Go は静的ファイルをロードするためにそれをどのように使用しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

goisastrongchoiceforprojectsingingingimplicity、andconcurrency、butmaylackinadvencedecosystemmaturity.1)

go'sinit functionandjava'sstaticInitializerserserservetosetupenmentseforeThemainfunction、buttheydifferinexecution andcontrol.go'sinitissimpleandpleandpleandautomatic、suftable forbasicasiccicsiccicsiccicsicciscicsupsupsbutsbutcanleadeadcoMplecticaticifoverseforedifuredifuredifuredifuredifuredifuredifuredifuredifuredifuredifured

fortheInit functioningoareの場合:1)configurationfilesbemainprogramstarts、2)初期化Globalvariables、および3)running-checksSorvalidationseforetheprogramprocutess.theinitistomationaledemainforeThemainfunction、Makin

cannelsElcialing of renablingsefientive communication betweengoroutines

GOでは、エラーをラップし、エラーを介してコンテキストを追加できます。 1)エラーパッケージの新機能を使用して、エラーの伝播中にコンテキスト情報を追加できます。 2)fmt.errorfおよび%wを介してエラーをラッピングして問題を見つけるのを手伝ってください。 3)カスタムエラータイプは、より多くのセマンティックエラーを作成し、エラー処理の表現力を高めることができます。

goooffersbustfeaturesforsecurecoding、butdevelopersmustimplementsecuritybestpracticive.1)usego'scryptageforsecuredathing.2)surncurrencywithranciationwithranizationprimitivestopreventraceconditions.3)sanitexe zeexerinputeterinpuptoravoidsqlinj

Goのエラーインターフェイスは、TypeErrorInterface {error()String}として定義され、エラー()メソッドを実装する任意のタイプをエラーと見なすことができます。使用の手順は次のとおりです。1。iferr!= nil {log.printf( "anerroroccurred:%v"、err)return}などのエラーを基本的にチェックおよびログエラー。 2。TypeMyErrorStruct {MSGSTRINGDETAILSTRING}などのより多くの情報を提供するカスタムエラータイプを作成します。 3.エラーラッパー(GO1.13以降)を使用して、元のエラーメッセージを失うことなくコンテキストを追加する、

Effectivitive Handleerrorsinconconconcurentgoprograms、usechannelstocommunicateerrors、Implienterrorwatchers、Sunidertimeouts、usebufferedchannels、およびprovideclearerrormess.1)usechannelstopasserrors fromgoroutineStothemainctunction.2)Anerrorwatcherを実装します


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

PhpStorm Mac バージョン
最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

VSCode Windows 64 ビットのダウンロード
Microsoft によって発売された無料で強力な IDE エディター

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

ドリームウィーバー CS6
ビジュアル Web 開発ツール

ホットトピック









