Wie kann ich Dateien öffnen, die relativ zu meinem GOPATH?
Ich bin mit io/ioutil
zu Lesen, eine kleine text-Datei:
fileBytes, err := ioutil.ReadFile("/absolute/path/to/file.txt")
Und das funktioniert auch, aber dies ist nicht wirklich tragbar. In meinem Fall, die Dateien, die ich öffnen will sind in meinem GOPATH, zum Beispiel:
/Users/matt/Dev/go/src/github.com/mholt/mypackage/data/file.txt
Da die data
Ordner fährt direkt neben dem source-code, ich würde gerne geben Sie nur den relativen Pfad:
data/file.txt
Aber dann bekomme ich diesen Fehler:
Panik: öffnen data/file.txt: no such file or directory
Wie kann ich das öffnen von Dateien mit Ihrem relativen Pfad, vor allem, wenn Sie Leben neben meinem Go-code?
(Hinweis, dass meine Frage ist speziell zum öffnen von Dateien relativ zum GOPATH. Öffnen von Dateien mit beliebigen relativen Pfad in Go ist so einfach wie geben Sie den relativen Pfad statt einem absoluten Pfad; Dateien geöffnet sind, relativ zu den kompilierten binären Arbeitsverzeichnis. In meinem Fall, ich wollen, um Dateien zu öffnen, relativ zu dem die binary kompiliert wurde. Im Nachhinein ist dies eine schlechte design-Entscheidung.)
- Die GOPATH hat keine große Bedeutung, sobald Ihr Programm wird kompiliert, und noch weniger, wenn Sie es zu verteilen.
- Was Sie scheinen zu wollen, sieht eher aus wie etwas das einbetten von Dateien in die kompilierte Programm.
- Art... außer ich will die Dateien von der Quelle getrennt. Die Dateien sind entscheidend für die Funktionalität des Programms. Wenn also jemand nach unten zieht mein source-code (mit den Daten-Dateien an der Seite) und kompiliert und es läuft, die Daten-Dateien geladen werden, über einen relativen Pfad, denn Sie existieren in der Nähe der source-code, oder in der Nähe, wo das Programm ausgeführt wird.
- Die den kompilierten binären sollte keine Abhängigkeit von der Lage der Quell-Dateien, aber es wäre schön, wenn es war ein Weg, um erstellen Sie eine ausführbare Datei bündeln, die eine Kopie von externen Ressourcen, auf welche Pakete abhängen können.
- Klingt gut für mich... ich bin etwas neues zu Gehen, und meine typische Herangehensweise an dieses (wie Python oder PHP) ist die Bündelung der Daten-Dateien mit dem source-code und verweisen Sie relativ. So zum Gehen, meine eigentliche Frage wäre: wie bekomme ich Zugang zu diesen externen Ressourcen? (Wenn Sie fehlen, natürlich würd ich handle auch entsprechend.)
- ist es das, was fileembed-gehen tut das schon? (bitbucket.org/rj/fileembed-go)
- Hier ist eine Frage über die Bündelung von Ressourcen, die ausreichen, obwohl dies nicht meine bevorzugte Methode in meinem Fall: stackoverflow.com/questions/13904441/... - oder dieses: stackoverflow.com/q/9443418/1048862
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hmm... die
path/filepath
Paket hatAbs()
die tut, was ich brauche (bisher), obwohl es ein bisschen umständlich:Dann benutze ich
absPath
um die Datei zu laden und es funktioniert gut.Beachten Sie, dass, in meinem Fall, die Daten-Dateien in einem Paket getrennt von der
main
Paket, von dem ich das Programm laufen lassen. Wenn alle in das gleiche Paket, ich würde entfernen Sie die führenden../mypackage/
. Da dieser Pfad ist natürlich relativ, verschiedene Programme haben unterschiedliche Strukturen und müssen diese entsprechend angepasst.Ob es einen besseren Weg, um die Verwendung von externen Ressourcen mit einem Go-Programm und halten Sie es für tragbar, fühlen Sie sich frei, um beizutragen, eine andere Antwort.
ioutil.ReadFile
um korrekt zu arbeiten, aber es ist völlig unnötige. Dies funktioniert gut:ioutil.ReadFile("../mypackage/data/file.txt")
. Es gibt wahrscheinlich noch viele andere Fälle, wo Sie wollen erstellen Sie einen absoluten Pfad, aber es erscheint die Verwendung mitio.ReadFile
ist nicht einer von Ihnen.dieser scheint ziemlich gut zu funktionieren:
import "path/filepath"
- und call -filepath.Join(...)
(mit der HauptstadtJ
). 🙂os.Open(pwd + "../mocks/product/default.json")
wie gehen Sie mit diesem Fall? es ist unter diesem literal.Schrieb ich gobundle zu lösen genau dieses problem. Es erzeugt Gehen-source-code und Daten-Dateien, die Sie kompilieren in die Binärdatei. Sie können dann auf die Datei zugreifen, Daten über ein VFS-Schicht. Es ist vollständig portabel, unterstützt das hinzufügen ganze Datei-Bäume, Kompression, etc.
Der Nachteil ist, dass Sie brauchen einen Zwischenschritt, um zu bauen, Gehen die Dateien aus den Quell-Daten. Ich verwende in der Regel machen für diese.
Hier ist, wie würden Sie Iteration über alle Dateien in einem bundle, das Lesen der bytes:
Können Sie sehen, ein echtes Beispiel für die Verwendung in meinem GeoIP Paket. Die
Makefile
generiert den code, undgeoip.gehen
verwendet die VFS.Ich denke, Alec Thomas, hat Die Antwort, aber in meiner Erfahrung ist es nicht narrensicher. Ein problem hatte ich mit dem kompilieren von Ressourcen in die binäre ist, dass das kompilieren kann verlangen, eine Menge Speicher, abhängig von der Größe Ihres Vermögens. Wenn Sie klein, dann ist es wahrscheinlich nichts zu befürchten. In meinem speziellen Szenario, ein 1-MB-font-Datei war, die Zusammenstellung zu verlangen, irgendwo rund 1 GB Speicher zu kompilieren. Es war ein problem, weil ich wollte, dass es gehen get erreichbar auf einem Raspberry Pi. Dies war mit Go 1.0; Dinge verbessert haben im Gehen 1.1.
So, in diesem besonderen Fall, ich entscheide mich, nur die
go/build
Paket zu finden, die source-Verzeichnis des Programms basieren auf den import-Pfad. Dies setzt natürlich Voraus, daß Sie Ihre Ziele haben einenGOPATH
einrichten und dass die Quelle verfügbar ist. Es ist also nicht die ideale Lösung in allen Fällen.