I am trying to write in newly generated file in a specific attached volume to my container (a directory)
however i am not sure about the correct the syntax. Below my code:
// Write the certificates to disk
f, _ := os.Create(filepath.Join("/data/certs/", "chamscertificate.pem"))
f.Write(cert)
f.Close()
f, _ = os.Create("key.pem")
f.Write(key)
f.Close()
}
when executing "go run .", i get the "key.pem" but not the "certificate.pem".
You don't check for errors. If the file wasn't created, the information about why the file wasn't created will be in the error return value from os.Create.
f, err := os.Create(filepath.Join("/data/certs/", "chamscertificate.pem"))
if err != nil {
log.Fatal(err)
}
... etc.
Note that f.Write and f.Close also return errors that should be checked.
Related
When I lock a file path with flock then check the file existence it return no error even though there is no file in that path. The code follows:
filePath := filepath.Join(r.path, fmt.Sprintf("%s_event.json", eventId))
fileLock := flock.New(filePath)
fileLock.Lock()
defer fileLock.Close()
_, err = os.Stat(filePath)
if err != nil {
if os.IsNotExist(errs) {
return event, EventNotFound{}
}
return
}
But when at first check the Stat then lock the file it works. I need to check it before that. Every idea is welcome!
I have a 7z archive of a number of .txt files. I am trying to list all the files in the archive and upload them to an s3 bucket. But I'm having trouble with extracting .7z archives on Go. To do this, I found a package github.com/gen2brain/go-unarr (imported as extractor) and this is what I have so far
content, err := ioutil.ReadFile("sample_archive.7z")
if err != nil {
fmt.Printf("err: %+v", err)
}
a, err := extractor.NewArchiveFromMemory(content)
if err != nil {
fmt.Printf("err: %+v", err)
}
lst, _ := a.List()
fmt.Printf("lst: %+v", last)
This prints a list of all the files in the archive. But this has two issues.
It reads files from local using ioutil and the input of NewArchiveFromMemory must be of type []byte. But I can't read from local and will have to use a file from memory of type os.file. So I will either have to find a different method or convert the os.file to []byte. There's another method NewArchiveFromReader(r io.Reader). But this is returning an error saying Bad File Descriptor.
file, err := os.OpenFile(
path,
os.O_WRONLY|os.O_TRUNC|os.O_CREATE,
0666,
)
a, err := extractor.NewArchiveFromReader(file)
if err != nil {
fmt.Printf("ERROR: %+v", err)
}
lst, _ := a.List()
fmt.Printf("files: %+v\n", lst)
I am able to get the list of the files in the archive. And using Extract(destinaltion_path string), I can also extract it to a local directory. But I want the extracted files also in os.file format ( ie. a list of os.file since there will be multiple files ).
How can I change my current code to achieve both the above targets? Is there any other library to do this?
os.File implements the io.Reader interface (because it has a Read([]byte) (int, error) method defined), so you can use NewArchiveFromReader(file) without any conversions needed. You can read up on Go interfaces for more background on why that works.
If you're okay with extracting to a local directory, you can do that and then read the files back in (warning, may contain typos):
func extractAndOpenAll(*extractor.Archive) ([]*os.File, error) {
err := a.Extract("/tmp/path") // consider using ioutil.TempDir()
if err != nil {
return nil, err
}
filestats, err := ioutil.ReadDir("/tmp/path")
if err != nil {
return nil, err
}
# warning: all these file handles must be closed by the caller,
# which is why even the error case here returns the list of files.
# if you forget, your process might leak file handles.
files := make([]*os.File, 0)
for _, fs := range(filestats) {
file, err := os.Open(fs.Name())
if err != nil {
return files, err
}
files = append(files, file)
}
return files, nil
}
It is possible to use the archived files without writing back to disk (https://github.com/gen2brain/go-unarr#read-all-entries-from-archive), but whether or not you should do that instead depends on what your next step is.
I have the following piece of code which creates an output file on a local drive and required to do the same on a network mapped drive let's call it [H:].
The file name (full path name) entered from command line as argument[1].
I am using Windows 10/Server 2016
// The following will create and append to the file when required.
sourcefile, errf := os.OpenFile(os.Args[1], s.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)
if erro != nil {
panic(erro)
}
defer outfile.Close()
I use the following function to write a map into this file.
func map2Linpro(inp map[string][]string, outfile io.Writer) {
for k, v := range inp {
_, err := fmt.Fprintf(outfile, "%s %s=%s %s\n", v[0], k, v[1], v[2])
if err != nil {
fmt.Println("Error Writing to File: ", err)
}
}
}
Everything is working just fine if the output file is on the local Drive, but when using full path with the Mapped Drive letter, I received the following error:
Error: write h://00_sc//dest01.txt: The parameter is incorrect.
I searched for any reason, but could not find one.
I would appreciate if someone help
The following is the Error I got after adding Panic(erro) after OpenFile.
Which proves that the error source is fmt.Fprintf
Error Writing to File: write H:/00_sc/dest01.txt: The parameter is incorrect.
Thanks to all.
outfile, _ := os.OpenFile(os.Args[2], os.O_CREATE|os.O_APPEND, 0666)
should read
outfile, err := os.OpenFile(os.Args[2], os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
panic(err)
}
rewrite those lines and the resulting error message should give a clue as to the cause
I could read the file after using functions Open() or OpenFile(path, os.O_RDONLY), but I could not remove the file after it. So I tried to open the file with the write flag os.RDWR like below code to see if I can remove the file. However, using os.RDWR I couldn't even read the file. Could anyone explain it to me the reason why it would lead to this issue? I have got the error sftp: "Permission denied" (SSH_FX_PERMISSION_DENIED)
I have tried to see the permission code of the file, the file is -rwxrwxrwx.
import (github.com/pkg/sftp)
config = sftp.NewConfig(nil)
config.SetAcct("xxxxx","xxxxx")
config.SetDes("ip address", 1234)
config.Connect()
if file, err = config.Client.OpenFile(path, os.O_RDWR); err != nil {
log.Println("Cannot open "+path+" , err:", err)
}
if _, err = ioutil.ReadAll(file); err != nil {
log.Println("Cannot read "+path+", err:", err)
}
file.Close()
err = config.Client.Remove(file)
if err != nil {
log.Println("cannot remove file)
}
Problem solved:
found out that I had opened the file without closing it. And somehow the file is still opened by FreeSSHDService. That's why I could not remove the file.
You have to provide the file path instead you have provided file handler.
config.Client.Remove(pathTofile)
defer file.close()
Here is the reference https://godoc.org/github.com/pkg/sftp#Client.Remove
I am using golang revel web framework and
I am trying to create a sqlite db in the current working directory.
model.go
func New(dbName string,table string) *Db {
_,filename,_,_ := runtime.Caller(1)
db , err := sql.Open("sqlite3",path.Join(path.Dir(filename),dbName))
if err != nil {
log.Fatal(err)
}
err = db.Ping()
if err != nil {
log.Panic(err)
}
database := &Db{Database:db}
_,err = db.Exec("create table %s" +
"( id integer primary key, " +
"name varchar(100),"+
"email varchar(100),"+
"branch varchar(100),"+
"help varchar(100)",)
if err != nil {
log.Fatal(err)
}
}
I have a test in place which just calls this function.
whenever i run the test using revel test or by going to the localhost:9000/#tests, the function Panics and the error message is
cannot open the database file.
The reason that is happening is because the filename returned by runtime.Caller(1) is /usr/local/go/src/runtime/asm_amd64.s for which the program has no permission.
if i directly write ./foo.db, even then the error shows.
I tried os.Getwd() which return empty string.
I also tried filepath.Abs(filepath.Dir(os.Args[0]))
but that returned /home/girish/GoProjects/bin/revel.d which is the revel binary.
So whats the best way to find the directory of the model.go?
It doesn't make sense to get the directory of the model.go file at runtime, because the compiled executable could be on a completely different filesystem.
You may want to get the directory of where the running executable was started from:
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
dir will be the folder where the program lives at runtime.