GoLang:更新由FileServer提供的文件

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

GoLang: Update file that is served by FileServer

问题

我正在使用FileServer来提供一个目录,代码如下所示:

go func() {
  fs := http.FileServer(http.Dir("./view"))
  err := http.ListenAndServe(":8000", fs)
  if err != nil {
    log.Fatal("ListenAndServe: ", err)
  }
}()

view目录中,我有一个index.html文件,我正在尝试在提供view目录的同时更新该文件。我观察到追加命令会阻塞,并且只有在停止提供目录后才会更新文件。

以下是修改文件的代码:

func AppendToFile() {
  f, err := os.OpenFile("./view/index.html", os.O_RDWR, 0644)
  if err != nil {
    panic(err)
  }
  defer f.Close()
  // 这假设文件以</body></html>结尾
  f.Seek(-15, 2)
  if _, err = f.WriteString("test test test\n"); err != nil {
    panic(err)
  }
  if _, err = f.WriteString("</body></html>\n"); err != nil {
    panic(err)
  }
}

这是预期的行为吗?

谢谢!

英文:

I am serving a directory using FileServer as follows:

go func() {
  fs := http.FileServer(http.Dir(&quot;./view&quot;))
  err := http.ListenAndServe(&quot;:8000&quot;, fs)
  if err != nil {
    log.Fatal(&quot;ListenAndServe: &quot;, err)
  }
}()

Inside the view directory I have an index.html file, which I am trying to update while the view directory is being served. I observe that the append commands block and update the file only after I stop serving the directory.

Below is the code to modify the file:

func AppendToFile() {
  f, err := os.OpenFile(&quot;./view/index.html&quot;, os.O_RDWR, 0644)
  if err != nil {
    panic(err)
  }
  defer f.Close()
  // This assumes that the file ends with &lt;/body&gt;&lt;/html&gt;
  f.Seek(-15, 2)
  if _, err = f.WriteString(&quot;test test test\n&quot;); err != nil {
    panic(err)
  }
  if _, err = f.WriteString(&quot;&lt;/body&gt;&lt;/html&gt;\n&quot;); err != nil {
    panic(err)
  }
}

Is this the expected behavior?

Thank you!

答案1

得分: 3

http.FileServer函数只返回一个处理程序,所以它不会阻塞文件系统。
这里的问题可能与文件的偏移量有关。我在我的机器上尝试过,没有任何问题。

我已经修改了你的代码如下:

package main

import (
	"net/http"
	"os"
	"time"
)

func main() {
	t := time.NewTicker(time.Second)
	defer t.Stop()
	go func() {
		srv := http.FileServer(http.Dir("./test"))
		http.ListenAndServe(":8080", srv)
	}()

	for {
		select {
		case <-t.C:
			appendToFile()
		}
	}
}

func appendToFile() {
	f, err := os.OpenFile("./test/index.html", os.O_RDWR, 0644)
	if err != nil {
		panic(err)
	}
	defer f.Close()
	// 这里假设文件以</body></html>结尾
	f.Seek(-16, 2)
	if _, err = f.WriteString("test test test\n"); err != nil {
		panic(err)
	}
	if _, err = f.WriteString("</body></html>\n"); err != nil {
		panic(err)
	}
}

在index.html中,我最初放了一个空白文档:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

</body></html>

PS:最好先检查的偏移量,然后将字符串写入该位置。

英文:

http.FileServer function just returns a handler. So it is not blocking the filesystem.
The problem in here might be related with the offset of your file. I've tried in my machine and it worked without any problem.

I've modified your code to this;

package main

import (
	&quot;net/http&quot;
	&quot;os&quot;
	&quot;time&quot;
)

func main() {
	t := time.NewTicker(time.Second)
    defer t.Stop()
	go func() {
		srv := http.FileServer(http.Dir(&quot;./test&quot;))
		http.ListenAndServe(&quot;:8080&quot;, srv)
	}()

	for {
		select {
		case &lt;-t.C:
			appendToFile()
		}
	}
}

func appendToFile() {
	f, err := os.OpenFile(&quot;./test/index.html&quot;, os.O_RDWR, 0644)
	if err != nil {
		panic(err)
	}
	defer f.Close()
	// This assumes that the file ends with &lt;/body&gt;&lt;/html&gt;
	f.Seek(-16, 2)
	if _, err = f.WriteString(&quot;test test test\n&quot;); err != nil {
		panic(err)
	}
	if _, err = f.WriteString(&quot;&lt;/body&gt;&lt;/html&gt;\n&quot;); err != nil {
		panic(err)
	}
}

In index.html I put blank document initially,

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;Document&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;/body&gt;&lt;/html&gt;

PS: It is better to check offset of </body></html> first, then write the string to that position.

huangapple
  • 本文由 发表于 2021年9月22日 02:56:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/69274214.html
匿名

发表评论

匿名网友

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

确定