2015-02-03 1 views
4

golang에 작은 webapp을 작성하고 있으며 사용자가 업로드 한 파일을 구문 분석합니다. 파일을 gzip으로 만들었는지 여부를 자동으로 감지하여 독자/스캐너를 적절하게 작성하고 싶습니다. 한 가지 비법은 전체 파일을 메모리로 읽을 수 없다는 것입니다. 스트림에서만 작동 할 수 있습니다. 여기에 내가있어 무엇 :golang에서 gzip 또는 일반 텍스트 판독기를 읽는 방법?

func scannerFromFile(reader io.Reader) (*bufio.Scanner, error) { 

var scanner *bufio.Scanner 
//create a bufio.Reader so we can 'peek' at the first few bytes 
bReader := bufio.NewReader(reader) 

testBytes, err := bReader.Peek(64) //read a few bytes without consuming 
if err != nil { 
    return nil, err 
} 
//Detect if the content is gzipped 
contentType := http.DetectContentType(testBytes) 

//If we detect gzip, then make a gzip reader, then wrap it in a scanner 
if strings.Contains(contentType, "x-gzip") { 
    gzipReader, err := gzip.NewReader(bReader) 
    if (err != nil) { 
     return nil, err 
    } 

    scanner = bufio.NewScanner(gzipReader) 

} else { 
    //Not gzipped, just make a scanner based on the reader 
    scanner = bufio.NewScanner(bReader) 
} 

return scanner, nil 
} 

이 일반 텍스트 잘 작동하지만 gzip으로 압축 된 데이터가 잘못 팽창, 몇 킬로바이트 후 나는 필연적으로 왜곡 된 텍스트를 얻을. 밖에 간단한 방법이 있습니까? 왜 수천 줄 뒤에 왜 압축이 풀리지 않는지?

+0

이 코드 외부의 내용에 결함이 있는지 궁금하게 생각합니다. gzip 판독기의 텍스트가 제대로 표시되지 않습니다. (편집 : 웁스, 그 "중요하지 않습니다. :)) – twotwotwo

+1

코드가 나에게 맞는 것 같습니다. 나는 strings.Contains 대신에'contentType == "application/x-gzip"을 추천한다. –

+1

압축 된 스트림 자체가 손상된 경우 CRC 오류가 발생할 것으로 예상됩니다. 압축 이전이거나 압축 해제 이후에있을 수 있습니다. 어쨌든, 문제를 해결하기에 충분한 정보가 없을 수도 있습니다. – twotwotwo

답변

3

첫 번째 2 바이트가 0x1f8b (해당 정보는 here입니다)과 같은지 확인하여 파일이 gziped 된 것을 감지 할 수 있습니다.

의견에서 누군가가 이러한 바이트를 별도로 확인해야한다고 언급 했으므로 첫 번째 바이트는 0x1f이고 두 번째 바이트는 0x8b입니다.

testBytes, err := bReader.Peek(2) //read 2 bytes 
.... 
if testBytes[0] == 31 && testBytes[1] == 139 { 
    //gzip 
}else{ 
    ... 
} 

희망이 있습니다.

0

모두에게 감사드립니다. twotwotwo와 thundercat은 정확했으며 스트림은 게시 된 코드와 관련이없는 자리에서 손상되었습니다. 이상하게도 요청 스트림에서 읽는 동안 http 응답에 쓰는 것과 관련이있는 것 같습니다. 나는 아직도 그것을 조사하고 있지만, 원래의 질문은 잘못된 것으로 보인다.