0

I want to check if a text file content has data inside before running some functions. so I use the following Python code

if os.path.exists("userInformation.txt") and os.path.getsize("userInformation.txt") > 0:
        with open("userInformation.txt") as info:
            contents = info.readlines()


 else:  
        new_file = open("userInformation.txt", "w")
        new_file.close()

if file doesn't exist or nothing inside it works fine. However, if a file contains newline, which will be 2 bytes. Then will cause IndexError: list index out of range, after I run some function I know i can use try, except to catch that index error. Is there any other way to it?

Thanks.

  • Here a [link](https://stackoverflow.com/a/2507819/17766295) that might help you – Nabil Jan 27 '22 at 08:17
  • You can also consider [this topic](https://stackoverflow.com/questions/7896495/python-how-to-check-if-a-line-is-an-empty-line/7896585) – Christophe Jan 27 '22 at 08:19
  • There is nothing in your code that will raise IndexError. Also, newline ('\n') is one byte. You may be thinking of carriage return + newline ('\r\n') which is indeed two bytes – DarkKnight Jan 27 '22 at 08:20
  • Can you publish the trace of the error ? Also I would like to see what you're doing with `contents`. What line is actually raising this exception ? – vinalti Jan 27 '22 at 09:12
  • Good Practice Tip: store the filename in a variable (or constant). Also maybe you don't want to create the file again if it exist but is empty, so you may want to include the `if` checking the filesize, inside the `if os.path.exists(...)` – vinalti Jan 27 '22 at 09:15

2 Answers2

0

You should use fewer conditions and more idempotent logic:

from pathlib import Path

p = Path('userInformation.txt')
p.touch()

with p.open() as f:
    contents = [l for l in f.readlines() if l.strip()]

Path.touch ensures the file exists, because that is your goal either way. Testing each line with str.strip ensures empty lines, including lines with only a linebreak, are omitted. This uses minimal calls to the filesystem and not a single if..else branch to achieve your goal.

deceze
  • 510,633
  • 85
  • 743
  • 889
0

you have 2 easy ways to check the file size:

os.path.getsize("sample.txt")

os.stat('sample.txt').st_size

warning - both will return an error if the file doesn't exists

so-

import os
def is_non_zero_file(file_path):  
    return os.path.isfile(file_path) and os.path.getsize(file_path) > 0
if is_non_zero_file(file_path):
    with open(file_path, "r") as f:
        data = f.read()
else:
    #create file
    with open(file_path, "w") as f:
        f.write("data") 
Tal Folkman
  • 2,368
  • 1
  • 7
  • 21