@@ -450,49 +450,70 @@ public int read(char[] cbuf) throws IOException {
450
450
*/
451
451
public List <String > readAllLines () throws IOException {
452
452
List <String > lines = new ArrayList <>();
453
- StringBuilder sb = new StringBuilder (0 );
453
+
454
+ int writePos = 0 ;
455
+ int fragPos = -1 ;
456
+ int fragLen = 0 ;
454
457
455
458
char [] cb = new char [TRANSFER_BUFFER_SIZE ];
456
459
boolean skipLF = false ;
457
460
int n ;
458
- while ((n = read (cb , 0 , cb .length )) != -1 ) {
459
- int pos = 0 ;
460
- while (pos < n ) {
461
- // find next line terminator; if none found, "term" equals "n"
461
+ while ((n = read (cb , writePos , cb .length - writePos )) != -1 ) {
462
+ int pos = writePos ;
463
+ int limit = pos + n ;
464
+ while (pos < limit ) {
465
+ // find next line terminator
462
466
int term = pos ;
463
- while (term < n ) {
467
+ while (term < limit ) {
464
468
char c = cb [term ];
465
469
if (c == '\n' || c == '\r' )
466
470
break ;
467
471
term ++;
468
472
}
469
473
470
- if (term < n ) { // line terminator
474
+ if (term < limit ) { // line terminator
471
475
boolean isCR = (cb [term ] == '\r' );
472
476
if (isCR || !(skipLF && term == pos )) {
473
477
// line terminator is a CR or an LF just after a CR
474
- if (sb . isEmpty () ) {
475
- // avoid the StringBuilder if possible
476
- lines . add ( new String ( cb , pos , term - pos )) ;
478
+ if (fragPos != - 1 ) {
479
+ lines . add ( new String ( cb , fragPos , term - fragPos ));
480
+ fragPos = - 1 ;
477
481
} else {
478
- sb .append (cb , pos , term - pos );
479
- lines .add (sb .toString ());
480
- sb .setLength (0 );
482
+ lines .add (new String (cb , pos , term - pos ));
481
483
}
482
484
}
483
485
pos = term + 1 ;
486
+ if (pos == limit )
487
+ writePos = 0 ;
484
488
skipLF = isCR ;
485
489
} else { // no line terminator
486
- sb .append (cb , pos , n - pos );
487
- pos = n ;
490
+ int len = term - pos ;
491
+ if (fragPos == -1 ) {
492
+ fragPos = pos ;
493
+ fragLen = len ;
494
+ } else {
495
+ fragLen += len ;
496
+ }
497
+ if (fragLen >= cb .length /2 ) {
498
+ // allocate larger buffer and copy chars to beginning
499
+ char [] tmp = new char [2 *cb .length ];
500
+ System .arraycopy (cb , fragPos , tmp , 0 , fragLen );
501
+ cb = tmp ;
502
+ } else if (fragPos != 0 ) {
503
+ // move fragment to beginning of buffer
504
+ System .arraycopy (cb , fragPos , cb , 0 , fragLen );
505
+ }
506
+ writePos = fragLen ;
507
+ fragPos = 0 ;
508
+ pos = limit ;
488
509
skipLF = false ;
489
510
}
490
511
}
491
512
}
492
513
493
514
// add a string if EOS terminates the last line
494
- if (! sb . isEmpty () )
495
- lines .add (sb . toString ( ));
515
+ if (fragPos != - 1 )
516
+ lines .add (new String ( cb , fragPos , fragLen ));
496
517
497
518
return Collections .unmodifiableList (lines );
498
519
}
0 commit comments