Using bytes.Buffer with csv.writer [closed] - csv

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I'm currently trying to serialize some string slice in a CSV without saving output to a file. I saw some examples using bytes.Buffer but even my the smallest test doesn't work. I don't know how to debug this, the code compiles without warning and doesn't throw error after writer.Flush(). It also works correctly with saving result to a file or piping it directly to standard output
Any help would be appreciated :)
Thx.
PS: the final print is just a test. I know i can use csv.NewWriter(os.stdout) to do so (and it works) but it doesn't fit my needs. I really would like to get the result in a byte array.
package main
import (
"bytes"
"encoding/csv"
"fmt"
)
func main() {
var buffer bytes.Buffer
writer := csv.NewWriter(&buffer)
writer.Write([]string{"1", "2", "3", "4"})
writer.Write([]string{"5", "6", "7", "8"})
defer writer.Flush()
if err := writer.Error(); err != nil {
panic(err)
}
fmt.Println(buffer.Bytes())
}

You are deferring the Flush call, making it execute after the fmt.Println call. Call Flush immediately:
package main
import (
"bytes"
"encoding/csv"
"fmt"
)
func main() {
var buffer bytes.Buffer
writer := csv.NewWriter(&buffer)
writer.Write([]string{"1", "2", "3", "4"})
writer.Write([]string{"5", "6", "7", "8"})
writer.Flush()
if err := writer.Error(); err != nil {
panic(err)
}
fmt.Println(buffer.String())
}
https://play.golang.org/p/BHTyfsuf0tY

Related

Anonymous structs outside function not working [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I don't understand why this doesn't work for this type of structure.
package main
import (
"fmt"
)
var myStruct struct {
number float64
word string
toggle bool
}
myStruct.number = 3.14
myStruct.word = "pie"
myStruct.toggle = true
func main() {
//myStruct.number = 3.14
//myStruct.word = "pie"
//myStruct.toggle = true
fmt.Println(myStruct.number)
fmt.Println(myStruct.toggle)
fmt.Println(myStruct.word)
}
If I try to change myStruct.number outside main, I get a compilation error syntax error: non-declaration statement outside function body, but it works fine inside the function. With variables or other types of data structures, it works fine to change values outside main scope, but not with struct.
The program is an example from Head first Go, and even if I searched at least three more books and google for more information, I haven't found something similar that would be better explained.
https://play.golang.org/p/brocZzWuRae
package main
import (
"fmt"
)
var myStruct = struct {
number float64
word string
toggle bool
}{
number: 3.14,
word: "pie",
toggle: true,
}
func main() {
//myStruct.number = 3.14
//myStruct.word = "pie"
//myStruct.toggle = true
fmt.Println(myStruct.number)
fmt.Println(myStruct.toggle)
fmt.Println(myStruct.word)
}

Writing to bzip2 archive [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I am processing multiple .json files which I need to add to a single .zip archive using a package available here: https://github.com/larzconwell/bzip2.
I have referenced other possible solutions and questions related to io.Writer along with .Close() and .Flush()
Code that is used:
if processedCounter%*filesInPackage == 0 || filesLeftToProcess == 0 {
// Create empty zip file with numbered filename.
emptyZip, err := os.Create(filepath.Join(absolutePathOutputDirectory, "package_"+strconv.Itoa(packageCounter)+".zip"))
if err != nil {
panic(err)
}
// Get list of .json filenames to be packaged:
listOfProcessedJSON := listFiles(absolutePathInterDirectory, ".json")
bzipWriter, err := bzip2.NewWriterLevel(emptyZip, 1)
if err != nil {
panic(err)
}
defer bzipWriter.Close()
// Add listed files to the archive
for _, file := range listOfProcessedJSON {
// Read byte array from json file:
JSONContents, err := ioutil.ReadFile(file)
if err != nil {
fmt.Printf("Failed to open %s: %s", file, err)
}
// Write a single JSON to .zip:
// Process hangs here!
_, compressionError := bzipWriter.Write(JSONContents)
if compressionError != nil {
fmt.Printf("Failed to write %s to zip: %s", file, err)
compressionErrorCounter++
}
err = bzipWriter.Close()
if err != nil {
fmt.Printf("Failed to Close bzipWriter")
}
}
// Delete intermediate .json files
dir, err := ioutil.ReadDir(absolutePathInterDirectory)
for _, d := range dir {
os.RemoveAll(filepath.Join([]string{"tmp", d.Name()}...))
}
packageCounter++
}
Using debugger it seems that the my program hangs on the following line:
_, compressionError := bzipWriter.Write(JSONContents)
The package itself does not provide usage examples so my knowledge is based on studying documentation, StackOverflow questions, and different available articles e.g.:
https://www.golangprograms.com/go-program-to-compress-list-of-files-into-zip.html
Let me know if anyone knows a possible solution to this problem.
You are confusing the formats and what they do, likely because they contain a the common substring "zip". zip is an archive format, intended to contain multiple files. bzip2 is a single-stream compressor, not an archive format, and can store only one file. gzip is the same as bzip2 in that regard. gzip, bzip2, xz, and other single-file compressors are all commonly used with tar in order to archive multiple files and their directory structure. tar collects the multiple files and structure into a single, uncompressed file, which is then compressed by the compressor of your choice.
The zip format works differently, where the archive format is on the outside, and each entry in the archive is individually compressed.
In any case, using a bzip2 package by itself will not be able to archive multiple files.

Convert number from float64 to Int64 is incorrect [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I try to write a function, the code:
package main
import (
"encoding/json"
"fmt"
)
type Test struct {
Data map[string]interface{} `json:"data"`
}
func main() {
jsonStr := "{\"data\": {\"id\": 999804707614896129}}"
t := &Test{}
json.Unmarshal([]byte(jsonStr), t)
fmt.Println(int64(t.Data["id"].(float64)))
var x float64 = 999804707614896129
fmt.Println(int64(x))
}
The result is below:
999804707614896128
999804707614896128
Why the results are 999804707614896128, not 999804707614896129.
Because 999804707614896129 cannot be represented exactly with a value of type float64. float64 uses the IEEE 754 standard for representing floating point numbers. It's a format with limited precision (roughly 16 decimal digits).
If you need to "transfer" the exact number, use string and not JSON number. If the number "fits" into an int64, you will be able to parse it "exactly" (else just work with it as a string or use big.Int):
jsonStr := `{"data": {"id": "999804707614896129"}}`
t := &Test{}
if err := json.Unmarshal([]byte(jsonStr), t); err != nil {
panic(err)
}
s := t.Data["id"].(string)
fmt.Println(s)
var x int64
x, err := strconv.ParseInt(s, 10, 64)
fmt.Println(x, err)
This will output (try it on the Go Playground):
999804707614896129
999804707614896129 <nil>

How to parse JSON extract array [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I work with Go.
I would like to parse a JSON file. But I only need just one array from the JSON file, not all the structure.
This is the JSON file : link
I only need the array of items.
How can I extract just this array from the JSON?
That depends of the definition of your structs. if you want only the array of items, you should unmarshal the main structure and then get the items array.
something like this
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
)
type Structure struct {
Items []Item `json:"items"`
}
type Item struct {
ID int `json:"id"`
Name string `json:"name"`
}
func main() {
data, err := ioutil.ReadFile("myjson.json")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
structure := new(Structure)
json.Unmarshal(data, structure)
theArray := structure.Items
fmt.Println(theArray)
}
The Unmarshal will ignore the fields you don't have defined in your struct. so that means you should add only what you whant to unmarshal
I used this JSON
{
"total_count": 123123,
"items": [
{
"id": 1,
"name": "name1"
},
{
"id": 2,
"name": "name2"
}
]
}

JSON encode returning blank Golang [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I have a very simple http resonse in my server where i json encode a struct. But its sending a blank of just {}
I don't know if i am doing it wrong but i get no errors. This is my json encode:
// Set uuid as string to user struct
user := User{uuid: uuid.String()}
fmt.Println(user) // check it has the uuid
responseWriter.Header().Set("Content-Type", "application/json")
responseWriter.WriteHeader(http.StatusCreated)
json.NewEncoder(responseWriter).Encode(user)
On the recieving end the data has:
Content-Type application/json
Content-Length 3
STATUS HTTP/1.1 201 Created
{}
Why does it not give me the uuid data? Am i doing something wrong with my encoding?
Export the field name by making the first character of the identifier's name a Unicode upper case letter (Unicode class "Lu").
Try this:
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
)
type User struct {
Uuid string
}
func handler(responseWriter http.ResponseWriter, r *http.Request) {
user := User{Uuid: "id1234657..."} // Set uuid as string to user struct
fmt.Println(user) // check it has the uuid
responseWriter.Header().Set("Content-Type", "application/json")
responseWriter.WriteHeader(http.StatusCreated)
json.NewEncoder(responseWriter).Encode(user)
}
func main() {
http.HandleFunc("/", handler) // set router
err := http.ListenAndServe(":9090", nil) // set listen port
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
output(http://localhost:9090/):
{"Uuid":"id1234657..."}