3 回答

TA贡献1839条经验 获得超15个赞
一些不同的选项:
跳过解析第一行。这假设每个文件都以标头开头。
跳过存在解析错误的行。最简单的方法,但在出现问题时很难调试。
如果第一行有解析错误,请跳过它,因为它可能是标题行。
另外,您应该在代码中正确处理错误,而您当前没有这样做。

TA贡献1875条经验 获得超5个赞
我已经注释掉了程序,所以很容易理解。基本思想是忽略标头。此外,当您编制索引并获取记录的字段时;最好检查记录中存在的字段数()。FieldsPerRecord
package main
import (
"encoding/csv"
"errors"
"fmt"
"io"
"log"
"os"
"strconv"
)
// file stores the filepath
const file = "./rr.csv"
// Data store metadata
type Data struct {
datetime string
open float64
high float64
low float64
close float64
volume float64
}
// s2f converts string to float64
func s2f(str string) (float64, error) {
f, err := strconv.ParseFloat(str, 64)
if err != nil {
return 0, fmt.Errorf("Error converting string \"%v\" to float", err)
}
return f, nil
}
// ReadAmounts processes the fields from the record and stores them in Data
func ReadAmounts(r []string) (*Data, error) {
var (
dt = r[0]
open = r[1]
high = r[2]
low = r[3]
close = r[4]
volume = r[5]
d = new(Data)
err error
)
d.datetime = dt
d.open, err = s2f(open)
if err != nil {
return nil, err
}
d.high, err = s2f(high)
if err != nil {
return nil, err
}
d.low, err = s2f(low)
if err != nil {
return nil, err
}
d.close, err = s2f(close)
if err != nil {
return nil, err
}
d.volume, err = s2f(volume)
if err != nil {
return nil, err
}
return d, nil
}
func main() {
// Open the file
file, err := os.Open(file)
if err != nil {
log.Fatalln(err)
}
// CSV Reader
r := csv.NewReader(file)
// Set Options for the reader
{
r.Comma = ',' // Delimiter
r.TrimLeadingSpace = true // Trim the leading spaces
r.FieldsPerRecord = 0 // Rows should have same number of columns as header
r.ReuseRecord = true // Reuse the same backing array (Efficient)
}
// Alternatively, r.ReadAll() could be also used and slicing it using [1:] ignores
// the header as well.
// Ignore header
_, _ = r.Read()
for {
// Read record (one by one)
record, err := r.Read()
if err != nil {
// Exit out. Done!
if errors.Is(err, io.EOF) {
break
}
// Log and continue
log.Printf("Error reading record: %v\n", err)
continue
}
// Process
data, err := ReadAmounts(record)
if err != nil {
// Log and continue
fmt.Printf("Error reading record: %v\n", err)
continue
}
// Print the filled Data struct
fmt.Printf("Record: %+v\n", *data)
}
}
输出:
Record: {datetime:2020-11-09 00:00 open:69.58 high:137.45 low:69 close:100 volume:2.73517274e+08}
Record: {datetime:2020-11-10 00:00 open:104.65 high:128.8 low:101.75 close:107 volume:1.41284399e+08}
Record: {datetime:2020-11-11 00:00 open:109 high:114.45 low:96.76 close:98.42 volume:9.6648953e+07}
Record: {datetime:2020-11-12 00:00 open:95.98 high:106.6 low:89.15 close:90 volume:1.49794913e+08}

TA贡献1844条经验 获得超8个赞
您可以将文件加载到 CSV 中,然后逐行处理该文件:
package main
import (
"bytes"
"encoding/csv"
"fmt"
"io/ioutil"
"strconv"
)
const file = "./data.csv"
// Data struct is the data from the csv file
type Data struct {
datetime string
open float64
high float64
low float64
close float64
volume float64
}
func main() {
f, err := ioutil.ReadFile(file)
if err != nil {
panic(err)
}
rawData, err := readCsv(f, ',')
if err != nil {
panic(err)
}
amounts, err := readAmounts(rawData[1:])
if err != nil {
panic(err)
}
fmt.Printf("%+v\n", amounts)
}
func readAmounts(r [][]string) ([]Data, error) {
var d []Data = make([]Data, len(r))
var err error
for i, row := range r {
d[i].datetime = row[0]
if err != nil {
fmt.Printf("Error converting string: %v", err)
}
d[i].open, err = strconv.ParseFloat(row[1], 64)
if err != nil {
fmt.Printf("Error converting string: %v", err)
}
d[i].high, err = strconv.ParseFloat(row[2], 64)
if err != nil {
fmt.Printf("Error converting string: %v", err)
}
d[i].low, err = strconv.ParseFloat(row[3], 64)
if err != nil {
fmt.Printf("Error converting string: %v", err)
}
d[i].close, err = strconv.ParseFloat(row[4], 64)
if err != nil {
fmt.Printf("Error converting string: %v", err)
}
d[i].volume, err = strconv.ParseFloat(row[5], 64)
if err != nil {
fmt.Printf("Error converting string: %v", err)
}
}
return d, nil
}
func readCsv(data []byte, separator rune) ([][]string, error) {
csvReader := csv.NewReader(bytes.NewReader(data))
csvReader.Comma = separator
lines, err := csvReader.ReadAll()
if err != nil {
return nil, err
}
return lines, nil
}
输出示例:
[{datetime:2020-11-09 00:00 open:69.58 high:137.45 low:69 close:100 volume:2.73517274e+08} {datetime:2020-11-10 00:00 open:104.65 high:128.8 low:101.75 close:107 volume:1.41284399e+08} {datetime:2020-11-11 00:00 open:109 high:114.45 low:96.76 close:98.42 volume:9.6648953e+07} {datetime:2020-11-12 00:00 open:95.
98 high:106.6 low:89.15 close:90 volume:1.49794913e+08}]
注意:
您可以找到一些使用该库工作的代码示例,您可以查看以下存储库:https://github.com/alessiosavi/GoSFTPtoS3CSV
- 3 回答
- 0 关注
- 101 浏览
添加回答
举报