输出GBK编码的文件

https://github.com/axgle/mahonia

  1. enc := mahonia.NewEncoder("gbk")
  2. buf := []byte(enc.ConvertString(result))
  3. ioutil.WriteFile("html/d.cmd", buf, 0666)

What is the best way to convert byte array to string?

methods that read data into byte slices return the number of bytes read. You should save that number and then use it to create your string. n being the number of bytes read, your code would look like this:

  1. s := string(byteArray[:n])

If for some reason you don’t have n, you could use the bytes package to find it, assuming your input doesn’t have a null character in it.

  1. n := bytes.Index(byteArray, []byte{0})

Or as icza pointed out, you can use the code below:

  1. n := bytes.IndexByte(byteArray, 0)

遍历目录中的*.html文件,提取特定内容,输出GBK编码的cmd文件:

  1. package main
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "log"
  6. "path/filepath"
  7. "strings"
  8. "github.com/axgle/mahonia"
  9. )
  10. // func toGBK(src string) []byte {
  11. // // srcCode := "utf8"
  12. // targetCode := "gbk"
  13. // // srcCoder := mahonia.NewDecoder(srcCode)
  14. // // srcResult := srcCoder.ConvertString(src)
  15. // tagCoder := mahonia.NewDecoder(targetCode)
  16. // _, cdata, _ := tagCoder.Translate([]byte(srcResult), true)
  17. // return cdata
  18. // }
  19. func main() {
  20. files, err := filepath.Glob("./html/*.html")
  21. if err != nil {
  22. log.Fatal(err)
  23. }
  24. // fmt.Println(files) // contains a list of all files in the current directory
  25. list := make([]string, 0)
  26. for _, fileName := range files {
  27. mp3 := strings.TrimPrefix(fileName, "html\\")
  28. mp3 = strings.TrimSuffix(mp3, ".html") + ".mp3"
  29. content, _ := ioutil.ReadFile(fileName)
  30. x := string(content)
  31. start := strings.Index(x, "<audio")
  32. end := strings.Index(x, "</audio>")
  33. if start < 0 || end < 0 {
  34. fmt.Println(fileName)
  35. continue
  36. }
  37. y := x[start : end+8]
  38. start = strings.Index(y, `src="`)
  39. end = strings.Index(y, `.mp3"`)
  40. if start < 0 || end < 0 {
  41. fmt.Println(fileName)
  42. continue
  43. }
  44. z := y[start+5 : end+4]
  45. // fmt.Println(z)
  46. // fmt.Println(fileName)
  47. // fmt.Println("wget -O ", `"`+mp3+`"`, z, "\r")
  48. list = append(list, fmt.Sprintf("wget -O \"%s\" %s", mp3, z))
  49. }
  50. result := strings.Join(list, "\r\n")
  51. // result = string(toGBK(result))
  52. // fmt.Print(toGBK(result))
  53. // ioutil.WriteFile("d.cmd", toGBK(result), 0666)
  54. enc := mahonia.NewEncoder("gbk")
  55. buf := []byte(enc.ConvertString(result))
  56. ioutil.WriteFile("html/d.cmd", buf, 0666)
  57. }

How to find a character index in Golang?

You can use the Index function of package strings

Playground: https://play.golang.org/p/_WaIKDWCec

  1. package main
  2. import "fmt"
  3. import "strings"
  4. func main() {
  5. x := "chars@arefun"
  6. i := strings.Index(x, "@")
  7. fmt.Println("Index: ", i)
  8. if i > -1 {
  9. chars := x[:i]
  10. arefun := x[i+1:]
  11. fmt.Println(chars)
  12. fmt.Println(arefun)
  13. } else {
  14. fmt.Println("Index not found")
  15. fmt.Println(x)
  16. }
  17. }

If you are searching for non-ASCII characters (languages other than english) you need to use http://golang.org/x/text/search.

  1. func SubstringIndex(str string, substr string) int, bool {
  2. m := search.New(language.English, search.IgnoreCase)
  3. start, _ := m.IndexString(str, substr)
  4. if start == -1 {
  5. return start, false
  6. }
  7. return start, true
  8. }
  9. index, found := SearchForStringIndex('Aarhus', 'Å');
  10. if found {
  11. fmt.Println("match starts at", index);
  12. }

Search the language.Tag structs here to find the language you wish to search with or use language.Und if you are not sure.


List directory in Go

You can try using the ReadDir function in the io/ioutil package. Per the docs:

ReadDir reads the directory named by dirname and returns a list of sorted directory entries.

The resulting slice contains os.FileInfo types, which provide the methods listed here. Here is a basic example that lists the name of everything in the current directory (folders are included but not specially marked - you can check if an item is a folder by using the IsDir() method):

  1. package main
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "log"
  6. )
  7. func main() {
  8. files, err := ioutil.ReadDir("./")
  9. if err != nil {
  10. log.Fatal(err)
  11. }
  12. for _, f := range files {
  13. fmt.Println(f.Name())
  14. }
  15. }

Even simpler, use path/filepath:

  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "path/filepath"
  6. )
  7. func main() {
  8. files, err := filepath.Glob("*")
  9. if err != nil {
  10. log.Fatal(err)
  11. }
  12. fmt.Println(files) // contains a list of all files in the current directory
  13. }

We can get a list of files inside a folder on the file system using various golang standard library functions.

  • filepath.Walk
  • ioutil.ReadDir
  • os.File.Readdir
  1. package main
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "log"
  6. "os"
  7. "path/filepath"
  8. )
  9. func main() {
  10. var (
  11. root string
  12. files []string
  13. err error
  14. )
  15. root := "/home/manigandan/golang/samples"
  16. // filepath.Walk
  17. files, err = FilePathWalkDir(root)
  18. if err != nil {
  19. panic(err)
  20. }
  21. // ioutil.ReadDir
  22. files, err = IOReadDir(root)
  23. if err != nil {
  24. panic(err)
  25. }
  26. //os.File.Readdir
  27. files, err = OSReadDir(root)
  28. if err != nil {
  29. panic(err)
  30. }
  31. for _, file := range files {
  32. fmt.Println(file)
  33. }
  34. }

Using filepath.Walk

The path/filepath package provides a handy way to scan all the files in a directory, it will automatically scan each sub-directories in the directory.

func FilePathWalkDir(root string) ([]string, error) {
var files []string
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if !info.IsDir() {
files = append(files, path)
}
return nil
})
return files, err
}

Using ioutil.ReadDir

ioutil.ReadDir reads the directory named by dirname and returns a list of directory entries sorted by filename.

  1. func IOReadDir(root string) ([]string, error) {
  2. var files []string
  3. fileInfo, err := ioutil.ReadDir(root)
  4. if err != nil {
  5. return files, err
  6. }
  7. for _, file := range fileInfo {
  8. files = append(files, file.Name())
  9. }
  10. return files, nil
  11. }

Using os.File.Readdir

Readdir reads the contents of the directory associated with file and returns a slice of up to n FileInfo values, as would be returned by Lstat, in directory order. Subsequent calls on the same file will yield further FileInfos.

  1. func OSReadDir(root string) ([]string, error) {
  2. var files []string
  3. f, err := os.Open(root)
  4. if err != nil {
  5. return files, err
  6. }
  7. fileInfo, err := f.Readdir(-1)
  8. f.Close()
  9. if err != nil {
  10. return files, err
  11. }
  12. for _, file := range fileInfo {
  13. files = append(files, file.Name())
  14. }
  15. return files, nil
  16. }

Benchmark results.

ft_authoradmin  ft_create_time2019-02-02 16:32
 ft_update_time2019-02-02 16:41