Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];

Вниз

Работа с нетипизированными файлами более 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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.078 c
15-1345368609
Дмитрий С
2012-08-19 13:30
2013.03.22
Pci-e SSD


15-1344534989
Прогер
2012-08-09 21:56
2013.03.22
Как поместить в Clipboard любой файл?


15-1351704720
Дмитрий С
2012-10-31 21:32
2013.03.22
Ком сервер в сервисе.


15-1340601785
Oleg1
2012-06-25 09:23
2013.03.22
Начинающим


15-1337956188
Pit
2012-05-25 18:29
2013.03.22
Кайт Томас, Oracle





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский