How to read a csv file in golang
A few days ago I discovered how easy and practical it is to read a file in csv format with golang.
Then I'll share the recipe.
Let's start
First step
For this example download the MX.zip (MX.txt csv file) file of GeoNames site.
The GeoNames geographical database covers all countries and contains over eleven million placenames that are available for download free of charge.
A sample of the file looks like this:
MX 20000 Zona Centro Aguascalientes AGU Aguascalientes 001 Aguascalientes 01 21.8734 -102.2806 1
MX 20008 Delegación de La Secretaria de Comercio y Fomento Industrial Aguascalientes AGU Aguascalientes 001 Aguascalientes 01 21.8734 -102.2806 1
MX 20009 Palacio de Gobierno del Estado de Aguascalientes Aguascalientes AGU Aguascalientes 001 Aguascalientes 01 21.8734 -102.2806 1
MX 20010 Ramon Romo Franco Aguascalientes AGU Aguascalientes 001 Aguascalientes 01 21.9644 -102.3192 1
MX 20010 Colinas del Rio Aguascalientes AGU Aguascalientes 001 Aguascalientes 01 21.9644 -102.3192 1
MX 20010 San Cayetano Aguascalientes AGU Aguascalientes 001 Aguascalientes 01 21.9644 -102.3192 1
MX 20010 Olivares Santana Aguascalientes AGU Aguascalientes 001 Aguascalientes 01 21.9644 -102.3192 1
MX 20010 Las Brisas Aguascalientes AGU Aguascalientes 001 Aguascalientes 01 21.9644 -102.3192 1
MX 20016 La Fundición Aguascalientes AGU Aguascalientes 001 Aguascalientes 01 21.9644 -102.3192 3
MX 20016 Colinas de San Ignacio Aguascalientes AGU Aguascalientes 001 Aguascalientes 01 21.9644 -102.3192
If you open the file with vim editor, with the following command:
:set list
you can see that data fields are separated by ^I (vim tabulador)
Second step
I'm going to use the encoding/csv package that belongs to the go standart library.
The full version of the code is here
const (
FILE = "./MX.txt"
FILE_DELIMITER = '\t'
TOTAL_ROWS = 5
)
func main() {
file, err := os.Open(FILE)
printError(err)
defer file.Close()
reader := csv.NewReader(file)
reader.Comma = FILE_DELIMITER
rows, err := reader.ReadAll()
printError(err)
fmt.Printf("\nrows type: %T\n\n", rows)
d := new(Document)
for n, col := range rows {
d.colonia = col[2]
d.ciudad = col[3]
d.delegacion = col[5]
n++
if n <= TOTAL_ROWS {
fmt.Printf("%v,%v,%v;\n", d.colonia, d.ciudad, d.delegacion)
}
}
}
The next line tells golang that data fields are separated by \t (tabulador) rather than by whitespace.
reader.Comma = FILE_DELIMITER
Now reader.ReadAll() function returns a [][]string data type.
rows, err := reader.ReadAll()
This allows me to store in each element of the array the values of the columns of each line of the file. And this way I can only use the columns of data that I need.
for n, col := range rows {
d.colonia = col[2]
d.ciudad = col[3]
d.delegacion = col[5]
Finally the condition if I use it to stop reading the file on line 5 (TOTAL_ROWS), because the whole file has 144513 records! And I just need a few for this example :)
if n <= TOTAL_ROWS {
fmt.Printf("%v,%v,%v;\n", d.colonia, d.ciudad, d.delegacion)
}
Maybe in the next post I'll take part of this example to show how to read and load those 144513 records on an ElasticSearch server :)
Congratulations @elsanto! You have completed some achievement on Steemit and have been rewarded with new badge(s) :
Award for the number of upvotes received
Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here
If you no longer want to receive notifications, reply to this comment with the word
STOP
Congratulations @elsanto! You have completed some achievement on Steemit and have been rewarded with new badge(s) :
Award for the number of upvotes
Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here
If you no longer want to receive notifications, reply to this comment with the word
STOP
Congratulations @elsanto! You have completed some achievement on Steemit and have been rewarded with new badge(s) :
Award for the number of upvotes received
Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here
If you no longer want to receive notifications, reply to this comment with the word
STOP