@@ -259,7 +259,7 @@ func (reader *ReaderImpl) consumeLinesFromStream(stream io.Reader) {
259259 // Preallocating the line pool and the lines slice improves large file
260260 // reading performance by 10%.
261261 linePool := linePool {}
262- if reader .FileName != nil && reader .GetLineCount () == 0 {
262+ if reader .FileName != nil && reader .GetLineCount () == 0 && isSeekableFile ( reader . FileName ) {
263263 lineCount , err := countLines (* reader .FileName )
264264 if err != nil {
265265 log .Warn ("Failed to count lines in file: " , err )
@@ -378,6 +378,11 @@ func (reader *ReaderImpl) tailFile() error {
378378 return nil
379379 }
380380
381+ if ! isSeekableFile (fileName ) {
382+ log .Debugf ("Giving up on tailing, %s is not seekable" , * fileName )
383+ return nil
384+ }
385+
381386 log .Debugf ("Tailing file %s" , * fileName )
382387
383388 for {
@@ -446,6 +451,28 @@ func (reader *ReaderImpl) tailFile() error {
446451 }
447452}
448453
454+ func isSeekableFile (fileName * string ) bool {
455+ if fileName == nil {
456+ return false
457+ }
458+
459+ file , err := os .Open (* fileName )
460+ if err != nil {
461+ return false
462+ }
463+
464+ defer func () {
465+ err := file .Close ()
466+ if err != nil {
467+ log .Debugf ("Failed to close %s while checking seekability: %s" , * fileName , err )
468+ }
469+ }()
470+
471+ _ , err = file .Seek (0 , io .SeekCurrent )
472+
473+ return err == nil
474+ }
475+
449476// NewFromStream creates a new stream reader
450477//
451478// The display name can be an empty string ("").
@@ -568,30 +595,39 @@ func NewFromTextForTesting(name string, text string) *ReaderImpl {
568595 return returnMe
569596}
570597
571- // Duplicate of moor/moor.go:TryOpen
572598func TryOpen (filename string ) error {
573599 // Try opening the file
574600 tryMe , err := os .Open (filename )
575601 if err != nil {
576602 return err
577603 }
578604
579- // Try reading a byte
580- buffer := make ([]byte , 1 )
581- _ , err = tryMe .Read (buffer )
605+ fileInfo , err := tryMe .Stat ()
606+ if err != nil {
607+ closeErr := tryMe .Close ()
608+ if closeErr != nil {
609+ return fmt .Errorf ("failed to close %s after stat error: %w" , filename , closeErr )
610+ }
611+
612+ return err
613+ }
614+
615+ if fileInfo .IsDir () {
616+ closeErr := tryMe .Close ()
617+ if closeErr != nil {
618+ return fmt .Errorf ("failed to close directory %s: %w" , filename , closeErr )
619+ }
582620
583- if err != nil && err .Error () == "EOF" {
584- // Empty file, this is fine
585- err = nil
621+ return fmt .Errorf ("%s is a directory" , filename )
586622 }
587623
588624 closeErr := tryMe .Close ()
589- if err == nil && closeErr != nil {
625+ if closeErr != nil {
590626 // Everything worked up until Close(), report the Close() error
591627 return closeErr
592628 }
593629
594- return err
630+ return nil
595631}
596632
597633// From: https://stackoverflow.com/a/52153000/473672
0 commit comments