I'm starting with golang and I'm trying to save some text into a file with os.WriteFile function.
When I'm saving it into a file with .txt file I get access denied error:
err := os.WriteFile("tex3.txt", []byte("text text text"), 0644)
if err != nil {
panic(err)
}
When I'm saving it into a file without the text extension - it works fine:
err := os.WriteFile("textFile", []byte("text text text"), 0644)
if err != nil {
panic(err)
}
I have tried the example from the os documentation of Mkdir (unrelated, but it has .txt file extension). The code was:
err := os.Mkdir("testdir", 0750)
if err != nil && !os.IsExist(err) {
panic(err)
}
err = os.WriteFile("testdir/testfile.txt", []byte("Hello, Gophers!"), 0660)
if err != nil {
panic(err)
}
It had no problems creating the folder, but I got access denied again for the text file.
I'm working with vscode. I've tried to open it in admin permissions, I've tried to run it with powershell and with gitbash. I've tried to create the file in and out of folders.
If it's a .txt extension I always get the access denied error. Without the extension it works.
How can I save to a text file using the os.WriteFile function?
Related
I write a golang program in Windows which remove old file then create new file. New file has same name as old file.
if err := os.Remove("abc.txt"); err != nil {
return err
}
file, err := os.OpenFile("abc.txt", os.O_EXCL|os.O_CREATE, 0600)
if err != nil {
return err
}
But I got error
OpenFile error, myfile is exist
When I check abc.txt is still the old file
The os.O_EXCL flag is used to ensure that the file does not already exist, so this error is expected when the file already exists.
To resolve this issue, you can try removing the os.O_EXCL flag and change the permissions to allow writing to the file:
Here is the corresponding code:
if err := os.Remove("abc.txt"); err != nil {
return err
}
file, err := os.OpenFile("abc.txt", os.O_CREATE|os.O_WRONLY, 0600)
if err != nil {
return err
}
This will remove the old abc.txt file and create a new file with the same name, allowing you to write to the file.
I tried downloading an Excel file from a URL using http/net by calling the GET method. I don't know if this is releveant, but as for my case, I use dropbox to store the file on the cloud (it's open for public, not restricted, it can be accessed on incognito).
But when I open the file that's saved on the local, it has no content at all. It has just an empty sheet. The file is supposed to have filled with lots of data in cell.
What's happening here? Anyone knows how to solve it? There's no error at all when I print it.
func main() {
filePath := "./file/filename.xlsx"
url := "http://www.dropbox.com/somethingsomething.xlsx"
out, err := os.Create(filePath)
if err != nil {
fmt.Println(err)
}
defer out.Close()
resp, err := http.Get(url)
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
_, err = io.Copy(out, resp.Body)
if err != nil {
fmt.Println(err)
}
return
}
Does the dropbox URL have dl=0 query param?
If so, try changing it to dl=1 to force download the file.
I tried the same with one of my files and it worked.
Thanks!
I am trying to put images into a specific folder in Golang. Here is the code below.
This is the function where I create a folder called photos in the root directory.
func createPhotoFolder(folderName string) {
err := os.Mkdir(folderName, 777)
if err != nil {
fmt.Println("Error creating folder: ", err)
return
}
fmt.Println(folderName, " created successfully in the root directory")
}
This is the function where I make get request to fetch image and try to put them into a photos folder I created earlier.
func downloadImages(urls []string) {
for i, url := range urls {
resp, err := http.Get(url)
fmt.Printf("%d inside for loop\n", i)
if err != nil {
log.Fatal("error fetching image: ", err)
}
defer resp.Body.Close()
out, err := os.Create("photos")
if err != nil {
log.Printf("Can't put image into folder: ", err)
}
defer out.Close()
}
}
This is the error I get when I run the program.
1- If the folder name is written in this way os.Create("photos") without forwardslash I get the error message as below.
Can't put image into folder: %!(EXTRA *fs.PathError=open photos: is a directory)
2- If I write it like os.Create("/photos"). I get the error as below.
Can't put image into folder: %!(EXTRA *fs.PathError=open /photos: read-only file system)
I gave all the permission while creating the photos folder in the way of chmod.
I did try using io.Copy() but it requires a file parameter which I don't get while creating one using os.Create()
How should I create the folder and put the images inside it properly?
Here, in your code, in os.Create, it should have the complete address of the file to be created along with the name of the file to be created. Like:
gopath := "C:/Users/<username>/go/src/photos/" //where photos is the folder you created
filename := "photo1.jpg"
out, err := os.Create(gopath + filename)
Also, as #steven-penny gave in his answer, create a filename from the image name directly from the url. So that you don't have to give the filename for each image you download.
out, err := os.create(gopath + filepath.Base(link))
And save the image to your system with,
out.Readfrom(resp.Body)
Here is a small program that does what I think you are trying to do:
package main
import (
"net/http"
"os"
"path/filepath"
)
func downloadImages(links []string) error {
tmp := os.TempDir()
for _, link := range links {
println(link)
res, err := http.Get(link)
if err != nil { return err }
defer res.Body.Close()
file, err := os.Create(filepath.Join(tmp, filepath.Base(link)))
if err != nil { return err }
defer file.Close()
file.ReadFrom(res.Body)
}
return nil
}
func main() {
links := []string{
"http://cdn.sstatic.net/Sites/stackoverflow/Img/apple-touch-icon.png",
"http://cdn.sstatic.net/Sites/stackoverflow/Img/favicon.ico",
}
err := downloadImages(links)
if err != nil {
panic(err)
}
}
You'll want to modify it, as you were using a different directory, but it should get you started.
https://golang.org/pkg/os#File.ReadFrom
I recently started working with Go and ran into a small problem. Below is my code for saving a file into the "./images" directory. While the code works and the files are being saved into "./images", the file is also being saved into the root directory of the project simultaneously. TL;DR: File is being saved twice (into root, as well as target) when it should only be saved once in the target directory
// Save
imageSave, err := os.Open(imageOutput.Name())
if err != nil {
log.Fatal(err)
}
defer imageSave.Close()
dir := "./images"
dst, err := os.Create(filepath.Join(dir, filepath.Base(imageOutput.Name())))
if err != nil {
log.Fatal(err)
}
defer dst.Close()
defer imageOutput.Close()
_, err = io.Copy(dst, imageSave)
if err != nil {
log.Fatal(err)
}
Any help is appreciated!
I am trying to upload a product feed to a Google Merchant SFTP account. I am able to upload a file manually through the command prompt but encounter the following error when trying to do it through Go.
Error: sftp: "User does not have appropriate read permission." (SSH_FX_PERMISSION_DENIED)
I am using the github.com/pkg/sftp package, following the example in https://godoc.org/github.com/pkg/sftp#Client.Open. I suspect that the Create/Write pattern here ends up being different from a simple put from command line.
Code
func (g *GoogleExporter) ExportToSFTP(file []byte) error {
// Creating an SSH connection
sshConfig := &ssh.ClientConfig{
User: g.Creds.AccessData.SFTPUser,
Auth: []ssh.AuthMethod{
ssh.Password(g.Creds.AccessData.SFTPPassword),
},
}
hostPort := fmt.Sprintf("%s:%d", SFTPHostName, SFTPHostPort)
connection, err := ssh.Dial("tcp", hostPort, sshConfig)
if err != nil {
return err
}
fmt.Println(">> SSH Connection Created!")
// Creating an SFPT connection over SSH
sftp, err := sftp.NewClient(connection)
if err != nil {
return err
}
defer sftp.Close()
fmt.Println(">> SFTP Client Created!")
// Uploading the file
remoteFileName := "products.xml" // TODO: Make this name configurable
remoteFile, err := sftp.Create(remoteFileName)
if err != nil {
return err
}
fmt.Println(">> SFTP File Created!")
if _, err := remoteFile.Write(file); err != nil {
return err
}
fmt.Println("Successfully uploaded product feed to SFTP, file:%s user:%s", remoteFileName, g.Creds.AccessData.SFTPUser)
util.Log("Successfully uploaded product feed to SFTP, file:%s user:%s", remoteFileName, g.Creds.AccessData.SFTPUser)
// Confirming if the file is there
if _, err := sftp.Lstat(remoteFileName); err != nil {
return err
}
return nil
}
The error is cause by this line:
remoteFile, err := sftp.Create(remoteFileName)
I am answering my own question to help anyone else that is having this problem. I was able to find a solution.
The Google Merchant SFTP account only gives you write only access. However, according to the docs, when using the sftp.Create(..) function, it creates a file with the flags as 0666, which does not agree with the permissions set on your user.
To mimic the behavior of sftp.Create(..) with write only permissions, you can use the more general sftp.OpenFile(..) function.
remoteFile, err := sftp.OpenFile(fileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC)
The flags os.O_WRONLY|os.O_CREATE|os.O_TRUNC will mimic the behavior of Create() i.e. create a file it doesn't exist and truncate the file if it does.