Search code examples
pythonpython-3.xbinaryfiles

UnicodDecodeError in Binary files


I've written a small sample code to try out pickle module. Faced UnicodeDecodeError in the pickle.load() statement. Writing encoding='utf-8' also has no effect. Here's the code

import pickle

class NewOne:
    def __init__(self):
        self.name = "None"
        self.age = 0

    def entries(self):
        self.name = input("Name: ")
        self.age = input("Age: ")

obj1 = NewOne()
for i in range(3):
    obj1.entries()
    pickle.dump(obj1, open("Details", "ab"))

for j in range(3):
    obj = pickle.load(open("Details",))

    if obj.age == 18:
        print("Name: "+obj.name)

Solution

  • The main problem with your code is, that you are appending to the end of the same file every time you run the script, but loading the first three objects later on.

    Actually, it's worse than that; You should be loading the first three objects, but in fact you are only loading the first one each time because you open the file anew in every iteration of your pickle.load()

    It may be that there is an error at the beginning of your file, and you are simply hitting this every time because you are loading the first object in the file. You could try deleting your Details file and see if you still get the error.

    The following code will create a new details file each time, write three objects to it, and then load those three objects back in.

    import pickle
    
    class NewOne:
        def __init__(self):
            self.name = "None"
            self.age = 0
    
        def entries(self):
            self.name = raw_input("Name: ")
            self.age = raw_input("Age: ")
    
    obj1 = NewOne()
    
    # Open file for writing. The `with` context manager will automatically close 
    # it at the end of the loop
    with open("Details", "wb") as myfile:
        for i in range(3):
            obj1.entries()
            pickle.dump(obj1, myfile)
    
    # Re-open the file for reading
    with open("Details",) as myfile:
        for j in range(3):
            obj = pickle.load(myfile)
    
            if obj.age == '18':
                print("Name: "+obj.name)