i am using the following code snippet to unpack a zipped csv file and split it into even parts.
func split(feed MerchantFeed, db *gorm.DB) {
var merchant Merchant
db.First(&merchant, feed.MerchantID)
merchant.Title = strings.Replace(merchant.Title, ".", "_", -1)
fileID := merchant.Title "__" fmt.Sprint(feed.MerchantID) "__" uniuri.NewLen(20)
out, _ := os.Create("/tmp/feeds/" fileID)
resp, err := http.Get(feed.Url)
if err != nil {
fmt.Println("Feed download error!")
}
defer resp.Body.Close()
// Calling Copy method with its parameters
bytes, err := io.Copy(out, resp.Body)
if err != nil {
fmt.Println("Could not create feed csv")
}
defer out.Close()
in, _ := os.Open("/tmp/feeds/" fileID)
reader, err := gzip.NewReader(in)
if err != nil {
fmt.Println("Could not unzip feed " fmt.Sprint(feed.MerchantID))
err.Error()
return
}
defer in.Close()
// Empty byte slice.
csvString := make([]byte, 100)
// Read in data.
_, errRead := reader.Read(csvString)
if errRead != nil {
fmt.Println(err)
}
path := "/tmp/split/feed__" fileID "__.csv"
csvfile, err := os.Create(path)
io.Copy(csvfile, reader)
if fileID != "" {
_, errx := splitter.Split(path, splitDir)
if errx != nil {
fmt.Println(errx)
}
defer csvfile.Close()
//fmt.Println(result)
result := os.Remove(path)
if result != nil {
fmt.Println(result)
}
}
fmt.Printf("Size in MB (Feed %d): %d\n", feed.MerchantID, bytes)
if bytes == 64 {
fmt.Println("could not download feed from " fmt.Sprint(feed.MerchantID))
e := os.Remove("/tmp/feeds/" fileID ".gz")
if e != nil {
log.Fatal(e)
}
return
}
}
So far so good. It's all working. But some Merchants pack their csv as zip, and others don't. So my idea is to dynamically switch between gzip.NewReader() and csv.NewReader() but i don't know the proper way to do that. I want to repeat as few code as possible. So i tried to say
var zipNetworks []int
zipNetworks = append(zipNetworks, 2)
if slices.Contains(zipMerchants,merchant.Network_ID) {
reader := zip.NewReader(in)
} else {
reader := csv.NewReader(in)
}
but then I have problems with the scope.
Is there any smart solution around that I don't know?
CodePudding user response:
You can use the common io.Reader
interface.
var reader io.Reader
if slices.Contains(zipMerchants, merchant.Network_ID) {
reader = zip.NewReader(in)
} else {
reader = csv.NewReader(in)
}
CodePudding user response:
Set the reader to the file. If gzipping, then replace reader with gzip reader around the file:
var reader io.Reader = in
if shouldUseGzip {
reader, err = gzip.NewReader(reader)
if err != nil {
fmt.Println("Could not unzip feed " fmt.Sprint(feed.MerchantID), err)
return
}