Файл Golang читает только последнюю строку

Итак, я взял некоторые общедоступные данные, которые выглядят так:

это файл

http://expirebox.com/download/b149b744768fb11aee9c5e26ad409bcc.html

,,,% of Total Expenditure,,,
Function Code,Type of Activity,Expenditure,Dollars/Student (ADA),"This District (ADA 49,497)",All Unified School Districts,Statewide Average
1000-1999ÊÊ,INSTRUCTIONÊÊ,"$249,397,226","$5,039",42%,62%,62%
1000,Instruction,"$247,472,790ÊÊ","$5,000",42%,48%,49%
1110,Special Education: Separate Classes,"$1,004,074",$20,N/A,N/A,N/A
1120,Special Education: Resource Specialist Instruction,"$781,629",$16,N/A,N/A,N/A
1130,Special Education: Supplemental Aids & Services in Regular Classrooms,"$46,747",$1,N/A,N/A,N/A
1180,Special Education:  Nonpublic Agencies/Schools (NPA/S),N/A,N/A,N/A,N/A,N/A
1190,Special Education:  Other Specialized Instructional Services,"$91,985",$2,N/A,N/A,N/A
1100-1199,Instruction - Special Education,"$1,924,436ÊÊ",$39,0%,14%,13%
"Subtotal, INSTRUCTION",,"$249,397,226","$5,039",42%,62%,62%
2000-2999ÊÊ,INSTRUCTION-RELATED SERVICESÊÊ,"$132,783,414","$2,683",22%,12%,12%
2100,Instructional Supervision and Administration,"$89,551,041","$1,809",N/A,N/A,N/A
2110,Instructional Supervision,N/A,N/A,N/A,N/A,N/A
2120,Instructional Research,N/A,N/A,N/A,N/A,N/A
2130,Curriculum Development,"$348,369",$7,N/A,N/A,N/A
2140,In-house Instructional Staff Development,"$19,855",$0,N/A,N/A,N/A
2150,Instructional Administration of Special Projects,N/A,N/A,N/A,N/A,N/A
2100-2199,Instructional Supervision and Administration,"$89,919,265ÊÊ","$1,817",15%,4%,4%
2200,Administrative Unit (AU) of a Multidistrict SELPA,$0,$0,0%,0%,0%
2420,"Instructional Library, Media, and Technology","$8,295,033ÊÊ",$168,1%,1%,1%
2490,Other Instructional Resources,"$538,734",$11,N/A,N/A,N/A
2495,Parent Participation,"$97,830",$2,N/A,N/A,N/A
2490-2495,Other Instructional Resources,"$636,565ÊÊ",$13,0%,1%,0%
2700,School Administration,"$33,932,551ÊÊ",$686,6%,7%,7%
"Subtotal, INSTRUCTION-RELATED SERVICES",,"$132,783,414","$2,683",22%,12%,12%
3000-3999ÊÊ,PUPIL SERVICESÊÊ,"$45,325,938",$916,8%,8%,8%
4000-4999ÊÊ,ANCILLARY SERVICESÊÊ,"$2,207,263",$45,0%,1%,1%
5000-5999ÊÊ,COMMUNITY SERVICESÊÊ,$0,$0,0%,0%,0%
6000-6999ÊÊ,ENTERPRISEÊÊ,"$4,264",$0,0%,0%,0%
7000-7999ÊÊ,GENERAL ADMINISTRATIONÊÊ,"$27,916,858",$564,5%,5%,6%
8000-8999ÊÊ,PLANT SERVICESÊÊ,"$55,172,247","$1,115",9%,11%,10%
9000-9999ÊÊ,OTHER OUTGOÊÊ,"$81,981,716",N/A,14%,2%,2%
"Total Expenditures, All Activities",,"$594,788,926","$12,017",100%,100%,100%

Это в CSV.

Я пробовал этот код

file, err := os.Open("expenses.csv")
if err != nil {
    log.Fatal(err)
}
defer file.Close()

scanner := bufio.NewScanner(file)
for scanner.Scan() {
    fmt.Println(scanner.Text())
}

if err := scanner.Err(); err != nil {
    log.Fatal(err)
}

и это

content, err := ioutil.ReadFile("expenses.csv")

lines := strings.Split(string(content), "\n")

fmt.Println(lines)

check(err)

dat, err := os.Open("expenses.csv")
check(err)

defer dat.Close()

reader := csv.NewReader(dat)
reader.LazyQuotes = true

reader.FieldsPerRecord = -1

rawCSVData, err := reader.ReadAll()

check(err)
fmt.Println(rawCSVData)

for _, each := range rawCSVData {
    fmt.Println(each)
}

где чек

func check(e error) {
    if e != nil {
        panic(e)
    }
}

В обоих случаях я получаю этот результат -

"Total Expenditures, All Activities",,"$594,788,926","$12,017",100%,100%,100%,1%15%,4%,4%AA,N/A,N/Anified School Districts,Statewide Average

Вместо всех строк.

Почему я читаю только последнюю строку?


person praks5432    schedule 04.06.2015    source источник
comment
Я не могу воспроизвести это. Я подозреваю, что ваш файл csv не совсем то, что вы думаете. Возможно, окончания строк странные? (Не окончания строк Windows; это поддерживается, но что-то еще? Пробелы?)   -  person Rob Napier    schedule 04.06.2015
comment
стоит попробовать. Вы также можете просмотреть его в шестнадцатеричном дампе, таком как xxd, и убедиться, что это именно то, что вы думаете. И, конечно же, убедитесь, что вы открываете именно тот файл, о котором думаете.   -  person Rob Napier    schedule 04.06.2015
comment
он загружен - я определенно открываю правильный файл, поскольку он находится в том же каталоге, что и мой код, и последняя строка выводится правильно.   -  person praks5432    schedule 04.06.2015
comment
@RobNapier есть идеи?   -  person praks5432    schedule 04.06.2015


Ответы (1)


Основная проблема заключается в том, что этот файл имеет \r окончание строки. Это также недействительно UTF-8. Вместе они принесут Scanner много неприятностей.

Во-первых, мы можем точно увидеть, что находится в файле, используя xxd

00000000: 2c2c 2c25 206f 6620 546f 7461 6c20 4578  ,,,% of Total Ex
00000010: 7065 6e64 6974 7572 652c 2c2c 0d46 756e  penditure,,,.Fun

Если вы посмотрите, вы увидите, что строка заканчивается на 0d, то есть на \r. Scanner нужно, чтобы это было либо \r\n, либо \n.

Далее у вас могут возникнуть проблемы, потому что это не UTF-8. Все эти Ê на самом деле 0xCA, что не является допустимой кодировкой UTF-8. Мы снова видим это в xxd:

000000b0: 3939 39ca ca2c 494e 5354 5255 4354 494f  999..,INSTRUCTIO
000000c0: 4eca ca2c 2224 3234 392c 3339 372c 3232  N..,"$249,397,22

Go, вероятно, просто отправит его в виде байтов (и получит Ê), что многие редакторы пытаются сделать, но это может вызвать проблемы.

Если возможно, переформатируйте этот файл, чтобы использовать окончания строк Unix или Windows в UTF-8.

person Rob Napier    schedule 04.06.2015
comment
есть ли способ сделать это программно? - person praks5432; 04.06.2015
comment
В идеале повторно экспортируйте файл. В противном случае вы могли бы начать с \r, а не с \n. - person Rob Napier; 04.06.2015
comment
но у меня нет доступа к каждой строке - я получаю только последнюю строку, когда распечатываю содержимое - person praks5432; 04.06.2015
comment
Потому что вы расходитесь на \n. Этот файл имеет \r между строками. В файле нет \n, поэтому там всего одна строка. - person Rob Napier; 04.06.2015
comment
ах, вы говорите о первом способе, который я использовал. Прохладный. Итак, я предполагаю, что второй метод, который я использовал, автоматически разделяется на \n? - person praks5432; 04.06.2015
comment
@praks5432, вы можете вставить простой пользовательский transform.Transformer, который переводит \r на \n (и, возможно, также что-то делает с недопустимым utf8) в путь. Это позволит вам тривиально использовать потоковую передачу csv.Reader для большого файла, переводящегося при чтении/потоковой передаче файла. Например. что-то вроде: play.golang.org/p/y3kKBI6721. - person Dave C; 04.06.2015