Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.03.22;
Скачать: CL | DM;

Вниз

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

 
rioko   (2012-06-04 13:47) [0]

Проблема в следующем, как перейти в конец файла посредством 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 ...


 
Ega23 ©   (2012-06-04 13:52) [1]

Через TSearchRec?


 
Palladin ©   (2012-06-04 14:43) [2]

function secretFuntionName(FileName: String): Int64;
var
 FindData: TWin32FindData;
 hFind: THandle;
begin
 Result := -1;
 hFind := FindFirstFile(PChar(FileName), FindData);
 if hFind <> INVALID_HANDLE_VALUE then
 begin
   Windows.FindClose(hFind);
   if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
   begin
     Int64Rec(Result).Lo := FindData.nFileSizeLow;
     Int64Rec(Result).Hi := FindData.nFileSizeHigh;
   end;
 end;
end;


 
DVM ©   (2012-06-04 14:49) [3]


> rioko

Имхо, взять TFileStream и не мучаться


 
MBo ©   (2012-06-04 14:52) [4]

seek в BDS 2006 принимает 32-разрядный параметр

Если нужно работать с большими файлами, то технологию, вероятно, стоит сменить, наример,  на Stream-ы, если в нужной версии они 64-битный размер поддерживают - в 2006 это так.)


 
han_malign   (2012-06-04 18:05) [5]


> seek(f, getfilesize(f2))

hFile:= CreateFile(...);
if(hFile <> INVALID_HANDLE_VALUE )then begin
   dwHigh:= 0;
   dwLow:= SetFilePointer(hFile, 0, @dwHigh, FILE_END);
   if( (dwLow <> $FFFFFFFF) or (GetLastError = ERROR_SUCCESS) )then
      fileSize:= int64(dwHigh) shl 32 or dwLow;
   ...
   CloseHandle(hFile);
end;


 
rioko   (2012-06-04 22:18) [6]

Всем спасибо большое)

А не подскажите как через 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;


 
rioko   (2012-06-04 22:20) [7]

В смысле, как записать один файл в другой (или в конец другого)..
у меня было так:


repeat
          BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
          BlockWrite(ToF, Buf, NumRead, NumWritten);
       until
         (NumRead = 0) or (NumWritten <> NumRead);


а как в стриме сделать умане приложу( и в интернете почему то не могу найти то что надо...


 
DVM ©   (2012-06-04 22:52) [8]


> rioko   (04.06.12 22:20) [7]
> В смысле, как записать один файл в другой (или в конец другого).
> .

открываешь один, открываешь второй с помощью разных TFileStream, потом CopyFrom


 
rioko   (2012-06-05 06:52) [9]


> открываешь один, открываешь второй с помощью разных 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-05 10:08) [10]


> Есть файл размером к примеру 20 мегабайт, как начать чтение
> с 15 мегабайт и записать в другой файл 5 ? Ни как не получается
> сделать правильно..

1. Position источника передвинь на нужную величину (на 15 мегабайт).
2. function TStream.CopyFrom(Source: TStream; Count: Int64): Int64; второй параметр - число байт которое надо скопировать из источника.


 
rioko   (2012-06-05 10:46) [11]

Большое спасибо! Очень очень очень помогли! :)))


 
rioko   (2012-06-05 14:16) [12]

Это снова я)
А как узнать количество считаных байт при TStream.CopyFrom
для отображения процесса в Gauge? С блокрид там все понятно, там можно легко сделать, а тут я что то не нахожу этой функции...


 
Anatoly Podgoretsky ©   (2012-06-05 14:37) [13]

> rioko  (05.06.2012 14:16:12)  [12]

У метода нет таких событий, используй CopyFileEx


 
MBo ©   (2012-06-05 14:53) [14]

>для отображения процесса в Gauge?
можно копировать кусками, например, по 64 мегабайта


 
rioko   (2012-06-05 15:15) [15]

Спасибо)
А.. если раз в какое то время проверять размер целевого файла, и в зависимости от этого заполнять прогресс у шкалы - это будет очень коряво?)


 
RWolf ©   (2012-06-05 15:17) [16]


> [15]

CopyFileEx специально для этой цели предоставляет коллбэк, городить велосипеды тут ни к чему, я считаю.


 
DVM ©   (2012-06-05 17:38) [17]


> 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;



 
DVM ©   (2012-06-05 17:43) [18]

Потом так:


var
 Src: TFileStream;
 Dest: TStreamProgressProxy;
begin
 Src := TFileStream.Create(...);
 Dst := TStreamProgressProxy(TFileStream.Create(...), true);
 Dst.OnProgress := ...твой обработчик ...
 ... тут копируй как и раньше из Src в Dst
end;


Думаю идея ясна


 
DVM ©   (2012-06-05 17:45) [19]


> rioko   (05.06.12 15:15) [15]
> Спасибо)
> А.. если раз в какое то время проверять размер целевого
> файла, и в зависимости от этого заполнять прогресс у шкалы
> - это будет очень коряво?)

коряво и работать может неверно


> RWolf ©   (05.06.12 15:17) [16]
>
> > [15]
>
> CopyFileEx специально для этой цели предоставляет коллбэк,
>  городить велосипеды тут ни к чему, я считаю.

А ООП предоставляет инкапсуляцию и полиморфизм :)


 
RWolf ©   (2012-06-05 17:59) [20]


> [19]

коллбэк тоже можно инкапсулировать.


 
DVM ©   (2012-06-05 18:05) [21]


> RWolf ©   (05.06.12 17:59) [20]


> коллбэк тоже можно инкапсулировать.
>
>

да, но по сравнению со способом выше a) не кроссплатформенно б) только для файлов


 
rioko   (2012-06-05 21:36) [22]

Огромное спасибо всем за ответы, и в особенности DVM © !!!
:))


 
Германн ©   (2012-06-06 01:39) [23]


> rioko   (05.06.12 21:36) [22]

Просто из любопытства.
А на кой .... может понадобиться
> Есть файл размером к примеру 20 мегабайт, как начать чтение
> с 15 мегабайт и записать в другой файл 5 ?

Спортивный интерес?


 
Anatoly Podgoretsky ©   (2012-06-06 09:11) [24]

> Германн  (06.06.2012 01:39:23)  [23]

Какой спортивный - диплом горит


 
%)   (2012-07-28 12:50) [25]


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 :=



Страницы: 1 вся ветка

Текущий архив: 2013.03.22;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.262 c
2-1337342744
NieL
2012-05-18 16:05
2013.03.22
функцию, которая проверяет попадание точки в прямоугольник


2-1330341762
kate158
2012-02-27 15:22
2013.03.22
выравнивание по ширине+абзац в qreport


2-1340353773
Chuck Bass
2012-06-22 12:29
2013.03.22
автоматическое обновление программы


15-1349298953
Дмитрий С
2012-10-04 01:15
2013.03.22
Как называется разъем?


3-1278051371
ford
2010-07-02 10:16
2013.03.22
плохой индекс в FireBird