Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Файловая система
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 30.01.2012, 20:34
ProDaNTe ProDaNTe вне форума
Новичок
 
Регистрация: 25.12.2011
Сообщения: 75
Репутация: 10
По умолчанию Установить позицию чтения\записи

Помогите плиз надо установить позицию чтения записи в файле, но все процедуры и функции в delphi известные мне Seek и т.д. работают только с LongInt т.е. с файлами не более 2.7 Гб а у меня файл больше.
Ответить с цитированием
  #2  
Старый 30.01.2012, 21:18
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Используй TFileStream. Там позиция - Int64.
Ответить с цитированием
  #3  
Старый 30.01.2012, 21:20
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Читай про функцию SetFilePointer - WinAPI. Допустимый размер файла 2^64 - 2, должно хватить.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #4  
Старый 30.01.2012, 21:30
ProDaNTe ProDaNTe вне форума
Новичок
 
Регистрация: 25.12.2011
Сообщения: 75
Репутация: 10
По умолчанию

SetFilePointer тоже integer у меня Delphi XE,


Как через TFileStream будет выглядеть?
AssignFile(f,tex);
Reset(f,1);
Seek(f, RestartPos);
BlockWrite(f, fBuf, ReadLen);
Ответить с цитированием
  #5  
Старый 30.01.2012, 21:41
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Цитата:
Сообщение от ProDaNTe
SetFilePointer тоже integer у меня Delphi XE,
Справку нужно внимательнее читать, там два параметра для задачи смещения и, если не указать второй, то будет только Longint. И не плохо, если посчитаете значение 2^64 - 2 байт, оно вам всё скажет.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #6  
Старый 30.01.2012, 21:55
ProDaNTe ProDaNTe вне форума
Новичок
 
Регистрация: 25.12.2011
Сообщения: 75
Репутация: 10
По умолчанию

Извени опиши как ей пользоваться справки нет!
Ответить с цитированием
  #7  
Старый 30.01.2012, 22:04
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Да не побъёт меня модератор:
Код:
The SetFilePointer function moves the file pointer of an open file. 

DWORD SetFilePointer(

    HANDLE hFile,	// handle of file 
    LONG lDistanceToMove,	// number of bytes to move file pointer 
    PLONG lpDistanceToMoveHigh,	// address of high-order word of distance to move  
    DWORD dwMoveMethod 	// how to move 
   );	
 

Parameters

hFile

Identifies the file whose file pointer is to be moved. The file handle must have been created with GENERIC_READ or GENERIC_WRITE access to the file. 

lDistanceToMove

Specifies the number of bytes to move the file pointer. A positive value moves the pointer forward in the file and a negative value moves it backward. 

lpDistanceToMoveHigh

Points to the high-order word of the 64-bit distance to move. If the value of this parameter is NULL, SetFilePointer can operate only on files whose maximum size is 2^32 - 2. If this parameter is specified, the maximum file size is 2^64 - 2. This parameter also receives the high-order word of the new value of the file pointer. 

dwMoveMethod

Specifies the starting point for the file pointer move. This parameter can be one of the following values: 

Value	Meaning
FILE_BEGIN	The starting point is zero or the beginning of the file. If FILE_BEGIN is specified, DistanceToMove is interpreted as an unsigned location for the new file pointer.
FILE_CURRENT	The current value of the file pointer is the starting point.
FILE_END	The current end-of-file position is the starting point.
 

Return Values

If the SetFilePointer function succeeds, the return value is the low-order doubleword of the new file pointer, and if lpDistanceToMoveHigh is not NULL, the function puts the high-order doubleword of the new file pointer into the LONG pointed to by that parameter. 
If the function fails and lpDistanceToMoveHigh is NULL, the return value is 0xFFFFFFFF. To get extended error information, call GetLastError. 
If the function fails, and lpDistanceToMoveHigh is non-NULL, the return value is 0xFFFFFFFF and GetLastError will return a value other than NO_ERROR. 

Remarks

You cannot use the SetFilePointer function with a handle to a nonseeking device, such as a pipe or a communications device. To determine the file type for hFile, use the GetFileType function. 
You should be careful when setting the file pointer in a multithreaded application. For example, an application whose threads share a file handle, update the file pointer, and read from the file must protect this sequence by using a critical section object or mutex object. For more information about these objects, see Mutex Objects and Critical Section Objects.

If the hFile file handle was opened with the FILE_FLAG_NO_BUFFERING flag set, an application can move the file pointer only to sector-aligned positions. A sector-aligned position is a position that is a whole number multiple of the volume's sector size. An application can obtain a volume's sector size by calling the GetDiskFreeSpace function. If an application calls SetFilePointer with distance-to-move values that result in a position that is not sector-aligned and a handle that was opened with FILE_FLAG_NO_BUFFERING, the function fails, and GetLastError returns ERROR_INVALID_PARAMETER.

Note that if the return value is 0xFFFFFFFF and if lpDistanceToMoveHigh is non-NULL, an application must call GetLastError to determine whether the function has succeeded or failed. The following sample code illustrates this point: 

//  
// Case One: calling the function with 
//           lpDistanceToMoveHigh == NULL 
 
// try to move hFile's file pointer some distance 
dwPointer = SetFilePointer (hFile, lDistance, 
                            NULL, FILE_BEGIN) ; 
 
// if we failed ... 
if (dwPointer == 0xFFFFFFFF) { 
 
    // obtain the error code 
    dwError = GetLastError() ; 
 
    // deal with that failure 
    . 
    . 
    . 
 
    } // end of error handler 
 
 
// 
// Case Two: calling the function with 

//           lpDistanceToMoveHigh != NULL 
 
// try to move hFile's file pointer some huge distance 
dwPointerLow = SetFilePointer (hFile, lDistanceLow, 
                               & lDistanceHigh, FILE_BEGIN) ; 
 
// if we failed ... 
if (dwPointerLow == 0xFFFFFFFF 
    && 
    (dwError = GetLastError()) != NO_ERROR ){ 
 
    // deal with that failure 
    . 
    . 
    . 
 
    } // end of error handler 
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #8  
Старый 30.01.2012, 22:51
ProDaNTe ProDaNTe вне форума
Новичок
 
Регистрация: 25.12.2011
Сообщения: 75
Репутация: 10
По умолчанию

restartpos у меня 5000000000
p:= SetFilePointer(h,0,@RestartPos, FILE_BEGIN);
а он мне выдаёт 4294967295
Ответить с цитированием
  #9  
Старый 30.01.2012, 23:04
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

И правильно делает, 4294967295 = $FFFF FFFF. Ты превысил предел, так как не использовал первый параметр:
Код:
  restartpos := 1;
  SetFilePointer(h, $2A05F200, @RestartPos, FILE_BEGIN);
1 параметр, младшая величина - $2A05F200
2 параметр, указатель на старшую величину - 1
в сумме $12A05F200 = 5000000000
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
Этот пользователь сказал Спасибо angvelem за это полезное сообщение:
ProDaNTe (31.01.2012)
  #10  
Старый 31.01.2012, 09:52
ProDaNTe ProDaNTe вне форума
Новичок
 
Регистрация: 25.12.2011
Сообщения: 75
Репутация: 10
По умолчанию

Сделал вот так
Код:
 m:=1;
   nac:=RestartPos-$FFFFFFFF-1;
  h:= CreateFileA(PAnsiChar(tex),GENERIC_Write,FILE_SHARE_READ,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
   p:= SetFilePointer(h,nac,@m, FILE_BEGIN);
Но теперь не работает
Код:
WriteFile(h, fBuf, SizeOf(fBuf), ReadLen,nil);
fBuf: array[1..1024] of byte;
Ответить с цитированием
  #11  
Старый 31.01.2012, 10:11
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

что говорит GetLastError?
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #12  
Старый 31.01.2012, 16:55
ProDaNTe ProDaNTe вне форума
Новичок
 
Регистрация: 25.12.2011
Сообщения: 75
Репутация: 10
По умолчанию

Ну говорит типа 6 - неправильный хэндл?
Ответить с цитированием
  #13  
Старый 31.01.2012, 21:44
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Мне непонятно совместное использование флагов GENERIC_Write и FILE_SHARE_READ. Что это должно получиться? И как объявлена переменная h?
Код:
var
  h : HFILE;
begin
  m := 1;
  nac := RestartPos - $FFFFFFFF - 1;
  h := CreateFileA(PAnsiChar(tex), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, NIL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if h <> INVALID_HANDLE_VALUE then
    p := SetFilePointer(h, nac, @m, FILE_BEGIN);
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.

Последний раз редактировалось angvelem, 31.01.2012 в 21:46.
Ответить с цитированием
  #14  
Старый 31.01.2012, 22:11
ProDaNTe ProDaNTe вне форума
Новичок
 
Регистрация: 25.12.2011
Сообщения: 75
Репутация: 10
По умолчанию

Цитата:
Мне непонятно совместное использование флагов GENERIC_Write и FILE_SHARE_READ

GENERIC_WRITE - получить доступ к записи

dwShareMode - флаги, указывающие на то, как создаваемый (открываемый) объект должен разделять достум между процессами. Это значит, как будет делится доступ к файлу с другими прогами если они тоже попытаются открыть этот файл. Параметр может принимать значения (можно использовать одно или сразу несколько):
FILE_SHARE_READ - другим процессам разрешается только читать файл

h:Cardinal;
Ответить с цитированием
  #15  
Старый 31.01.2012, 22:27
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Я знаю значение и область применения флагов. Непонятно зачем кому-то отдавать ещё на чтение.
Попробую на iso-шке.

Долго подбирал позицию, где не пустые байты.
Код:
program test;

{$APPTYPE CONSOLE}

uses
  Windows, Messages;

var
  h       : HFILE;
  buf     : array[0..4095] of Byte;
  Read, p : DWORD;
  m, nac  : DWORD;
begin
  m := 1;
  nac := 4800000000 - $FFFFFFFF - 1;
  h := CreateFileA('cinema4D_11.008.iso', GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, NIL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if h <> INVALID_HANDLE_VALUE then
  begin
    p := SetFilePointer(h, nac, @m, FILE_BEGIN);
    if p <> 0 then
      ReadFile(h, Buf, SizeOf(Buf), Read, NIL);
  end;
end.
нормально счталось, писать по понятной причине в файл не стал.

Решил протестировать до конца на копии:
Код:
program test;

{$APPTYPE CONSOLE}

uses
  Windows, Messages;

var
  h       : HFILE;
  buf     : array[0..4095] of AnsiChar;
  Read, p : DWORD;
  m, nac  : DWORD;
begin
  m := 1;
  nac := 4800000000 - $FFFFFFFF - 1;
  h := CreateFileA('cinema4D.iso', GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, NIL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if h <> INVALID_HANDLE_VALUE then
  begin
    p := SetFilePointer(h, nac, @m, FILE_BEGIN);
    if p <> 0 then
    begin
      ReadFile(h, Buf, SizeOf(Buf), Read, NIL);
      lstrcpy(Buf, 'Вася Питерский');
      p := SetFilePointer(h, nac, @m, FILE_BEGIN);
      if p <> 0 then
        WriteFile(h, Buf, SizeOf(Buf), Read, NIL);
    end;
  end;
end.
читается и пишется нормально.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.

Последний раз редактировалось angvelem, 31.01.2012 в 23:21.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 08:29.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter