@@ -4,18 +4,18 @@ import (
44 "context"
55 "errors"
66 "fmt"
7- "github.com/OpenListTeam/OpenList/v4/internal/conf"
8- "github.com/rclone/rclone/lib/mmap"
97 "io"
108 "math"
119 "os"
1210 "sync"
1311
12+ "github.com/OpenListTeam/OpenList/v4/internal/conf"
1413 "github.com/OpenListTeam/OpenList/v4/internal/errs"
1514 "github.com/OpenListTeam/OpenList/v4/internal/model"
1615 "github.com/OpenListTeam/OpenList/v4/pkg/buffer"
1716 "github.com/OpenListTeam/OpenList/v4/pkg/http_range"
1817 "github.com/OpenListTeam/OpenList/v4/pkg/utils"
18+ "github.com/rclone/rclone/lib/mmap"
1919 "go4.org/readerutil"
2020)
2121
@@ -137,6 +137,61 @@ func (f *FileStream) CacheFullAndWriter(up *model.UpdateProgress, writer io.Writ
137137 if writer != nil {
138138 reader = io .TeeReader (reader , writer )
139139 }
140+
141+ if f .GetSize () == 0 {
142+ if f .peekBuff == nil {
143+ f .peekBuff = & buffer.Reader {}
144+ }
145+ // 检查是否有数据
146+ buf := make ([]byte , 64 * utils .KB )
147+ n , err := io .ReadFull (reader , buf )
148+ if err == io .ErrUnexpectedEOF {
149+ if n > 0 {
150+ f .peekBuff .Append (buf [:n ])
151+ }
152+ f .size = f .peekBuff .Size ()
153+ f .Reader = f .peekBuff
154+ return f .peekBuff , nil
155+ } else if err != nil {
156+ return nil , err
157+ }
158+ f .peekBuff .Append (buf [:n ])
159+ if conf .MaxBufferLimit - n > conf .MmapThreshold && conf .MmapThreshold > 0 {
160+ m , err := mmap .Alloc (conf .MaxBufferLimit - n )
161+ if err == nil {
162+ f .Add (utils .CloseFunc (func () error {
163+ return mmap .Free (m )
164+ }))
165+ n , err = io .ReadFull (reader , m )
166+ if err == io .ErrUnexpectedEOF {
167+ if n > 0 {
168+ f .peekBuff .Append (m [:n ])
169+ }
170+ f .size = f .peekBuff .Size ()
171+ f .Reader = f .peekBuff
172+ return f .peekBuff , nil
173+ } else if err != nil {
174+ return nil , err
175+ }
176+ }
177+ }
178+
179+ tmpF , err := utils .CreateTempFile (reader , 0 )
180+ if err != nil {
181+ return nil , err
182+ }
183+ f .Add (utils .CloseFunc (func () error {
184+ return errors .Join (tmpF .Close (), os .RemoveAll (tmpF .Name ()))
185+ }))
186+ peekF , err := buffer .NewPeekFile (f .peekBuff , tmpF )
187+ if err != nil {
188+ return nil , err
189+ }
190+ f .size = peekF .Size ()
191+ f .Reader = peekF
192+ return peekF , nil
193+ }
194+
140195 f .Reader = reader
141196 return f .cache (f .GetSize ())
142197}
@@ -162,7 +217,7 @@ func (f *FileStream) RangeRead(httpRange http_range.Range) (io.Reader, error) {
162217 }
163218
164219 size := httpRange .Start + httpRange .Length
165- if f .peekBuff != nil && size <= int64 (f .peekBuff .Len ()) {
220+ if f .peekBuff != nil && size <= int64 (f .peekBuff .Size ()) {
166221 return io .NewSectionReader (f .peekBuff , httpRange .Start , httpRange .Length ), nil
167222 }
168223
@@ -179,57 +234,47 @@ func (f *FileStream) RangeRead(httpRange http_range.Range) (io.Reader, error) {
179234// 即使被写入的数据量与Buffer.Cap一致,Buffer也会扩大
180235
181236func (f * FileStream ) cache (maxCacheSize int64 ) (model.File , error ) {
182- limit := int64 (conf .MaxBufferLimit )
237+ if maxCacheSize > int64 (conf .MaxBufferLimit ) {
238+ tmpF , err := utils .CreateTempFile (f .Reader , f .GetSize ())
239+ if err != nil {
240+ return nil , err
241+ }
242+ f .Add (tmpF )
243+ f .tmpFile = tmpF
244+ f .Reader = tmpF
245+ return tmpF , nil
246+ }
183247
184248 if f .peekBuff == nil {
185249 f .peekBuff = & buffer.Reader {}
186250 f .oriReader = f .Reader
187251 }
252+ bufSize := maxCacheSize - int64 (f .peekBuff .Size ())
188253 var buf []byte
189- bufSize := 64 << 10 // 64KB as default
190- if conf .MmapThreshold > 0 && bufSize >= conf .MmapThreshold {
191- m , err := mmap .Alloc (bufSize )
254+ if conf .MmapThreshold > 0 && bufSize >= int64 (conf .MmapThreshold ) {
255+ m , err := mmap .Alloc (int (bufSize ))
192256 if err == nil {
193257 f .Add (utils .CloseFunc (func () error {
194258 return mmap .Free (m )
195259 }))
196260 buf = m
197261 }
198262 }
199-
200- var readBytes int
201- // precache first `limit` byte
202- for int64 (readBytes ) < limit {
203- if buf == nil {
204- buf = make ([]byte , bufSize )
205- }
206-
207- want := limit - int64 (readBytes )
208- if want > int64 (len (buf )) {
209- want = int64 (len (buf ))
210- }
211- n , err := f .oriReader .Read (buf [:want ])
212- if n > 0 {
213- f .peekBuff .Append (buf [:n ])
214- readBytes += n
215- }
216- if err == io .EOF {
217- f .Reader = f .peekBuff
218- f .oriReader = nil
219- // should update real file size here to solve `GetSize == 0` issue
220- f .size = int64 (readBytes )
221- return f .peekBuff , nil
222- }
263+ if buf == nil {
264+ buf = make ([]byte , bufSize )
223265 }
224- // if file is larger than MaxBufferLimit, fallback to disk
225- tmpF , err := utils .CreateTempFile (io .MultiReader (f .peekBuff , f .oriReader ), f .GetSize ())
226- if err != nil {
227- return nil , err
266+ n , err := io .ReadFull (f .oriReader , buf )
267+ if bufSize != int64 (n ) {
268+ return nil , fmt .Errorf ("failed to read all data: (expect =%d, actual =%d) %w" , bufSize , n , err )
269+ }
270+ f .peekBuff .Append (buf )
271+ if int64 (f .peekBuff .Size ()) >= f .GetSize () {
272+ f .Reader = f .peekBuff
273+ f .oriReader = nil
274+ } else {
275+ f .Reader = io .MultiReader (f .peekBuff , f .oriReader )
228276 }
229- f .Add (tmpF )
230- f .tmpFile = tmpF
231- f .Reader = tmpF
232- return tmpF , nil
277+ return f .peekBuff , nil
233278}
234279
235280func (f * FileStream ) SetTmpFile (file model.File ) {
0 commit comments