Função SetFilePointer (fileapi.h)
Move o ponteiro do arquivo especificado.
Essa função armazena o ponteiro de arquivo em dois valores LONG . Para trabalhar com ponteiros de arquivo maiores que um único valor LONG , é mais fácil usar a função SetFilePointerEx .
Sintaxe
DWORD SetFilePointer(
[in] HANDLE hFile,
[in] LONG lDistanceToMove,
[in, out, optional] PLONG lpDistanceToMoveHigh,
[in] DWORD dwMoveMethod
);
Parâmetros
[in] hFile
Um manipulador para o arquivo.
O identificador de arquivo deve ser criado com o GENERIC_READ ou GENERIC_WRITE direito de acesso. Para obter mais informações, consulte Segurança de arquivos e Direitos de Acesso.
[in] lDistanceToMove
A ordem baixa de 32 bits de um valor assinado que especifica o número de bytes para mover o ponteiro do arquivo.
Se lpDistanceToMoveHigh não for NULL, lpDistanceToMoveHigh e lDistanceToMove formarão um único valor assinado de 64 bits que especificará a distância a ser movida.
Se lpDistanceToMoveHigh for NULL, lDistanceToMove será um valor assinado de 32 bits. Um valor positivo para lDistanceToMove move o ponteiro do arquivo para frente no arquivo e um valor negativo move o ponteiro de arquivo para trás.
[in, out, optional] lpDistanceToMoveHigh
Um ponteiro para a ordem alta de 32 bits da distância assinada de 64 bits a ser movida.
Se você não precisar da ordem alta de 32 bits, esse ponteiro deverá ser definido como NULL.
Quando não é NULL, esse parâmetro também recebe a DWORD de ordem alta do novo valor do ponteiro de arquivo. Para obter mais informações, consulte a seção Comentários neste tópico.
[in] dwMoveMethod
O ponto de partida para a movimentação do ponteiro do arquivo.
Esse parâmetro pode usar um dos valores a seguir.
Retornar valor
Se a função for bem-sucedida e lpDistanceToMoveHigh for NULL, o valor retornado será o DWORD de baixa ordem do novo ponteiro de arquivo. Nota Se a função retornar um valor diferente de INVALID_SET_FILE_POINTER, a chamada para SetFilePointer terá êxito. Você não precisa chamar GetLastError.
Se a função for bem-sucedida e lpDistanceToMoveHigh não for NULL, o valor retornado será o DWORD de baixa ordem do novo ponteiro de arquivo e lpDistanceToMoveHigh conterá a DWORD de ordem alta do novo ponteiro de arquivo.
Se a função falhar, o valor retornado será INVALID_SET_FILE_POINTER. Para obter informações de erro estendidas, chame GetLastError.
Se um novo ponteiro de arquivo for um valor negativo, a função falhará, o ponteiro do arquivo não será movido e o código retornado por GetLastErrorserá ERROR_NEGATIVE_SEEK.
Se lpDistanceToMoveHigh for NULL e a nova posição do arquivo não se ajustar a um valor de 32 bits, a função falhará e retornará INVALID_SET_FILE_POINTER.
Comentários
O ponteiro de arquivo identificado pelo valor do parâmetro hFile não é usado para operações de leitura e gravação sobrepostas.
O parâmetro hFile deve se referir a um arquivo armazenado em um dispositivo em busca; por exemplo, um volume de disco. Não há suporte para chamar a função SetFilePointer com um identificador para um dispositivo que não está em busca, como um pipe ou um dispositivo de comunicação, embora a função SetFilePointer não retorne um erro. O comportamento da função SetFilePointer nesse caso é indefinido.
Para especificar o deslocamento para operações sobrepostas
- Use os membros Offset e OffsetHigh da estrutura OVERLAPPED .
Para determinar o tipo de arquivo para hFile
- Use a função GetFileType .
Tenha cuidado ao definir um ponteiro de arquivo em um aplicativo multithread. Você deve sincronizar o acesso aos recursos compartilhados. Por exemplo, um aplicativo com threads que compartilham um identificador de arquivo, atualizam o ponteiro do arquivo e leem do arquivo devem proteger essa sequência usando um objeto de seção crítico ou objeto mutex. Para obter mais informações, consulte Objetos de Seção Críticos e Objetos Mutex.
Se o identificador hFile for aberto com o sinalizador FILE_FLAG_NO_BUFFERING definido, um aplicativo poderá mover o ponteiro de arquivo apenas para posições alinhadas ao setor. Uma posição alinhada ao setor é uma posição que é um número inteiro múltiplo do tamanho do setor de volume. Um aplicativo pode obter um tamanho de setor de volume chamando a função GetDiskFreeSpace .
Se um aplicativo chamar SetFilePointer com distância para mover valores que resultam em uma posição não alinhada ao setor e um identificador aberto com FILE_FLAG_NO_BUFFERING, a função falhará e GetLastError retornará ERROR_INVALID_PARAMETER.
Não é um erro definir um ponteiro de arquivo para uma posição além do final do arquivo. O tamanho do arquivo não aumenta até que você chame a função SetEndOfFile, WriteFile ou WriteFileEx . Uma operação de gravação aumenta o tamanho do arquivo para a posição do ponteiro do arquivo mais o tamanho do buffer gravado, o que resulta na inicialização zero dos bytes intervindo.
Se o valor retornado for INVALID_SET_FILE_POINTER e se lpDistanceToMoveHigh não for NULL, um aplicativo deverá chamar GetLastError para determinar se a função foi bem-sucedida ou falhou. O exemplo de código a seguir mostra esse cenário.
// Case One: calling the function with lpDistanceToMoveHigh == NULL
// Try to move hFile file pointer some distance
DWORD dwPtr = SetFilePointer( hFile,
lDistance,
NULL,
FILE_BEGIN );
if (dwPtr == INVALID_SET_FILE_POINTER) // Test for failure
{
// Obtain the error code.
DWORD dwError = GetLastError() ;
// Deal with failure
// . . .
} // End of error handler
//
// Case Two: calling the function with lpDistanceToMoveHigh != NULL
// Try to move hFile file pointer a huge distance
DWORD dwPtrLow = SetFilePointer( hFile,
lDistLow,
&lDistHigh,
FILE_BEGIN );
// Test for failure
if ( dwPtrLow == INVALID_SET_FILE_POINTER &&
GetLastError() != NO_ERROR )
{
// Deal with failure
// . . .
} // End of error handler
Embora o parâmetro lpDistanceToMoveHigh seja usado para manipular arquivos enormes, o valor do parâmetro deve ser definido ao mover arquivos de qualquer tamanho. Se estiver definido como NULL, lDistanceToMove terá um valor máximo de 2^31-2 ou 2 gigabytes menos 2, pois todos os valores de ponteiro de arquivo são valores assinados. Portanto, se houver uma pequena chance de o arquivo aumentar para esse tamanho, é melhor tratar o arquivo como um arquivo enorme e trabalhar com ponteiros de arquivo de 64 bits. Com a compactação de arquivos no sistema de arquivos NTFS e arquivos esparsos, é possível ter arquivos grandes, mesmo que o volume subjacente não seja muito grande.
Se lpDistanceToMoveHigh não for NULL, lpDistanceToMoveHigh e lDistanceToMove formarão um único valor assinado de 64 bits. O parâmetro lDistanceToMove é tratado como a ordem baixa de 32 bits do valor e lpDistanceToMoveHigh como a ordem alta de 32 bits, o que significa que lpDistanceToMoveHigh é uma extensão de sinal de lDistanceToMove.
Para mover o ponteiro do arquivo de zero para 2 gigabytes, lpDistanceToMoveHigh deve ser definido como NULL ou uma extensão de sinal de lDistanceToMove. Para mover o ponteiro com mais de 2 gigabytes, use lpDistanceToMoveHigh e lDistanceToMove como uma única quantidade de 64 bits. Por exemplo, para mover no intervalo de 2 gigabytes a 4 gigabytes, defina o conteúdo de lpDistanceToMoveHigh como zero ou para –1 para uma extensão de sinal negativa de lDistanceToMove.
Para trabalhar com ponteiros de arquivo de 64 bits, você pode declarar um LONG, tratá-lo como a metade superior do ponteiro de arquivo de 64 bits e passar seu endereço em lpDistanceToMoveHigh. Isso significa que você precisa tratar duas variáveis diferentes como uma unidade lógica, o que pode causar um erro. É melhor usar a estrutura LARGE_INTEGER para criar um valor de 64 bits e passar os dois valores de 32 bits usando os elementos apropriados da união.
Além disso, é melhor usar uma função para ocultar a interface para SetFilePointer. O exemplo de código a seguir mostra esse cenário.
__int64 myFileSeek (HANDLE hf, __int64 distance, DWORD MoveMethod)
{
LARGE_INTEGER li;
li.QuadPart = distance;
li.LowPart = SetFilePointer (hf,
li.LowPart,
&li.HighPart,
MoveMethod);
if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError()
!= NO_ERROR)
{
li.QuadPart = -1;
}
return li.QuadPart;
}
Você pode usar SetFilePointer para determinar o comprimento de um arquivo. Para fazer isso, use FILE_END para dwMoveMethod e procure o local zero. O deslocamento de arquivo retornado é o comprimento do arquivo. No entanto, essa prática pode ter efeitos colaterais não intencionais, por exemplo, falha ao salvar o ponteiro de arquivo atual para que o programa possa retornar a esse local. Em vez disso, é melhor usar GetFileSize .
Você também pode usar a função SetFilePointer para consultar a posição do ponteiro do arquivo atual. Para fazer isso, especifique um método de movimentação de FILE_CURRENT e uma distância de zero.
No Windows 8 e Windows Server 2012, essa função é compatível com as tecnologias a seguir.
Tecnologia | Com suporte |
---|---|
Protocolo SMB (SMB) 3.0 | Sim |
TFO (Failover transparente) do SMB 3.0 | Sim |
SMB 3.0 com compartilhamentos de arquivos de expansão (SO) | Sim |
Sistema de arquivos de Volume Compartilhado Clusterizado (CsvFS) | Sim |
ReFS (Sistema de Arquivos Resiliente) | Sim |
Exemplos
Para obter um exemplo de código de anexação de arquivos, consulte Anexando um arquivo a outro arquivo.
Requisitos
Requisito | Valor |
---|---|
Cliente mínimo com suporte | Windows XP [aplicativos da área de trabalho | aplicativos UWP] |
Servidor mínimo com suporte | Windows Server 2003 [aplicativos da área de trabalho | Aplicativos UWP] |
Plataforma de Destino | Windows |
Cabeçalho | fileapi.h (inclua Windows.h) |
Biblioteca | Kernel32.lib |
DLL | Kernel32.dll |