@@ -2,6 +2,7 @@ package switchfs
22
33import (
44 "errors"
5+ "github.com/avast/retry-go"
56 "io"
67 "io/ioutil"
78 "os"
@@ -22,6 +23,38 @@ type splitFile struct {
2223 chunkSize int64
2324}
2425
26+ type fileWrapper struct {
27+ file ReadAtCloser
28+ path string
29+ }
30+
31+ func NewFileWrapper (filePath string ) (* fileWrapper , error ) {
32+ result := fileWrapper {}
33+ result .path = filePath
34+ file , err := _openFile (filePath )
35+ if err != nil {
36+ return nil , err
37+ }
38+ result .file = file
39+ return & result , nil
40+ }
41+
42+ func (sp * fileWrapper ) ReadAt (p []byte , off int64 ) (n int , err error ) {
43+ if sp .file != nil {
44+ return sp .file .ReadAt (p , off )
45+ }
46+ return 0 , errors .New ("file is not opened" )
47+ }
48+
49+ func (sp * fileWrapper ) Close () error {
50+
51+ if sp .file != nil {
52+ return sp .file .Close ()
53+ }
54+
55+ return nil
56+ }
57+
2558func NewSplitFileReader (filePath string ) (* splitFile , error ) {
2659 result := splitFile {}
2760 index := strings .LastIndex (filePath , string (os .PathSeparator ))
@@ -51,7 +84,7 @@ func (sp *splitFile) ReadAt(p []byte, off int64) (n int, err error) {
5184 }
5285
5386 if len (sp .files ) == 0 || sp .files [part ] == nil {
54- file , _ := os . Open (path .Join (sp .path , sp .info [part ].Name ()))
87+ file , _ := _openFile (path .Join (sp .path , sp .info [part ].Name ()))
5588 sp .files [part ] = file
5689 }
5790 off = off - sp .chunkSize * int64 (part )
@@ -62,6 +95,19 @@ func (sp *splitFile) ReadAt(p []byte, off int64) (n int, err error) {
6295 return sp .files [part ].ReadAt (p , off )
6396}
6497
98+ func _openFile (path string ) (* os.File , error ) {
99+ var file * os.File
100+ var err error
101+ retry .Attempts (5 )
102+ err = retry .Do (
103+ func () error {
104+ file , err = os .Open (path )
105+ return err
106+ },
107+ )
108+ return file , err
109+ }
110+
65111func (sp * splitFile ) Close () error {
66112 for _ , file := range sp .files {
67113 if file != nil {
@@ -76,6 +122,6 @@ func OpenFile(filePath string) (ReadAtCloser, error) {
76122 if _ , err := strconv .Atoi (filePath [len (filePath )- 1 :]); err == nil {
77123 return NewSplitFileReader (filePath )
78124 } else {
79- return os . Open (filePath )
125+ return NewFileWrapper (filePath )
80126 }
81127}
0 commit comments