file.read() doesn't read the whole file
Sreejith K
sreejithemk at gmail.com
Sat Mar 21 01:25:58 EDT 2009
class MedusaFile(object):
def __init__(self, path, flags, *mode):
global METHOD
global NORMAL
global SNAP
global FRESH_SNAP
self.path = path
tf.writelines("File initiating..\n")
self.file = os.fdopen(os.open("." + path, flags, *mode),flag2mode
(flags))
self.fd = self.file.fileno()
curdir = GetDirPath('.' + path)
self.snapdir = '.' + path + '_snaps'
self.snap_cnt = 0
if os.path.exists(self.snapdir):
self.snap_cnt = len(os.listdir(self.snapdir))
METHOD = SNAP
elif FRESH_SNAP == 1:
self.snap_cnt += 1
os.mkdir(self.snapdir)
os.mkdir(self.snapdir+'/snap%s' % repr(self.snap_cnt))
METHOD = SNAP
FRESH_SNAP = 0
tf.writelines("File initiated..\n")
def read(self, length, offset):
global METHOD
global NORMAL
global SNAP
tf.writelines("Read length: %d offset: %d\n" % (length,offset))
blk_num = offset/4096
no_blks = length/4096 + 1
blocks = []
block_read = False
## Read form the Base File (Snap 1)
if METHOD == NORMAL:
self.file.seek(offset)
tf.writelines("Normal read\n")
return self.file.read(length)
## Read blocks from the snapshots
else:
snap_list = range(self.snap_cnt)
rev_snap_list = snap_list
rev_snap_list.reverse()
for i in snap_list:
blocks.append(os.listdir(self.snapdir+'/snap%s' % repr(i+1))) ##
list of blocks in the current snapshot
off = offset
bend = 0
data = ''
for block in range(blk_num,blk_num+no_blks): ## loop through the
blocks which are to be read
for i in rev_snap_list: ## loop through snapshots (starting from
latest snap)
tf.writelines('Snapshot %d opened..\n' % i)
if repr(block) in blocks[i]: ## Check if it is in the snapshot
tf.writelines("Snap read\n")
self.snap = open(self.snapdir + '/snap%d/%d' % (i+1,
block),'r')
self.snap.seek(off%4096)
bend = 4096-(off%4096)
block_read = True
if length-bend <= 0: ## if only a part of block file is to be
read (i.e. not till the end of block file)
tf.writelines("Partial read from snap \n")
data = self.snap.read(length)
self.snap.close()
break
tf.writelines("Full block read from snap\n")
data += self.snap.read(bend)
length -= bend
off = 4096
self.snap.close()
break
tf.writelines("Block not in snap\n")
if block_read:
block_read = False
continue
## otherwise the block should be in the base file itself. So,
read from there
tf.writelines("Reading from Base File\n")
self.file.seek(block*4096 + off%4096)
bend = 4096-(off%4096)
if length-bend <= 0: ## if only a part of a block is to be read
(not till the end of the block)
data = self.file.read(length)
break
data += self.file.read(bend)
length -= bend
off = 4096
return data
This is the filesystem class for files. Whenever a read occurs an
instance is created and read function is called. In my example when
accessing a file named 'mango.txt' it checks for mango.txt_snaps/snap1
dirctory and open file '0' as self.snap. But the read() returns (i.e
data) a small part....
Almost all the code worked weird in this example. Apart from read(),
the break and continue also works weird. When opening the file
'mango.txt' the following output is written by tf (an output file).
Here METHOD is not NORMAL, self.snap_cnt is 1, blocks is [['0']]
File initiating..
File initiated..
Read length: 4096 offset: 0
Snapshot 0 opened..
Snap read
Partial read from snap
Snapshot 0 opened..
Block not in snap
Reading from Base File
See the weirdness of continue and break here ?(loop was supposed to
loop only once as rev_snap_list contains 0 only)
More information about the Python-list
mailing list