![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Работа с нетипизированными файлами более 2 гигабайт
rioko © (2012-06-04 13:47:00)Проблема в следующем, как перейти в конец файла посредством seek(), для записи \ чтения, если размер файла более 2.5 гигабайт, и функция
function GetFileSize(FIleName: string): integer;
var
f: file of Byte;
begin
try
AssignFile(f, FileName);
Reset(f);
result := filesize(F);
CloseFile(f);
except
result := 0;
end;
end;
.. возвращает ошибку
seek(f, getfilesize(f2))
... I\O error ...
%) (2012-07-28 12:50:00) [1]
DVM © (05.06.12 17:43) [18]
Потом так:
var
Src: TFileStream;
Dest: TStreamProgressProxy;
begin
Src := TFileStream.Create(...);
Dst := TStreamProgressProxy(TFileStream.Create(...), true);
Dst.OnProgress := ...твой обработчик ...
... тут копируй как и раньше из Src в Dst
end;
не могу ни как понять что писать после Dst.OnProgress :=
Anatoly Podgoretsky (2012-06-06 09:11:00) [2]> Германн (06.06.2012 01:39:23) [23]
Какой спортивный - диплом горит
Германн (2012-06-06 01:39:00) [3]
> rioko (05.06.12 21:36) [22]
Просто из любопытства.
А на кой .... может понадобиться
> Есть файл размером к примеру 20 мегабайт, как начать чтение
> с 15 мегабайт и записать в другой файл 5 ?
Спортивный интерес?
rioko (2012-06-05 21:36:00) [4]Огромное спасибо всем за ответы, и в особенности DVM ©!!!
:))
DVM (2012-06-05 18:05:00) [5]
> RWolf © (05.06.12 17:59) [20]
> коллбэк тоже можно инкапсулировать.
>
>
да, но по сравнению со способом выше a) не кроссплатформенно б) только для файлов
RWolf (2012-06-05 17:59:00) [6]
> [19]
коллбэк тоже можно инкапсулировать.
DVM (2012-06-05 17:45:00) [7]
> rioko (05.06.12 15:15) [15]
> Спасибо)
> А.. если раз в какое то время проверять размер целевого
> файла, и в зависимости от этого заполнять прогресс у шкалы
> - это будет очень коряво?)
коряво и работать может неверно
> RWolf © (05.06.12 15:17) [16]
>
> > [15]
>
> CopyFileEx специально для этой цели предоставляет коллбэк,
> городить велосипеды тут ни к чему, я считаю.
А ООП предоставляет инкапсуляцию и полиморфизм :)
DVM (2012-06-05 17:43:00) [8]Потом так:
var
Src: TFileStream;
Dest: TStreamProgressProxy;
begin
Src := TFileStream.Create(...);
Dst := TStreamProgressProxy(TFileStream.Create(...), true);
Dst.OnProgress := ...твой обработчик ...
... тут копируй как и раньше из Src в Dst
end;
Думаю идея ясна
DVM (2012-06-05 17:38:00) [9]
> rioko (05.06.12 14:16) [12]
> Это снова я)
> А как узнать количество считаных байт при
> 1
> TStream.CopyFrom
>
> для отображения процесса в Gauge?
Тебе нужно сделать обертку к TFileStream которая бы одновременно была наследником TStream:
////////////////////////////////////////////////////////////////////////////////
// TStreamProxy
////////////////////////////////////////////////////////////////////////////////
TStreamProxy = class(TStream)
protected
FStream: TStream;
FOwnsStream: Boolean;
public
constructor Create(AStream: TStream; AOwnsStream: Boolean = False); reintroduce;
destructor Destroy; override;
function Read(var Buffer; Count: Integer): Longint; override;
function Write(const Buffer; Count: Integer): Longint; override;
function Seek(Offset: Longint; Origin: Word): Longint; override;
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;
property Stream: TStream read FStream;
end;
////////////////////////////////////////////////////////////////////////////////
// TStreamProgressProxy
////////////////////////////////////////////////////////////////////////////////
TOnStreamProgress = procedure(Sender: TObject; ASize, ACurrentPos: Int64) of object;
TStreamProgressProxy = class(TStreamProxy)
private
FOnProgress: TOnStreamProgress;
protected
procedure DoProgress(ASize, ACurrentPos: Int64); virtual;
public
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const Buffer; Count: Longint): Longint; override;
property OnProgress: TOnStreamProgress read FOnProgress write FOnProgress;
end;
.....
////////////////////////////////////////////////////////////////////////////////
// TStreamProxy
////////////////////////////////////////////////////////////////////////////////
constructor TStreamProxy.Create(AStream: TStream; AOwnsStream: Boolean = False);
begin
inherited Create;
Assert(AStream <> nil, rsStreamMustBeAssigned);
FStream := AStream;
FOwnsStream := AOwnsStream;
end;
//------------------------------------------------------------------------------
destructor TStreamProxy.Destroy;
begin
if FOwnsStream then
FreeAndNil(FStream);
inherited Destroy;
end;
//------------------------------------------------------------------------------
function TStreamProxy.Read(var Buffer; Count: Integer): Longint;
begin
result := FStream.Read(Buffer, Count)
end;
//------------------------------------------------------------------------------
function TStreamProxy.Seek(Offset: Integer; Origin: Word): Longint;
begin
result := FStream.Seek(Offset, Origin);
end;
//------------------------------------------------------------------------------
function TStreamProxy.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
begin
result := FStream.Seek(Offset, Origin);
end;
//------------------------------------------------------------------------------
function TStreamProxy.Write(const Buffer; Count: Integer): Longint;
begin
result := FStream.Write(Buffer, Count)
end;
////////////////////////////////////////////////////////////////////////////////
// TStreamProgressProxy
////////////////////////////////////////////////////////////////////////////////
function TStreamProgressProxy.Read(var Buffer; Count: Longint): Longint;
begin
Result := inherited Read(Buffer, Count);
DoProgress(Size, Position);
end;
//------------------------------------------------------------------------------
function TStreamProgressProxy.Write(const Buffer; Count: Longint): Longint;
begin
Result := inherited Write(Buffer, Count);
DoProgress(Size, Position);
end;
//------------------------------------------------------------------------------
procedure TStreamProgressProxy.DoProgress(ASize, ACurrentPos: Int64);
begin
if Assigned(OnProgress) then
OnProgress(Self, ASize, ACurrentPos);
end;
RWolf (2012-06-05 15:17:00) [10]
> [15]
CopyFileEx специально для этой цели предоставляет коллбэк, городить велосипеды тут ни к чему, я считаю.
rioko (2012-06-05 15:15:00) [11]Спасибо)
А.. если раз в какое то время проверять размер целевого файла, и в зависимости от этого заполнять прогресс у шкалы - это будет очень коряво?)
MBo (2012-06-05 14:53:00) [12]>для отображения процесса в Gauge?
можно копировать кусками, например, по 64 мегабайта
Anatoly Podgoretsky (2012-06-05 14:37:00) [13]> rioko (05.06.2012 14:16:12) [12]
У метода нет таких событий, используй CopyFileEx
rioko (2012-06-05 14:16:00) [14]Это снова я)
А как узнать количество считаных байт приTStream.CopyFrom
для отображения процесса в Gauge? С блокрид там все понятно, там можно легко сделать, а тут я что то не нахожу этой функции...
rioko (2012-06-05 10:46:00) [15]Большое спасибо! Очень очень очень помогли! :)))
DVM (2012-06-05 10:08:00) [16]
> Есть файл размером к примеру 20 мегабайт, как начать чтение
> с 15 мегабайт и записать в другой файл 5 ? Ни как не получается
> сделать правильно..
1. Position источника передвинь на нужную величину (на 15 мегабайт).
2. function TStream.CopyFrom(Source: TStream; Count: Int64): Int64; второй параметр - число байт которое надо скопировать из источника.
rioko (2012-06-05 06:52:00) [17]
> открываешь один, открываешь второй с помощью разных TFileStream,
> потом CopyFrom
спасибо ))
Последний вопрос: Есть файл размером к примеру 20 мегабайт, как начать чтение с 15 мегабайт и записать в другой файл 5 ? Ни как не получается сделать правильно.. Конечный файл получается то копией оригинала то я не пойму по какому принципу происходит переход на позицию функцией seek (
Var
S,T: TFileStream;
Begin
//5639916
//2790300
S:=TFileStream.Create(pp+'Test.tst', fmOpenRead);
try
T:=TFileStream.Create('6f6290047313.jpg', fmCreate);
try
t.Seek(S.Size-5639916, soFromBeginning);
T.CopyFrom(S, 2790300);
finally
T.Free;
end;
finally
S.Free;
end;
End;
DVM (2012-06-04 22:52:00) [18]
> rioko (04.06.12 22:20) [7]
> В смысле, как записать один файл в другой (или в конец другого).
> .
открываешь один, открываешь второй с помощью разных TFileStream, потом CopyFrom
rioko (2012-06-04 22:20:00) [19]В смысле, как записать один файл в другой (или в конец другого)..
у меня было так:
repeat
BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
BlockWrite(ToF, Buf, NumRead, NumWritten);
until
(NumRead = 0) or (NumWritten <> NumRead);
а как в стриме сделать умане приложу( и в интернете почему то не могу найти то что надо...
rioko (2012-06-04 22:18:00) [20]Всем спасибо большое)
А не подскажите как через TFileStream грамотнее реализовать то что я пытаюсь сделать :
var
F, f2: TFileStream;
Buf: array[1..819200] of byte;
NumRead: Longint;
begin
F:=TFileStream.Create(FileName1, fmOpenRead);
F2:=TFileStream.Create(Filename2, fmCreate or fmOpenWrite or fmShareDenyNone);
repeat
F.Read(Buf, SizeOf(Buf));
f2.Write(Buf, SizeOf(Buf));
until
SizeOf(buf) = 0;
F.Free;
F2.Free;
end;