Comment puis-je ouvrir des fichiers par rapport à mon GOPATH?
Je suis en utilisant io/ioutil
de lire un petit fichier texte:
fileBytes, err := ioutil.ReadFile("/absolute/path/to/file.txt")
Et qui fonctionne très bien, mais ce n'est pas exactement le portable. Dans mon cas, les fichiers que je veux ouvrir sont à mon GOPATH, par exemple:
/Users/matt/Dev/go/src/github.com/mholt/mypackage/data/file.txt
Depuis le data
dossier promenades droit à côté du code source, j'aimerais juste préciser le chemin d'accès relatif:
data/file.txt
Mais ensuite, j'obtiens cette erreur:
de panique: ouvert data/file.txt: aucun fichier ou répertoire de
Comment puis-je ouvrir des fichiers à l'aide de leur chemin d'accès relatif, surtout s'ils vivent à côté de mon code?
(Remarque que ma question est plus précisément sur l'ouverture de fichiers par rapport à la GOPATH. Ouverture de fichiers en utilisant un chemin relatif dans le jeu de Go est aussi facile que de donner le chemin d'accès relatif au lieu d'un chemin d'accès absolu; les fichiers sont ouverts par rapport à la binaire compilé répertoire de travail. Dans mon cas, je veux ouvrir les fichiers par rapport à l'endroit où le binaire a été compilé. Avec le recul, c'est une mauvaise décision de conception.)
- Le GOPATH n'a pas un grand sens une fois que votre programme est compilé, et encore moins quand vous le distribuer.
- Ce que vous semblez vouloir ressemble plus à certains intégration des fichiers dans votre programme compilé.
- Une sorte de... sauf que je veux les fichiers de données distinct de la source. Les fichiers de données sont vitales pour les fonctionnalités du programme. Donc quand quelqu'un tire vers le bas de mon code source (avec les fichiers de données le long de côté) et compile et s'exécute, les fichiers de données sont chargées à l'aide d'un chemin d'accès relatif, car ils existent à proximité de la source code, ou près de l'endroit où le programme est en cours d'exécution.
- Le binaire compilé devrait avoir aucune dépendance sur l'emplacement des fichiers source, mais ce serait bien si il y avait un moyen de créer un exécutable bundle qui contient une copie des ressources externes sur les paquets peuvent dépendre.
- Ça sonne bien pour moi... je suis un peu nouveau pour Aller, et mon approche typique pour cela (comme Python ou PHP) est de regrouper les fichiers de données avec le code source et de référence relativement. Donc, pour Aller, ma vraie question pourrait être: comment puis-je accéder à ces ressources externes? (Si elles sont manquantes, bien sûr, j'avais d'agir en conséquence.)
- c'est que ce fileembed-aller ne? (bitbucket.org/rj/fileembed-go)
- Voici une question connexe sur le regroupement des ressources qui peut être suffisant, mais ce n'est pas ma méthode de prédilection dans mon cas: stackoverflow.com/questions/13904441/... - ou celui-ci: stackoverflow.com/q/9443418/1048862
Vous devez vous connecter pour publier un commentaire.
Hmm... le
path/filepath
paquet aAbs()
qui fait ce dont j'ai besoin (pour l'instant) mais c'est un peu gênant:Puis-je utiliser
absPath
pour charger le fichier et il fonctionne très bien.Noter que, dans mon cas, les fichiers de données sont dans un paquet séparé de la
main
paquet dont je suis l'exécution du programme. Si c'était tous dans le même paquet, je voudrais retirer le premier../mypackage/
. Depuis ce chemin est évidemment relative, des programmes différents ont des structures différentes et ont besoin de cette ajusté en conséquence.Si il ya une meilleure façon d'utiliser les ressources externes avec un programme de Go et de le garder portable, n'hésitez pas à apporter une autre réponse.
ioutil.ReadFile
fonctionne correctement, mais il est complètement inutile. Cela fonctionne bien:ioutil.ReadFile("../mypackage/data/file.txt")
. Il y a probablement de nombreux autres cas où vous souhaitez construire un chemin d'accès absolu, mais il semble utiliser avecio.ReadFile
n'est pas l'un d'eux.cela semble fonctionner assez bien:
import "path/filepath"
et appelfilepath.Join(...)
(avec capitalJ
). 🙂os.Open(pwd + "../mocks/product/default.json")
comment gérez-vous cette affaire? c'est de prendre ce que littérale.J'ai écrit gobundle pour résoudre ce problème. Il génère Aller le code source à partir de fichiers de données, ce qui permet ensuite de compiler dans votre binaire. Vous pouvez ensuite accéder au fichier de données par le biais d'un VFS-couche. Il est complètement portable, prend en charge l'ajout de fichier complet des arbres, compression, etc.
L'inconvénient est que vous avez besoin d'une étape intermédiaire pour construire le Go de fichiers à partir de la source de données. J'ai l'habitude de faire pour cela.
Voici comment vous pouvez itérer sur tous les fichiers dans un bundle, la lecture des octets:
Vous pouvez voir un exemple de son utilisation dans mon GeoIP paquet. Le
Makefile
génère le code, etgeoip.aller
utilise le VFS.Je pense que Alec Thomas a fourni La Réponse, mais dans mon expérience, il n'est pas infaillible. Un problème que j'avais avec la compilation de ressources, en binaire, c'est que la compilation peut prendre beaucoup de mémoire selon la taille de vos actifs. Si ils sont petits, alors il est probablement rien à craindre. Dans mon scénario particulier, un 1 MO fichier de police était à l'origine de la compilation d'exiger quelque part autour de 1 GO de mémoire pour compiler. C'était un problème parce que je voulais aller gettable sur un Raspberry Pi. C'était au rendez-vous 1.0; les choses ont peut-être amélioré en Aller 1.1.
Donc, dans ce cas particulier, j'opte pour juste utiliser le
go/build
paquet de trouver le répertoire source du programme fondé sur le chemin d'importation. Bien sûr, cela nécessite que vos objectifs ont unGOPATH
établi et que la source est disponible. Il n'est donc pas une solution idéale dans tous les cas.