Pracuję nad małą aplikacją internetową w Go, która ma być używana jako narzędzie na komputerze dewelopera do pomocy w debugowaniu ich aplikacji / usług internetowych. Interfejs programu to strona internetowa, która zawiera nie tylko HTML, ale także JavaScript (dla funkcjonalności), obrazy i CSS (dla stylizacji). Planuję udostępnienie tej aplikacji na zasadach open source, więc użytkownicy powinni po prostu mieć możliwość uruchomienia pliku Makefile, a wszystkie zasoby zostaną umieszczone tam, gdzie muszą. Chciałbym jednak również móc po prostu dystrybuować plik wykonywalny z jak najmniejszą liczbą plików / zależności. Czy istnieje dobry sposób na dołączenie kodu HTML / CSS / JS do pliku wykonywalnego, tak aby użytkownicy musieli pobrać tylko jeden plik i martwić się o niego?
W tej chwili w mojej aplikacji udostępnianie statycznego pliku wygląda trochę tak:
// 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
}
Jest to więc całkiem proste: jeśli żądany plik istnieje w moim katalogu statycznym, wywołaj procedurę obsługi, która po prostu otwiera plik i próbuje ustawić towar Content-Type
przed podaniem. Pomyślałem, że nie ma powodu, aby było to oparte na prawdziwym systemie plików: gdyby były skompilowane zasoby, mógłbym je po prostu zindeksować przez identyfikator URI żądania i służyć jako takie.
Jeśli nie ma dobrego sposobu na zrobienie tego lub szczekam na niewłaściwe drzewo, próbując to zrobić, daj mi znać. Pomyślałem, że użytkownik końcowy doceniłby jak najmniejszą liczbę plików do zarządzania.
Jeśli są bardziej odpowiednie tagi niż udać się, proszę, dodaj je lub daj mi znać.
go generate
małego narzędzia wiersza poleceń (spakowanego z moim kodem źródłowym) do konwersji plików na[]byte
plasterki, które są osadzone jako zmienne w kodzie, podobnie jakstringer
to się dzieje (patrz blog.golang.org / generuj ).Odpowiedzi:
Wygląda na to, że pakiet go-bindata może być tym, co Cię interesuje.
https://github.com/go-bindata/go-bindata
Umożliwi to przekonwertowanie dowolnego pliku statycznego na wywołanie funkcji, które można osadzić w kodzie, a po wywołaniu zwróci fragment bajtu zawartości pliku.
źródło
Osadzanie plików tekstowych
Jeśli mówimy o plikach tekstowych, można je łatwo osadzić w samym kodzie źródłowym. Po prostu użyj cudzysłowów wstecz, aby zadeklarować
string
literał w następujący sposób:Wskazówka dotycząca optymalizacji:
Ponieważ w większości przypadków wystarczy zapisać zasób do pliku
io.Writer
, możesz również zapisać wynik[]byte
konwersji:Jedyną rzeczą, na którą musisz uważać, jest to, że surowe literały ciągów nie mogą zawierać znaku cudzysłowu (`). Surowe literały ciągów nie mogą zawierać sekwencji (w przeciwieństwie do zinterpretowanych literałów ciągów), więc jeśli tekst, który chcesz osadzić, zawiera cudzysłowy wsteczne, musisz przerwać nieprzetworzony literał ciągu i połączyć cudzysłowy jako zinterpretowane literały ciągów, jak w tym przykładzie:
Nie ma to wpływu na wydajność, ponieważ te konkatenacje będą wykonywane przez kompilator.
Osadzanie plików binarnych
Przechowywanie jako kawałek bajtu
W przypadku plików binarnych (np. Obrazów) najbardziej zwartym (pod względem wynikowego natywnego pliku binarnego) i najbardziej wydajnym byłoby umieszczenie zawartości pliku
[]byte
w kodzie źródłowym. Może to zostać wygenerowane przez zewnętrzne biblioteki toos / biblioteki, takie jak go-bindata .Jeśli nie chcesz do tego używać biblioteki innej firmy, oto prosty fragment kodu, który odczytuje plik binarny i wyświetla kod źródłowy Go, który deklaruje zmienną typu,
[]byte
która zostanie zainicjowana z dokładną zawartością pliku:Przykładowe dane wyjściowe, jeśli plik zawierałby bajty od 0 do 16 (spróbuj w Go Playground ):
Przechowywanie jako base64
string
Jeśli plik nie jest „zbyt duży” (większość obrazów / ikon kwalifikuje się), istnieją również inne przydatne opcje. Możesz przekonwertować zawartość pliku na Base64
string
i zapisać ją w kodzie źródłowym. Podczas uruchamiania aplikacji (func init()
) lub w razie potrzeby możesz zdekodować ją do oryginalnej[]byte
treści. Go ma dobre wsparcie dla kodowania Base64 wencoding/base64
pakiecie.Konwersja pliku (binarnego) do formatu base64
string
jest tak prosta, jak:Przechowuj wynikowy ciąg base64 w swoim kodzie źródłowym, np. Jako plik
const
.Dekodowanie to tylko jedno wywołanie funkcji:
Przechowywanie zgodnie z notowaniem
string
Bardziej wydajne niż przechowywanie jako base64, ale może być dłuższe w kodzie źródłowym, jest przechowywanie cytowanego literału ciągu danych binarnych. Możemy otrzymać cytowaną postać dowolnego ciągu za pomocą
strconv.Quote()
funkcji:W przypadku danych binarnych zawierających wartości od 0 do 64 tak wyglądałoby dane wyjściowe (wypróbuj na Go Playground ):
"\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:;<=>?"
(Zwróć uwagę, że
strconv.Quote()
dołącza i poprzedza cudzysłów).Możesz bezpośrednio użyć tego cytowanego ciągu w swoim kodzie źródłowym, na przykład:
Jest gotowy do użycia, nie trzeba go dekodować; usuwanie cytatów jest wykonywane przez kompilator Go w czasie kompilacji.
Możesz również zapisać go jako fragment bajtu, jeśli potrzebujesz go w ten sposób:
źródło
sh
pliku z plikiem wykonywalnym go?jest też egzotyczny sposób - używam wtyczki maven do budowania projektów GoLang i pozwala ona na użycie preprocesora JCP do osadzania bloków binarnych i plików tekstowych w źródłach. W przypadku kod wygląda jak linia poniżej ( a przykład można znaleźć tutaj )
źródło
sh
plik wykonywalny lub plik wykonywalny jak powyżejsh
plik? Nie wiem co masz na myśli. Jeśli chcesz, aby wszystko w katalogu zostało osadzone, jest to coś, z czym zrobiłemgo-bindata
. Na przykład, jeśli wstawię//go:generate $GOPATH/bin/go-bindata -prefix=data/ -pkg=$GOPACKAGE data/
(nie wygenerowany) plik go,go generate ./...
uruchomię go-bindata w katalogu pakietu, osadzając wszystko w podkatalogu danych, ale z usuniętym prefiksem „data /”.Jako popularna alternatywa dla
go-bindata
wspomnianej w innej odpowiedzi, mjibson / esc również osadza dowolne pliki, ale szczególnie wygodnie obsługuje drzewa katalogów.źródło