You've already forked lazarus-ccr
fpspreadsheet: Fix buffered stream reading speed issues.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3904 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -10,7 +10,7 @@ program excel8write;
|
|||||||
{$mode delphi}{$H+}
|
{$mode delphi}{$H+}
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, fpspreadsheet, fpsRPN, xlsbiff8, fpsTypes, fpsHelpers;
|
Classes, SysUtils, fpspreadsheet, fpsRPN, xlsbiff8, fpsTypes, fpsCell;
|
||||||
|
|
||||||
const
|
const
|
||||||
Str_First = 'First';
|
Str_First = 'First';
|
||||||
|
@ -60,7 +60,6 @@
|
|||||||
</Target>
|
</Target>
|
||||||
<SearchPaths>
|
<SearchPaths>
|
||||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||||
<OtherUnitFiles Value="C:\Users\Rik\Downloads\udata\"/>
|
|
||||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||||
</SearchPaths>
|
</SearchPaths>
|
||||||
<Parsing>
|
<Parsing>
|
||||||
|
@ -8447,10 +8447,18 @@ procedure TsCustomSpreadReader.ReadFromFile(AFileName: string; AData: TsWorkbook
|
|||||||
var
|
var
|
||||||
InputFile: TStream;
|
InputFile: TStream;
|
||||||
begin
|
begin
|
||||||
|
|
||||||
if (boBufStream in Workbook.Options) then
|
if (boBufStream in Workbook.Options) then
|
||||||
InputFile := TBufStream.Create(AFileName, fmOpenRead + fmShareDenyNone)
|
InputFile := TBufStream.Create(AFileName, fmOpenRead + fmShareDenyNone)
|
||||||
else
|
else
|
||||||
InputFile := TFileStream.Create(AFileName, fmOpenRead + fmShareDenyNone);
|
InputFile := TFileStream.Create(AFileName, fmOpenRead + fmShareDenyNone);
|
||||||
|
{
|
||||||
|
//<--
|
||||||
|
InputFile := TMemoryStream.Create;
|
||||||
|
TMemoryStream(InputFile).LoadFromFile(AFilename);
|
||||||
|
//--->
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
ReadFromStream(InputFile, AData);
|
ReadFromStream(InputFile, AData);
|
||||||
finally
|
finally
|
||||||
|
@ -18,6 +18,8 @@ type
|
|||||||
private
|
private
|
||||||
FFileStream: TFileStream;
|
FFileStream: TFileStream;
|
||||||
FMemoryStream: TMemoryStream;
|
FMemoryStream: TMemoryStream;
|
||||||
|
FFileStreamPos: Int64;
|
||||||
|
FFileStreamSize: Int64;
|
||||||
FBufWritten: Boolean;
|
FBufWritten: Boolean;
|
||||||
FBufSize: Int64;
|
FBufSize: Int64;
|
||||||
FKeepTmpFile: Boolean;
|
FKeepTmpFile: Boolean;
|
||||||
@ -144,10 +146,13 @@ begin
|
|||||||
if FFileStream = nil then begin
|
if FFileStream = nil then begin
|
||||||
if FFileName = '' then FFileName := ChangeFileExt(GetTempFileName, '.~abc');
|
if FFileName = '' then FFileName := ChangeFileExt(GetTempFileName, '.~abc');
|
||||||
FFileStream := TFileStream.Create(FFileName, FFileMode);
|
FFileStream := TFileStream.Create(FFileName, FFileMode);
|
||||||
|
FFileStreamSize := FFileStream.Size;
|
||||||
|
FFileStreamPos := 0;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Reads FBufSize bytes from the stream into the buffer }
|
{ Reads FBufSize bytes from the stream into the buffer.
|
||||||
|
Called when reading. }
|
||||||
procedure TBufStream.FillBuffer;
|
procedure TBufStream.FillBuffer;
|
||||||
var
|
var
|
||||||
p, n: Int64;
|
p, n: Int64;
|
||||||
@ -156,19 +161,23 @@ begin
|
|||||||
FMemoryStream.Clear;
|
FMemoryStream.Clear;
|
||||||
FMemoryStream.Position := 0;
|
FMemoryStream.Position := 0;
|
||||||
FFileStream.Position := p;
|
FFileStream.Position := p;
|
||||||
n := Min(FBufSize, FFileStream.Size - p);
|
n := Min(FBufSize, FFileStreamSize - p);
|
||||||
FMemoryStream.CopyFrom(FFileStream, n);
|
FMemoryStream.CopyFrom(FFileStream, n);
|
||||||
FMemoryStream.Position := 0;
|
FMemoryStream.Position := 0;
|
||||||
FFileStream.Position := p;
|
FFileStream.Position := p; // The file stream ends where the memorystream begins!
|
||||||
|
FFileStreamPos := p;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Flushes the contents of the memory stream to file }
|
{ Flushes the contents of the memory stream to file
|
||||||
|
Called when writing. }
|
||||||
procedure TBufStream.FlushBuffer;
|
procedure TBufStream.FlushBuffer;
|
||||||
begin
|
begin
|
||||||
if (FMemoryStream.Size > 0) and not FBufWritten and IsWritingMode then begin
|
if (FMemoryStream.Size > 0) and not FBufWritten and IsWritingMode then begin
|
||||||
FMemoryStream.Position := 0;
|
FMemoryStream.Position := 0;
|
||||||
CreateFileStream;
|
CreateFileStream;
|
||||||
FFileStream.CopyFrom(FMemoryStream, FMemoryStream.Size);
|
FFileStream.CopyFrom(FMemoryStream, FMemoryStream.Size);
|
||||||
|
FFileStreamPos := FFileStream.Position;
|
||||||
|
FFileStreamSize := FFileStream.Size;
|
||||||
FMemoryStream.Clear;
|
FMemoryStream.Clear;
|
||||||
FBufWritten := true;
|
FBufWritten := true;
|
||||||
end;
|
end;
|
||||||
@ -181,7 +190,8 @@ begin
|
|||||||
if FFileStream = nil then
|
if FFileStream = nil then
|
||||||
Result := FMemoryStream.Position
|
Result := FMemoryStream.Position
|
||||||
else
|
else
|
||||||
Result := FFileStream.Position + FMemoryStream.Position;
|
// Result := FFileStream.Position + FMemoryStream.Position;
|
||||||
|
Result := FFileStreamPos + FMemoryStream.Position;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Returns the size of the stream. Both memory and file streams are considered
|
{ Returns the size of the stream. Both memory and file streams are considered
|
||||||
@ -192,14 +202,15 @@ var
|
|||||||
begin
|
begin
|
||||||
if IsWritingMode then begin
|
if IsWritingMode then begin
|
||||||
if FFileStream <> nil then
|
if FFileStream <> nil then
|
||||||
n := FFileStream.Size
|
n := FFileStreamSize
|
||||||
|
// n := FFileStream.Size
|
||||||
else
|
else
|
||||||
n := 0;
|
n := 0;
|
||||||
if n = 0 then n := FMemoryStream.Size;
|
if n = 0 then n := FMemoryStream.Size;
|
||||||
Result := Max(n, GetPosition);
|
Result := Max(n, GetPosition);
|
||||||
end else begin
|
end else begin
|
||||||
CreateFileStream;
|
CreateFileStream;
|
||||||
Result := FFileStream.Size;
|
Result := FFileStreamSize;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -238,6 +249,7 @@ begin
|
|||||||
CreateFileStream;
|
CreateFileStream;
|
||||||
if IsWritingMode then begin
|
if IsWritingMode then begin
|
||||||
Result := FFileStream.Read(Buffer, Count);
|
Result := FFileStream.Read(Buffer, Count);
|
||||||
|
FFileStreamPos := FFileStream.Position;
|
||||||
end else begin
|
end else begin
|
||||||
FillBuffer;
|
FillBuffer;
|
||||||
Result := FMemoryStream.Read(Buffer, Count);
|
Result := FMemoryStream.Read(Buffer, Count);
|
||||||
@ -256,6 +268,7 @@ begin
|
|||||||
FlushBuffer;
|
FlushBuffer;
|
||||||
FFileStream.Position := p;
|
FFileStream.Position := p;
|
||||||
Result := FFileStream.Read(Buffer, Count);
|
Result := FFileStream.Read(Buffer, Count);
|
||||||
|
FFileStreamPos := p + Count;
|
||||||
end else begin
|
end else begin
|
||||||
FillBuffer;
|
FillBuffer;
|
||||||
Result := FMemoryStream.Read(Buffer, Count);
|
Result := FMemoryStream.Read(Buffer, Count);
|
||||||
@ -285,10 +298,12 @@ begin
|
|||||||
CreateFileStream;
|
CreateFileStream;
|
||||||
|
|
||||||
// case #2: New position is within buffer, file stream exists
|
// case #2: New position is within buffer, file stream exists
|
||||||
if (newPos >= FFileStream.Position) and (newPos < FFileStream.Position + FMemoryStream.Size)
|
// if (newPos >= FFileStream.Position) and (newPos < FFileStream.Position + FMemoryStream.Size)
|
||||||
|
if (newPos >= FFileStreamPos) and (newPos < FFileStreamPos + FMemoryStream.Size)
|
||||||
then begin
|
then begin
|
||||||
FMemoryStream.Position := newPos - FFileStream.Position;
|
// FMemoryStream.Position := newPos - FFileStream.Position;
|
||||||
Result := FMemoryStream.Position;
|
FMemoryStream.Position := newPos - FFileStreamPos;
|
||||||
|
Result := newpos; //FMemoryStream.Position;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -296,6 +311,7 @@ begin
|
|||||||
if IsWritingMode then
|
if IsWritingMode then
|
||||||
FlushBuffer;
|
FlushBuffer;
|
||||||
FFileStream.Position := newPos;
|
FFileStream.Position := newPos;
|
||||||
|
FFileStreamPos := newPos;
|
||||||
FMemoryStream.Position := 0;
|
FMemoryStream.Position := 0;
|
||||||
if not IsWritingMode then
|
if not IsWritingMode then
|
||||||
FillBuffer;
|
FillBuffer;
|
||||||
@ -306,17 +322,20 @@ var
|
|||||||
savedPos: Int64;
|
savedPos: Int64;
|
||||||
begin
|
begin
|
||||||
// Case #1: Bytes fit into buffer
|
// Case #1: Bytes fit into buffer
|
||||||
if FMemoryStream.Position + ACount < FBufSize then begin
|
if FMemoryStream.Position + ACount < FBufSize then
|
||||||
|
begin
|
||||||
Result := FMemoryStream.Write(ABuffer, ACount);
|
Result := FMemoryStream.Write(ABuffer, ACount);
|
||||||
FBufWritten := false;
|
FBufWritten := false;
|
||||||
exit;
|
end else
|
||||||
end;
|
|
||||||
|
|
||||||
// Case #2: Buffer would overflow
|
// Case #2: Buffer would overflow
|
||||||
savedPos := GetPosition;
|
begin;
|
||||||
FlushBuffer;
|
savedPos := GetPosition;
|
||||||
FFileStream.Position := savedPos;
|
FlushBuffer;
|
||||||
Result := FFileStream.Write(ABuffer, ACount);
|
FFileStream.Position := savedPos;
|
||||||
|
Result := FFileStream.Write(ABuffer, ACount);
|
||||||
|
FFileStreamPos := savedPos + ACount;
|
||||||
|
FFileStreamSize := FFileStream.Size;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,6 +69,7 @@
|
|||||||
<Unit6>
|
<Unit6>
|
||||||
<Filename Value="internaltests.pas"/>
|
<Filename Value="internaltests.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="internaltests"/>
|
||||||
</Unit6>
|
</Unit6>
|
||||||
<Unit7>
|
<Unit7>
|
||||||
<Filename Value="formattests.pas"/>
|
<Filename Value="formattests.pas"/>
|
||||||
|
Reference in New Issue
Block a user