ch1/ch1-06 #176
Replies: 10 comments 2 replies
-
练习 1.10,需要在fetch函数中,创建文件,copy时将数据copy到创建的文件中即可 func fetch(url string, ch chan string) {
start := time.Now()
resp, err := http.Get(url)
if err != nil {
ch <- fmt.Sprint(err) // send err to channel
return
}
// 创建文件
out, err := os.Create(url + ".txt")
if err != nil {
ch <- fmt.Sprint(err)
return
}
// nbytes 是拷贝的内容大小
//nbytes, err := io.Copy(ioutil.Discard, resp.Body)
nbytes, err := io.Copy(out, resp.Body)
resp.Body.Close()
if err != nil {
ch <- fmt.Sprintf("while reading %s: %v", url, err)
return
}
secs := time.Since(start).Seconds()
ch <- fmt.Sprintf("%.2fs %7d %s", secs, nbytes, url)
} |
Beta Was this translation helpful? Give feedback.
-
切片url 使保存文件名字为//后 .前 例如 https://godoc.org 保存到文件godoc.txt中 } func findSubstringIndex(str, substr string) int { |
Beta Was this translation helpful? Give feedback.
-
练习1.10
保存到文件后的结果
|
Beta Was this translation helpful? Give feedback.
-
Exercise 1.1package main
import (
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"strings"
"time"
)
const TIMES int = 2
func main() {
fd, err := os.Create("fetch.log")
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
start := time.Now()
ch := make(chan string)
for i := 0; i < TIMES; i++ {
io.WriteString(fd, fmt.Sprintf("---Start fetch for the %d time---\n", i+1))
for _, url := range os.Args[1:] {
go fetch(url, ch)
}
for range os.Args[1:] {
io.WriteString(fd, <-ch)
io.WriteString(fd, "\n")
}
io.WriteString(fd, fmt.Sprintf("%.2fs elapsed\n", time.Since(start).Seconds()))
}
fd.Close()
dirs, err := os.ReadDir("./")
for _, dir := range dirs {
dirname := dir.Name()
if strings.HasSuffix(dirname, ".html") {
os.Remove(dirname)
}
}
}
func fetch(url string, ch chan<- string) {
var full_url string = url
if !strings.HasPrefix(url, "http") {
full_url = "http://" + url
}
start := time.Now()
resp, err := http.Get(full_url)
if err != nil {
ch <- fmt.Sprint(err)
return
}
curSiteContent, err := ioutil.ReadAll(resp.Body)
if err != nil {
ch <- fmt.Sprint(err)
return
}
fileName := url + ".html"
if _, err := os.Stat(fileName); err == nil {
// when file has already exits
fd, _ := os.Open(fileName)
prevSiteContent, _ := ioutil.ReadAll(fd)
if string(prevSiteContent) != string(curSiteContent) {
ch <- url + ": site content has changed"
return
}
}
// save reponse body
fd, err := os.Create(fileName)
if err != nil {
ch <- fmt.Sprint(err)
return
}
nbytes, err := io.WriteString(fd, string(curSiteContent))
resp.Body.Close()
fd.Close()
if err != nil {
ch <- fmt.Sprintf("while reading %s: %v", url, err)
return
}
secs := time.Since(start).Seconds()
ch <- fmt.Sprintf("%.2fs\t%7d\t%s", secs, nbytes, url)
} |
Beta Was this translation helpful? Give feedback.
-
package main
import (
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"strings"
"time"
)
func main() {
start := time.Now()
ch := make(chan string)
file, err := os.OpenFile("./text.txt", os.O_RDWR|os.O_CREATE,0)
if err != nil {
fmt.Printf("open file failed: %s", err)
return
}
for _, url := range os.Args[1:] {
if !strings.HasPrefix("http://", url) {
url = "http://" + url
}
go fetch(url, ch, file)
go fetch(url, ch, file)
}
for range os.Args[1:] {
file.WriteString(<-ch)
file.WriteString(<-ch)
fmt.Printf("%.2fs elapsed\n", time.Since(start).Seconds())
}
file.Close()
}
func fetch(url string, ch chan<- string, file *os.File) {
start := time.Now()
resp, err := http.Get(url)
if err != nil {
ch <- fmt.Sprint(err)
return
}
nbytes, err := io.Copy(ioutil.Discard, resp.Body)
if err != nil {
ch <- fmt.Sprint("while reading %s: %v", url, err)
return
}
secs := time.Since(start).Seconds()
ch <- fmt.Sprintf("%.2fs %7d %s \r\n", secs, nbytes, url)
}
|
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
// 练习 1.10: 找一个数据量比较大的网站,用本小节中的程序调研网站的缓存策略, // 1. 提示1,输入到文件可以使用 file, err := os.Create(fileName), nbytes, err := io.Copy(file, response.Body) 得到 package main
import (
"fmt"
"os"
"io"
"net/http"
"time"
"strings"
)
func main(){
start := time.Now()
channel := make(chan string)
for _, url := range os.Args[1:]{
go fetchToFile(url, channel, 1)
go fetchToFile(url, channel, 2)
}
for range os.Args[1:]{
fmt.Println(<- channel)
fmt.Println(<- channel)
}
fmt.Printf("time elaseped: %.2f\n", time.Since(start).Seconds())
}
func fetchToFile(url string, channel chan <- string, number int){
start := time.Now()
// 1. getting url's response
response, urlError := http.Get(url)
if urlError != nil{
channel <- fmt.Sprintf("Exec_1.10: %v\n", urlError)
return
}
// 2. Creating output file
preString := url
nextSlice := strings.Split(preString, ".")
outputfileName := nextSlice[1] // https://www . baidu . com
if number == 1{
outputfileName += "_1.html"
}else{
outputfileName += "_2.html"
}
outputfile, outputfileErr := os.Create(outputfileName)
if outputfileErr != nil{
channel <- fmt.Sprintf("Exec_1.10: Creating %s: %v\n", outputfileName, outputfileErr)
return
}
// 3. Copy response's Body to outputfile
nbytes, copyErr := io.Copy(outputfile, response.Body)
response.Body.Close()
if copyErr != nil{
channel <- fmt.Sprintf("Exec_1.10: Copying %s:[%d] %v\n", url, number, copyErr)
return
}
channel <- fmt.Sprintf("%.2f %7d %s [%d]", time.Since(start).Seconds(), nbytes, url, number)
} |
Beta Was this translation helpful? Give feedback.
-
$ ./curl_plus_pra_1_10 golang~https://golang.org gopl~http://gopl.io godoc~https://godoc.org
3.14 32378 https://godoc.org
3.14 4154 http://gopl.io
4.07 61860 https://golang.org
4.07 elapsed%
$ diff gopl20240417204517.dat gopl20240417205303.dat //curl_plus_pra_1_10
package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
"time"
)
func main() {
start := time.Now()
ch := make(chan string)
for _, urlinf := range os.Args[1:] {
inf := strings.Split(urlinf, "~")
urlflag := inf[0]
url := inf[1]
go fetch(urlflag, url, ch)
}
for range os.Args[1:] {
fmt.Println(<-ch)
}
fmt.Printf("%.2f elapsed", time.Since(start).Seconds())
}
func fetch(urlflag string, url string, ch chan<- string) {
start := time.Now()
resp, err := http.Get(url)
if err != nil {
ch <- fmt.Sprint(err)
return
}
if resp == nil {
ch <- (url + "resp is nil")
return
}
//在Go语言中,`time.Format`方法的输入字符串是通过一个特定的格式来决定的,这个格式是Go设计者选择的一个固定的时间点:`Mon Jan 2 15:04:05 MST 2006`(go诞生的时间点)。
filename := urlflag + start.Format("20060102150405") + ".dat"
filestream, err := os.Create(filename)
if err != nil {
ch <- fmt.Sprint(err)
return
}
defer filestream.Close()
defer resp.Body.Close()
bytes, err := io.Copy(filestream, resp.Body)
if err != nil {
ch <- fmt.Sprint(err)
return
}
ch <- fmt.Sprintf("%.2f\t%7d\t%s", time.Since(start).Seconds(), bytes, url)
} |
Beta Was this translation helpful? Give feedback.
-
练习一
|
Beta Was this translation helpful? Give feedback.
-
为什么会出现下面的错误: |
Beta Was this translation helpful? Give feedback.
-
ch1/ch1-06
中文版
https://gopl-zh.github.io/ch1/ch1-06.html
Beta Was this translation helpful? Give feedback.
All reactions