Zéiksz
Zéiksz

Reputation: 695

Reading file stops at halfway

I am writing a direct x importer for Blender, to be able to open ascii .x files. For this I try to make a good Python script. I am pretty new to it, actually I just started, but got good results, except a strange ... ummm ... problem: my .x file is pretty large, exactly 3 263 453 bytes long. I will not put my whole code here, just some workaround so the problem is still visible, and in console.

>>> teszt = open('d:\DRA_ACTORDEF_T0.x','rt')
>>> teszt
<_io.TextIOWrapper name='d:\\DRA_ACTORDEF_T0.x' mode='rt' encoding='cp1250'>

then I read the file:

>>> t2 = teszt.readlines()
>>> len(t2)
39768

but then again, when I verify:

>>> import os
>>> os.fstat(teszt.fileno()).st_size
3263453

Could someone lend me a hand and tell me, what the problem is? Maybe I am to set a buffer size or such? Got no idea, how this works in Python.

I open the file same way as above, and I use .readline().

Thank you very much.

EDIT:

The code simplified. I need .readline().

fajlnev = 'd:\DRA_ACTORDEF_T0.x'

import bpy
import os

fajl = open(fajlnev, 'rt')
fajl_teljes_merete = os.fstat(fajl.fileno()).st_size

while (fajl.tell() < fajl_teljes_merete):
    print(fajl.tell(),fajl.readline())

Upvotes: 1

Views: 2439

Answers (1)

Viktor Kerkez
Viktor Kerkez

Reputation: 46636

readlines returns a list of lines, so when you do len(t2) this will return the number of lines in the file and the length of a file.

If you want the numbers to match you should do:

with open('your_file', 'rb') as f:
    data = f.read()
print(len(data))

Also if the file is encoded rt might incorrectly interpret the newlines. So it's much safer to do something like:

import io
with io.open('your_file', 'r', encoding='your_file_encoding') as f:
    lines = f.readlines()

And if you want a streaming line by line read then it's best to do:

import io
with io.open('d:\\DRA_ACTORDEF_T0.x', 'r', encoding='your_encoding') as f:
    for line in f:
        print line

This will take care of streaming and not reading the whole file into memory.

If you still want to use readline:

import io
filename = 'd:\\DRA_ACTORDEF_T0.x'
size = os.stat(filename).st_size
with io.open(filename, 'r', encoding='your_encoding') as f:
    while f.tell() < size:
         # Do what you want
         line = f.readline()

Upvotes: 1

Related Questions