How to add images into specific folder in Go? Getting error like: `%!(EXTRA *fs.PathError=open /photos: read-only file system)`

huangapple go评论82阅读模式
英文:

How to add images into specific folder in Go? Getting error like: `%!(EXTRA *fs.PathError=open /photos: read-only file system)`

问题

我正在尝试将图像放入Golang中的特定文件夹。以下是代码示例。

这是一个函数,用于在根目录中创建名为photos的文件夹。

func createPhotoFolder(folderName string) {
	err := os.Mkdir(folderName, 0777)
	if err != nil {
		fmt.Println("创建文件夹时出错:", err)
		return
	}
	fmt.Println(folderName, "成功创建在根目录中")
}

这是一个函数,用于发送GET请求以获取图像,并尝试将它们放入之前创建的photos文件夹中。

func downloadImages(urls []string) {
	for i, url := range urls {
		resp, err := http.Get(url)
		fmt.Printf("%d 在循环中\n", i)
		if err != nil {
			log.Fatal("获取图像时出错:", err)
		}
		defer resp.Body.Close()
		out, err := os.Create("photos/" + strconv.Itoa(i) + ".jpg")
		if err != nil {
			log.Printf("无法将图像放入文件夹中:", err)
		}
		defer out.Close()
	}
}

当我运行程序时,我遇到了以下错误:

1- 如果文件夹名称以os.Create("photos")的方式编写,没有斜杠,我会收到以下错误消息。

无法将图像放入文件夹中:%!(EXTRA *fs.PathError=open photos: is a directory)

2- 如果我将其编写为os.Create("/photos"),我会收到以下错误。

无法将图像放入文件夹中:%!(EXTRA *fs.PathError=open /photos: read-only file system)

在创建photos文件夹时,我已经给予了所有权限,使用了chmod命令。我尝试使用io.Copy(),但它需要一个文件参数,而使用os.Create()创建的文件参数我无法获取。

请问我应该如何正确创建文件夹并将图像放入其中?

英文:

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?

答案1

得分: 1

在你的代码中,os.Create应该包含要创建的文件的完整地址以及要创建的文件的名称。例如:

gopath := "C:/Users/<username>/go/src/photos/" //其中photos是你创建的文件夹
filename := "photo1.jpg"

out, err := os.Create(gopath + filename)

此外,正如@steven-penny在他的答案中提到的,可以直接从URL中创建图像名称。这样,你就不需要为每个要下载的图像提供文件名。

out, err := os.Create(gopath + filepath.Base(link))

然后,使用以下代码将图像保存到你的系统中:

out.ReadFrom(resp.Body)
英文:

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 := &quot;C:/Users/&lt;username&gt;/go/src/photos/&quot; //where photos is the folder you created 
filename := &quot;photo1.jpg&quot;

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)

答案2

得分: 0

这是一个小程序,它实现了我认为你想要做的事情:

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)
   }
}

你需要根据自己的需求进行修改,因为你使用的是不同的目录,但这个程序可以帮助你入门。

https://golang.org/pkg/os#File.ReadFrom

英文:

Here is a small program that does what I think you are trying to do:

package main

import (
   &quot;net/http&quot;
   &quot;os&quot;
   &quot;path/filepath&quot;
)

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{
      &quot;http://cdn.sstatic.net/Sites/stackoverflow/Img/apple-touch-icon.png&quot;,
      &quot;http://cdn.sstatic.net/Sites/stackoverflow/Img/favicon.ico&quot;,
   }
   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

huangapple
  • 本文由 发表于 2021年6月8日 03:06:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/67877409.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定