-1

I have the following function in python. It's a simple function that reads a file. I coded it to act differently when the file is empty. When the file is non-empty, len(f.read()) has a non zero value but still it gets into the if condition.

Code:

def data():
    with open('data.dat','r') as f:
        print (len(f.read()))

        print(len(f.read())==0)

        if len(f.read())==0:
            print ("IF Entered")
        else:
            print ("Else Entered")

    return {}

Output:

19
True
IF Entered

Expected Output:

19
False
Else Entered

EDIT: I updated my code(I wanted to use the f twice for json.load but when I used it once, it went to the end to give crazy outputs. Now this gets the work done.) to:

def data():
    with open('data.dat','r') as f:
        if len(f.read())==0:
            return {'post':{}}
    with open('data.dat','r') as f:
        return json.load(f)
Abhinay Pandey
  • 46
  • 3
  • 15
  • Possible duplicate of [Why can't I call read() twice on an open file?](https://stackoverflow.com/questions/3906137/why-cant-i-call-read-twice-on-an-open-file) – Georgy May 20 '19 at 08:00

1 Answers1

3

This happens because when you call f.read() this will move your cursor to the end of the file, and in the second run nothing would be read.

This example is also presented in the docs:

To read a file’s contents, call f.read(size), which reads some quantity of data and returns it as a string (in text mode) or bytes object (in binary mode). size is an optional numeric argument. When the size is omitted or negative, the entire contents of the file will be read and returned; it’s your problem if file is twice as large as your machine’s memory. Otherwise, at most size bytes are read and returned. If the end of the file has been reached, f.read() will return an empty string ('').

So as OP correctly asked, you need to assign the value of .read() to any variable and process it as you wish.

def data():
    with open('data.dat','r') as f:
        contents = f.read()

    # do anything with your `contents`

    return {}

Update to OP's EDIT (with solution) :

You can omit second time read just by catching decode error (if file is empty):

def data():
    with open('data.dat', 'r') as f:
        try:
            return json.load(f)
        except json.JSONDecodeError:
            return {'post': {}}
vishes_shell
  • 22,409
  • 6
  • 71
  • 81