在受保护的zip文件中读取CSV文件。

huangapple go评论90阅读模式
英文:

Read CSV file on protected zip

问题

我有一个链接,类似这样:https://storage.googleapis.com/data/test_file.csv.zip
内容是一个受密码保护的zip文件,里面包含一个csv文件。我该如何从csv文件中读取数据?

我尝试了以下代码,但出现错误:

func ReadCSVZIPFromURL(fileURL string) (data [][]string, err error) {
	resp, err := http.Get(fileURL)
	if err != nil {
		return data, errors.AddTrace(err)
	}
	defer resp.Body.Close()

	r, err := zip.OpenReader(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	defer r.Close()

	for _, file := range r.File {
		if file.IsEncrypted() {
			file.SetPassword("password")
		}
		reader := csv.NewReader(file)

		data, err := reader.ReadAll()
	}

	return data, nil
}
英文:

I have link like this: https://storage.googleapis.com/data/test_file.csv.zip
the content is one csv file on the protected zip with password. How can I read data from the csv?

I have try this but its error

func ReadCSVZIPFromURL(fileURL string) (data [][]string, err error) {
	resp, err := http.Get(fileURL)
	if err != nil {
		return data, errors.AddTrace(err)
	}
	defer resp.Body.Close()

	r, err := zip.OpenReader(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	defer r.Close()

	for _, file := range r.File {
		if file.IsEncrypted() {
			file.SetPassword("password")
		}
		reader := csv.NewReader(file)

		data, err := reader.ReadAll()
	}

	return data, nil
} 

</details>


# 答案1
**得分**: 0

我已经解决了这个问题,以下是解决方法。思路是将字节复制到zip读取器中,然后获取ioReader,然后使用csv库读取ioReader。
要使用密码对数据进行加密和解密,我们使用了这个库 "github.com/alexmullins/zip"

```go
func GetCSVFromZipURL(ctx context.Context, fileURL, filePassword string) (ioReader io.Reader, err error) {
	span, ctx := tracer.StartSpanFromContext(ctx)
	defer span.Finish()

	resp, err := http.Get(fileURL)
	if err != nil {
		return ioReader, errors.AddTrace(err)
	}
	defer resp.Body.Close()

	buf := &bytes.Buffer{}

	_, err = io.Copy(buf, resp.Body)
	if err != nil {
		return ioReader, errors.AddTrace(err)
	}

	b := bytes.NewReader(buf.Bytes())
	r, err := zip.NewReader(b, int64(b.Len()))
	if err != nil {
		return ioReader, errors.AddTrace(err)
	}

	for _, f := range r.File {
		if f.IsEncrypted() {
			f.SetPassword(filePassword)
		}
		ioReader, err = f.Open()
		if err != nil {
			return ioReader, errors.AddTrace(err)
		}

		return ioReader, nil
	}

	return ioReader, nil
}

func getUserBenefitListFromCSV(ioReader io.Reader) (userBenefitList []UserBenefit, err error) {
	reader := csv.NewReader(ioReader)

	row := 1
	for {
		csvRowsStr, err := reader.Read()
		if err == io.EOF {
			break
		}
		if err != nil {
			return userBenefitList, errors.AddTrace(err)
		}

		// check if 1st row (header), skip
		if row == 1 {
			row++
			continue
		}

		if len(csvRowsStr) > 0 {
			userID, err := strconv.ParseInt(csvRowsStr[0], 10, 64)
			if err != nil {
				return userBenefitList, errors.AddTrace(err)
			}

			catalogID := 0
			if len(csvRowsStr) > 1 {
				catalogID, err = strconv.ParseInt(csvRowsStr[1], 10, 64)
				if err != nil {
					return userBenefitList, errors.AddTrace(err)
				}
			}

			userBenefitTemp := UserBenefit{
				UserID:    userID,
				CatalogID: catalogID,
			}

			userBenefitList = append(userBenefitList, userBenefitTemp)
		}
	}

	return userBenefitList, nil
}
英文:

i have solve the problem, this the solve. the idea is we copy the byte to zip reader, and we will get the ioReader, the we we read ioReader use csv library.
to encrypt and decrypt data using password we use this library "github.com/alexmullins/zip"

func GetCSVFromZipURL(ctx context.Context, fileURL, filePassword string) (ioReader io.Reader, err error) {
	span, ctx := tracer.StartSpanFromContext(ctx)
	defer span.Finish()

	resp, err := http.Get(fileURL)
	if err != nil {
		return ioReader, errors.AddTrace(err)
	}
	defer resp.Body.Close()

	buf := &amp;bytes.Buffer{}

	_, err = io.Copy(buf, resp.Body)
	if err != nil {
		return ioReader, errors.AddTrace(err)
	}

	b := bytes.NewReader(buf.Bytes())
	r, err := zip.NewReader(b, int64(b.Len()))
	if err != nil {
		return ioReader, errors.AddTrace(err)
	}

	for _, f := range r.File {
		if f.IsEncrypted() {
			f.SetPassword(filePassword)
		}
		ioReader, err = f.Open()
		if err != nil {
			return ioReader, errors.AddTrace(err)
		}

		return ioReader, nil
	}

	return ioReader, nil
}

func getUserBenefitListFromCSV(ioReader io.Reader) (userBenefitList []UserBenefit, err error) {
	reader := csv.NewReader(ioReader)

	row := 1
	for {
		csvRowsStr, err := reader.Read()
		if err == io.EOF {
			break
		}
		if err != nil {
			return userBenefitList, errors.AddTrace(err)
		}

		// check if 1st row (header), skip
		if row == 1 {
			row++
			continue
		}

		if len(csvRowsStr) &gt; 0 {
			userID, err := strconv.ParseInt(csvRowsStr[0], 10, 64)
			if err != nil {
				return userBenefitList, errors.AddTrace(err)
			}

			catalogID := 0
			if len(csvRowsStr) &gt; 1 {
				catalogID, err = strconv.ParseInt(csvRowsStr[1], 10, 64)
				if err != nil {
					return userBenefitList, errors.AddTrace(err)
				}
			}

			userBenefitTemp := UserBenefit{
				UserID:    userID,
				CatalogID: catalogID,
			}

			userBenefitList = append(userBenefitList, userBenefitTemp)
		}
	}

	return userBenefitList, nil
}

</details>



huangapple
  • 本文由 发表于 2021年7月29日 16:18:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/68572471.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定