@@ -386,8 +386,10 @@ def _read(cls, fileobj, header, buffer_size=4):
386
386
"""
387
387
dtype = header ["_dtype" ]
388
388
389
- #align batch_size to be multiple of 3 within the specified buffer size
390
- batch_size = int (buffer_size * MEGABYTE / dtype .itemsize / 3 ) * 3
389
+ coordinate_size = 3 * dtype .itemsize
390
+ # Make buffer_size an integer and a multiple of coordinate_size.
391
+ buffer_size = int (buffer_size * MEGABYTE )
392
+ buffer_size += coordinate_size - (buffer_size % coordinate_size )
391
393
392
394
with Opener (fileobj ) as f :
393
395
start_position = f .tell ()
@@ -397,38 +399,39 @@ def _read(cls, fileobj, header, buffer_size=4):
397
399
398
400
eof = False
399
401
n_streams = 0
400
- leftover = np .empty ((0 ,3 ), dtype = '<f4' )
402
+ leftover = np .empty ((0 , 3 ), dtype = '<f4' )
401
403
while not eof :
404
+ buff = bytearray (buffer_size )
405
+ n_read = f .readinto (buff )
406
+ eof = n_read != buffer_size
407
+ if eof :
408
+ buff = buff [:n_read ]
402
409
403
410
# read raw files from file
404
- raw_values = np .fromfile (f .fobj , dtype , batch_size )
405
- if len (raw_values ) < batch_size :
406
- eof = True
411
+ raw_values = np .frombuffer (buff , dtype = dtype )
407
412
408
- # Convert raw_values into a list of little-endian tuples (for x,y,z coord)
409
- coords = raw_values .astype ('<f4' , copy = False ).reshape ([ - 1 , 3 ] )
413
+ # Convert raw_values into a list of little-endian triples (for x,y,z coord)
414
+ coords = raw_values .astype ('<f4' , copy = False ).reshape (( - 1 , 3 ) )
410
415
411
- # find stream delimiter locations (all NaNs)
412
- delims = np .where (np .all (np .isnan (coords ), axis = 1 ))[0 ]
416
+ # Find stream delimiter locations (all NaNs)
417
+ delims = np .where (np .isnan (coords ).all (axis = 1 ))[0 ]
418
+
419
+ if leftover .size :
420
+ delims += leftover .shape [0 ]
421
+ coords = np .vstack ((leftover , coords ))
413
422
414
- # for each delimiters, yeild new streams
415
423
begin = 0
416
- for i in range (0 , len (delims )):
417
- end = delims [i ]
418
- if i == 0 :
419
- stream = np .vstack ((leftover , coords [begin :end ]))
420
- else :
421
- stream = coords [begin :end ]
422
- leftover = np .empty ((0 ,3 ), dtype = '<f4' )
423
- yield stream
424
- n_streams += 1
425
-
426
- begin = end + 1 #skip the delimiter
424
+ for delim in delims :
425
+ pts = coords [begin :delim ]
426
+ if pts .size :
427
+ yield coords [begin :delim ]
428
+ n_streams += 1
429
+ begin = delim + 1
427
430
428
431
# the rest gets appended to the leftover
429
- leftover = np . vstack (( leftover , coords [begin :]))
432
+ leftover = coords [begin :]
430
433
431
- if not np . all ( np .isinf (leftover ), axis = 1 ):
434
+ if not ( leftover . shape == ( 1 , 3 ) and np .isinf (leftover ). all () ):
432
435
raise DataError ("Expecting end-of-file marker 'inf inf inf'" )
433
436
434
437
# In case the 'count' field was not provided.
0 commit comments