Función SetFilePointer (fileapi.h)

Mueve el puntero de archivo del archivo especificado.

Esta función almacena el puntero de archivo en dos valores LONG . Para trabajar con punteros de archivo mayores que un único valor LONG , es más fácil usar la función SetFilePointerEx .

Sintaxis

DWORD SetFilePointer(
  [in]                HANDLE hFile,
  [in]                LONG   lDistanceToMove,
  [in, out, optional] PLONG  lpDistanceToMoveHigh,
  [in]                DWORD  dwMoveMethod
);

Parámetros

[in] hFile

Identificador del archivo.

El identificador de archivo debe crearse con el derecho de acceso GENERIC_READ o GENERIC_WRITE . Para obtener más información, vea Derechos de acceso y seguridad de archivos.

[in] lDistanceToMove

El orden bajo de 32 bits de un valor firmado que especifica el número de bytes para mover el puntero de archivo.

Si lpDistanceToMoveHigh no es NULL, lpDistanceToMoveHigh y lDistanceToMove forman un único valor con signo de 64 bits que especifica la distancia que se va a mover.

Si lpDistanceToMoveHigh es NULL, lDistanceToMove es un valor con signo de 32 bits. Un valor positivo para lDistanceToMove mueve el puntero de archivo hacia delante en el archivo y un valor negativo vuelve a mover el puntero de archivo.

[in, out, optional] lpDistanceToMoveHigh

Puntero al orden superior de 32 bits de la distancia de 64 bits firmada que se va a mover.

Si no necesita el orden alto de 32 bits, este puntero debe establecerse en NULL.

Cuando no es NULL, este parámetro también recibe el DWORD de orden superior del nuevo valor del puntero de archivo. Para obtener más información, vea la sección Comentarios de este tema.

[in] dwMoveMethod

Punto de partida para el movimiento del puntero de archivo.

Este parámetro puede ser uno de los valores siguientes.

Valor Significado
FILE_BEGIN
0
El punto inicial es cero o el principio del archivo.
FILE_CURRENT
1
El punto inicial es el valor actual del puntero de archivo.
FILE_END
2
El punto de partida es la posición actual del final del archivo.

Valor devuelto

Si la función se ejecuta correctamente y lpDistanceToMoveHigh es NULL, el valor devuelto es el DWORD de orden bajo del nuevo puntero de archivo. Nota Si la función devuelve un valor distinto de INVALID_SET_FILE_POINTER, la llamada a SetFilePointer se realizó correctamente. No es necesario llamar a GetLastError.

Si la función se ejecuta correctamente y lpDistanceToMoveHigh no es NULL, el valor devuelto es el DWORD de orden bajo del nuevo puntero de archivo y lpDistanceToMoveHigh contiene el DWORD de orden alto del nuevo puntero de archivo.

Si se produce un error en la función, se INVALID_SET_FILE_POINTER el valor devuelto. Para obtener información de error extendida, llame a GetLastError.

Si un nuevo puntero de archivo es un valor negativo, se produce un error en la función, el puntero de archivo no se mueve y el código devuelto por GetLastError se ERROR_NEGATIVE_SEEK.

Si lpDistanceToMoveHigh es NULL y la nueva posición del archivo no cabe en un valor de 32 bits, la función produce un error y devuelve INVALID_SET_FILE_POINTER.

Nota Dado que INVALID_SET_FILE_POINTER es un valor válido para el DWORD de orden bajo del nuevo puntero de archivo, debe comprobar el valor devuelto de la función y el código de error devuelto por GetLastError para determinar si se ha producido o no un error. Si se ha producido un error, el valor devuelto de SetFilePointer es INVALID_SET_FILE_POINTER y GetLastError devuelve un valor distinto de NO_ERROR. Para obtener un ejemplo de código que muestra cómo comprobar si hay errores, vea la sección Comentarios de este tema.
 

Comentarios

El puntero de archivo identificado por el valor del parámetro hFile no se usa para las operaciones de lectura y escritura superpuestas.

El parámetro hFile debe hacer referencia a un archivo almacenado en un dispositivo que busca; por ejemplo, un volumen de disco. No se admite la llamada a la función SetFilePointer con un identificador a un dispositivo que no busca, como una canalización o un dispositivo de comunicaciones, aunque la función SetFilePointer no devuelva un error. El comportamiento de la función SetFilePointer en este caso no está definido.

Para especificar el desplazamiento de las operaciones superpuestas

  • Utilice los miembros Offset y OffsetHigh de la estructura SUPERPUESTA .

Para determinar el tipo de archivo para hFile

Para obtener información sobre cómo determinar la posición de un puntero de archivo, vea Posicionamiento de un puntero de archivo.

Tenga cuidado al establecer un puntero de archivo en una aplicación multiproceso. Debe sincronizar el acceso a los recursos compartidos. Por ejemplo, una aplicación con subprocesos que comparten un identificador de archivo, actualiza el puntero de archivo y lee desde el archivo debe proteger esta secuencia mediante un objeto de sección crítico o un objeto de exclusión mutua. Para obtener más información, vea Critical Section Objects and Mutex Objects.

Si el identificador hFile se abre con el conjunto de marcas de FILE_FLAG_NO_BUFFERING , una aplicación solo puede mover el puntero de archivo a posiciones alineadas con sector. Una posición alineada con el sector es una posición que es un número entero múltiplo del tamaño del sector del volumen. Una aplicación puede obtener un tamaño de sector de volumen llamando a la función GetDiskFreeSpace .

Si una aplicación llama a SetFilePointer con distancia para mover valores que dan lugar a una posición no alineada con el sector y un identificador que se abre con FILE_FLAG_NO_BUFFERING, se produce un error en la función y GetLastError devuelve ERROR_INVALID_PARAMETER.

No es un error establecer un puntero de archivo en una posición más allá del final del archivo. El tamaño del archivo no aumenta hasta que se llama a la función SetEndOfFile, WriteFile o WriteFileEx . Una operación de escritura aumenta el tamaño del archivo a la posición del puntero de archivo más el tamaño del búfer escrito, lo que hace que los bytes intermedios se inicialicen en cero.

Si el valor devuelto es INVALID_SET_FILE_POINTER y si lpDistanceToMoveHigh no es NULL, una aplicación debe llamar a GetLastError para determinar si la función se ha realizado correctamente o no. En el ejemplo de código siguiente se muestra ese escenario.

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

Aunque el parámetro lpDistanceToMoveHigh se usa para manipular archivos enormes, el valor del parámetro debe establecerse al mover archivos de cualquier tamaño. Si se establece en NULL, lDistanceToMove tiene un valor máximo de 2^31–2 o 2 gigabytes menos de 2, porque todos los valores de puntero de archivo están firmados. Por lo tanto, si hay incluso una pequeña posibilidad de que el archivo aumente a ese tamaño, es mejor tratar el archivo como un archivo enorme y trabajar con punteros de archivo de 64 bits. Con la compresión de archivos en el sistema de archivos NTFS y archivos dispersos, es posible tener archivos grandes incluso si el volumen subyacente no es muy grande.

Si lpDistanceToMoveHigh no es NULL, lpDistanceToMoveHigh y lDistanceToMove forman un único valor con signo de 64 bits. El parámetro lDistanceToMove se trata como los 32 bits de orden bajo del valor, y lpDistanceToMoveHigh como los 32 bits de orden superior, lo que significa que lpDistanceToMoveHigh es una extensión de signo de lDistanceToMove.

Para mover el puntero de archivo de cero a 2 gigabytes, lpDistanceToMoveHigh debe establecerse en NULL o en una extensión de signo de lDistanceToMove. Para mover el puntero más de 2 gigabytes, use lpDistanceToMoveHigh y lDistanceToMove como una única cantidad de 64 bits. Por ejemplo, para moverse en el intervalo de 2 gigabytes a 4 gigabytes, establezca el contenido de lpDistanceToMoveHigh en cero o en –1 para una extensión de signo negativo de lDistanceToMove.

Para trabajar con punteros de archivo de 64 bits, puede declarar un long, tratarlo como la mitad superior del puntero de archivo de 64 bits y pasar su dirección en lpDistanceToMoveHigh. Esto significa que tiene que tratar dos variables diferentes como una unidad lógica, lo que puede provocar un error. Es mejor usar la estructura de LARGE_INTEGER para crear un valor de 64 bits y pasar los dos valores de 32 bits mediante los elementos adecuados de la unión.

Además, es mejor usar una función para ocultar la interfaz en SetFilePointer. En el ejemplo de código siguiente se muestra ese escenario.

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

Puede usar SetFilePointer para determinar la longitud de un archivo. Para ello, use FILE_END para dwMoveMethod y busque la ubicación cero. El desplazamiento del archivo devuelto es la longitud del archivo. Sin embargo, esta práctica puede tener efectos secundarios no deseados, por ejemplo, si no se guarda el puntero de archivo actual para que el programa pueda volver a esa ubicación. Es mejor usar GetFileSize en su lugar.

También puede usar la función SetFilePointer para consultar la posición del puntero de archivo actual. Para ello, especifique un método de movimiento de FILE_CURRENT y una distancia de cero.

En Windows 8 y Windows Server 2012, esta función es compatible con las tecnologías siguientes.

Tecnología Compatible
Protocolo Bloque de mensajes del servidor (SMB) 3.0
Conmutación por error transparente (TFO) de SMB 3.0
SMB 3.0 con recursos compartidos de archivos de escalabilidad horizontal (SO)
Sistema de archivos de Volumen compartido de clúster (CsvFS)
Sistema de archivos resistente a errores (ReFS)
 

Ejemplos

Para obtener un ejemplo de código de anexar archivos, vea Anexar un archivo a otro archivo.

Requisitos

Requisito Value
Cliente mínimo compatible Windows XP [aplicaciones de escritorio | aplicaciones para UWP]
Servidor mínimo compatible Windows Server 2003 [aplicaciones de escritorio | aplicaciones para UWP]
Plataforma de destino Windows
Encabezado fileapi.h (incluye Windows.h)
Library Kernel32.lib
Archivo DLL Kernel32.dll

Vea también

Funciones de administración de archivos

GetDiskFreeSpace

GetFileSize

GetFileType

ReadFile

ReadFileEx

SetEndOfFile

SetFilePointerEx

WriteFile

WriteFileEx