Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Работа с нетипизированными файлами более 2 гигабайт


Страницы:   1 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;


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо