我开始学习 Go,我对它在使用 ioutil.ReadFile 时包含 EOF 这一事实感到有点困惑。功能。例如,我想读取一个文件并解析字段分隔符上的所有行。
示例输入文件:
CZG;KCZG;some text
EKY;KEKY;some text
A50;KA50;some text
UKY;UCFL;some text
MIC;KMIC;some text
K2M;K23M;some text
这是我读取和解析该文件的方式:
import(
"fmt"
"log"
"io/ioutil"
"strings"
)
func main() {
/* Read file */
airportsFile := "/path/to/file/ad_iata"
content, err := ioutil.ReadFile(airportsFile)
if err != nil {
log.Fatal(err)
}
/* split content on EOL */
lines := strings.Split(string(content), "\n")
/* split line on field separator ; */
for _, line := range lines {
lineSplit := strings.Split(line, ";")
fmt.Println(lineSplit)
}
}
string.Split函数在看到 EOF(无需解析)时在 lineSplit slice 的末尾添加一个空元素。因此,如果我想访问该 slice 的第二个索引 (lineSplit[1]
),我会遇到 panic: runtime error: index out of range
。我必须通过这样做来限制范围
/* split line on field separator ; */
lenLines := len(lines) -1
for _, line := range lines[:lenLines] {
lineSplit := strings.Split(line, ";")
fmt.Println(lineSplit[1])
}
如果我想继续使用 ReadFile 的简洁性,有没有更好的方法?
同样的问题在使用ioutil.ReadAll时出现
最佳答案
没有“EOF 字节”或“EOF 字符”这样的东西。您所看到的可能是由文件末尾的换行符 ('\n'
) 引起的。
要逐行读取文件,使用 bufio.Scanner
更为惯用:
file, err := os.Open(airportsFile)
if err != nil {
log.Fatal(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
// ... use line as you please ...
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
这实际上解决了您的问题,因为 Scanner
将在不开始新行的情况下读取最后的换行符,如 this playground example 所证明的那样.
关于go - 防止 ReadFile 或 ReadAll 读取 EOF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39567179/