1

I am trying to follow the solution from question How to write a csv file in binary mode? (or somewhat related Python: reading from binary zipfile into csv) by playing with a test code, but don't know how to exactly handle the actual file.

Basically, I want the original b'\x01' byte value to be preserved as bytes type in the end when it comes back out, but in my code it comes out as string.

Also on Linux (Raspberry Pi OS) Python 3.7 the test code below throws AttributeError: 'file' object has no attribute 'readable' on line 8, whereas on Windows 10 / Python 3.9 the test code runs without any error.

How can I handle the file properly in this context ?

Test code:

import io
import csv

test_byte = b'\x01'
print ("original item value is %s of type %s" % (test_byte, type(test_byte)))
csv_data_dict = [{"preset": "item", "value": test_byte}]

with io.TextIOWrapper(open("test.csv", 'wb'), encoding = 'utf-8', newline = '') as csvfile:
    fieldnames = ["preset", "value"]
    writer = csv.DictWriter(csvfile, fieldnames = fieldnames)
    writer.writeheader()
    for i in range(len(csv_data_dict)):
        writer.writerow(csv_data_dict[i])

with io.TextIOWrapper(open("test.csv", 'rb'), encoding = 'utf-8', newline = '') as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
        if row["preset"] == "item":
            print ("item value returned as %s of type %s" % (row["value"], type(row["value"]))) # comes back a string

And its output (on Windows):

original item value is b'\x01' of type <class 'bytes'>
item value returned as b'\x01' of type <class 'str'>
secarica
  • 597
  • 5
  • 18
  • 1
    CSV files are not designed to hold binary data. It is a text format. Your options: 1. translate `b'\x01'` to hex on the way out, and back again to a byte on the way in. 2. Abandon the `csv` module and write your nonstandard format explicitly with `write()` calls. 3. Revisit your decision to use the CSV format for storage. – BoarGules Feb 12 '21 at 08:22
  • Right, that is a good systematization. For now, I ended up in converting the bytes string in question into base64 encoded string and then back to bytes via base64 decoding. Still, I don't understand how is working the solution given for the question mentioned in my first sentence, i.e. from https://stackoverflow.com/questions/50120806/how-to-write-a-csv-file-in-binary-mode – secarica Feb 13 '21 at 14:08
  • I know that question has an accepted answer but I can't see how what it recommends could do what you wanted. It writes `str(b"\x01")` and you appear to want it to write `b"\x01"` which module `csv` is defined *not* to do. Docs: Apart from `None`, "all other non-string data are stringified with `str()` before being written". – BoarGules Feb 13 '21 at 16:33

0 Answers0