Helpers – File – Archivos
Libreria para la ulización de archivos de texto o binario. Detectar propiedades de los archivos, renombrar, eliminar y copiar archivos.
/** * HelperFile.php * @author Code Develium */ namespace Helpers; use Exception; /** * Class HelperFile */ abstract class HelpFile { /** * Escribe texto en un archivo. Se puede indica un máximo a * escribir. * Devuelve los bytes escritos. * * @param resource $handle_archivo * @param mixed $texto * @param int $max_bytes * * @return int * @throws Exception */ public static function write( $handle_archivo, $texto, $max_bytes = null) { if (is_null($max_bytes)) { $ret = fwrite($handle_archivo, $texto); } else { $ret = fwrite($handle_archivo, $texto, $max_bytes); } if ($ret === false) { throw new Exception('No se puede escribir en el archivo'); } self::flush($handle_archivo); return $ret; } /** * Desbloquea un archivo bloqueado. * Al hacer un close, también se desbloquea * * @param resource $handle_archivo * * @throws Exception */ public static function ubLock($handle_archivo) { if (flock($handle_archivo, LOCK_UN) === false) { throw new Exception('Imposible desbloquear el archivo'); } } /** * Trunca un archivo a un determinado tamaño * * @param resource $handle_archivo * @param int $tamanio * * @throws Exception */ public static function truncateContent($handle_archivo, $tamanio) { if (ftruncate($handle_archivo, $tamanio) === false) { throw new Exception('No se puede truncar el archivo'); } } /** * Modifica la fecha del último acceso al archivo * * @param $nombre_archivo * * @throws Exception */ public static function touch($nombre_archivo) { if (touch($nombre_archivo) === false) { throw new Exception("No se puede realizar un touch al archivo {$nombre_archivo}"); } } /** * Posiciona el cursor al final del archivo * * @param resource $handle_archivo * * @throws Exception */ public static function seekToEnd($handle_archivo) { $ret = fseek($handle_archivo, 0, SEEK_END); if ($ret === false || $ret == -1) { throw new Exception('No se puede desplazar el cursor al final del archivo'); } } /** * Posiciona el cursor al inicio del archivo * * @param $handle_archivo * * @throws Exception */ public static function seekToBegin($handle_archivo) { if (rewind($handle_archivo) === false) { throw new Exception('No se puede desplazar el cursor al inicio del archivo'); } } /** * Posiciona el cursor dentro de un archivo partiendo de la * posición actual del cursor * * @param resource $handle_archivo * @param int $offset * * @throws Exception */ public static function seekIncrement($handle_archivo, $offset) { $ret = fseek($handle_archivo, $offset, SEEK_CUR); if ($ret === false || $ret == -1) { throw new Exception('No se puede desplazar el cursor en el archivo'); } } /** * Posiciona el cursor dentro de un archivo partiendo desde el * final * * @param resource $handle_archivo * @param int $offset * * @throws Exception */ public static function seekFromEnd($handle_archivo, $offset) { $ret = fseek($handle_archivo, (-1 * $offset), SEEK_END); if ($ret === false || $ret == -1) { throw new Exception('No se puede desplazar el cursor desde el final del archivo'); } } /** * Posiciona el cursor dentro de un archivo partiendo desde el * inicio * * @param resource $handle_archivo * @param int $offset * * @throws Exception */ public static function seekFromBegin($handle_archivo, $offset) { $ret = fseek($handle_archivo, $offset, SEEK_SET); if ($ret === false || $ret == -1) { throw new Exception('No se puede desplazar el cursor desde dede el inicio del archivo'); } } /** * Renombra un archivo a otro nombre. Puede sobreescribir el * destino * Por defecto no lo sobreescribe. Lanza una excepción si hay * algún error * * @param string $archivo_origen * @param string $archivo_destino * @param bool $sobreescribir * * @throws Exception */ public static function rename( $archivo_origen, $archivo_destino, $sobreescribir = false) { if (!$sobreescribir && file_exists($archivo_destino)) { throw new Exception("El archivo destino {$archivo_destino} ya existe y no se ha de sobreescribir"); } if (rename($archivo_origen, $archivo_destino) === false) { throw new Exception("No se ha podido sobreescribir el archivo origen {$archivo_origen} con el archivo destino {$archivo_destino}"); } } /** * Elimina todos los archivos de un directorio que cumplan un * determinado patrón. * Lanza excepciones si algún archivo no se ha podido eliminad * * @param string $pattern * */ public static function removeByPattern($pattern) { array_map(function ($nombre_archivo) { self::remove($nombre_archivo); }, glob($pattern)); } /** * Elimina fÃsicamente un archivo. * Si no existe, no pasa nada, pero si existe y no se ha podido * eliminar, se lanza una excepción. * * @param $path_archivo * * @throws Exception */ public static function remove($path_archivo) { if (!file_exists($path_archivo)) { return; } if (unlink($path_archivo) === false) { throw new Exception("No se puede eliminar el archivo {$path_archivo}"); } } /** * Lee el contenido de un archivo en función de un formato * * @param resource $handle_archivo * @param string $formato * * @return array|int */ public static function readScan($handle_archivo, $formato) { return fscanf($handle_archivo, $formato); } /** * Lee una linea de un archivo abierto. Hasta encontrar un \r\n * La lÃnea tambén incluye el salto de lÃnea. * Si no puede leer del archivo, lanza una excepción * Si el archivo a leer esta vacÃo, lanza una excepción * * @param resource $handle_archivo * * @return string * @throws Exception */ public static function readLine($handle_archivo) { $ret = fgets($handle_archivo); if ($ret === false) { throw new Exception('No se puede leer la linea del archivo'); } return $ret; } /** * Lee una cantidad de char de un archivo. Por defecto 1. * Saltos de lÃnea (\r\n) son dos chars. * Si no puede leer del archivo, lanza una excepción * Si el archivo a leer esta vacÃo, lanza una excepción * * @param resource $handle_archivo * @param int $max_bytes * * @return string * @throws Exception */ public static function readChars($handle_archivo, $max_bytes = 1) { $ret = fread($handle_archivo, $max_bytes); if ($ret === false) { throw new Exception("Imposible leer {$max_bytes} bytes del archivo"); } return $ret; } /** * Abre una conexión contra un archivo de texto * Si se abre, devuelve el handle de la conexion, si hay error * lanza excepción * r * Sólo permite leer. No se puede escribir mientras esta * abierto * Puntero al inicio del archivo al abrir. * Falla si el archivo no existe. * r+ * Se puede leer i escribit. * Puntero al inicio del archivo al abrir. * Falla si el archivo no existe. Es obligatorio que exista * w * Sólo permite escribir. No leer * Puntero al inicio del archivo al abrir. * Si el archivo no existe, se crea. Si está credo * sobreescribe. * w+ * Se puede leer i escribit. * Puntero al inicio del archivo al abrir. * Si el archivo no existe, se crea. Si está credo * sobreescribe. * a * Sólo permite escribir. No leer * Puntero al final del archivo al abrir. * Si el archivo no existe, se crea. * a+ * Se puede leer i escribit. * Puntero al final del archivo al abrir. * Si el archivo no existe, se crea. * * @param string $path_archivo * @param string $modo_acceso * * @return resource * @throws Exception */ public static function openText($path_archivo, $modo_acceso) { $handle = @fopen($path_archivo, $modo_acceso); if (!$handle) { throw new Exception("Imposible abrir archivo {$path_archivo} en modo {$modo_acceso}"); } return $handle; } /** * Abre una conexión contra un archivo binario * Si se abre, devuelve el handle de la conexion, si hay error * lanza excepción * r * Sólo permite leer. No se puede escribir mientras esta * abierto * Puntero al inicio del archivo al abrir. * Falla si el archivo no existe. * r+ * Se puede leer i escribit. * Puntero al inicio del archivo al abrir. * Falla si el archivo no existe. Es obligatorio que exista * w * Sólo permite escribir. No leer * Puntero al inicio del archivo al abrir. * Si el archivo no existe, se crea. Si está credo * sobreescribe. * w+ * Se puede leer i escribit. * Puntero al inicio del archivo al abrir. * Si el archivo no existe, se crea. Si está credo * sobreescribe. * a * Sólo permite escribir. No leer * Puntero al final del archivo al abrir. * Si el archivo no existe, se crea. * a+ * Se puede leer i escribit. * Puntero al final del archivo al abrir. * Si el archivo no existe, se crea. * * @param string $path_archivo * @param string $modo_acceso * * @return resource * @throws Exception */ public static function openBinary($path_archivo, $modo_acceso) { $handle = @fopen($path_archivo, $modo_acceso .'b'); /* b => Abre un binario */ if (!$handle) { throw new Exception("Imposible abrir archivo {$path_archivo} en modo {$modo_acceso}"); } return $handle; } /** * Bloquea un archivo en modo exclusivo, tanto para leer como para * escribir * * @param resource $handle_archivo * * @throws Exception */ public static function lock($handle_archivo) { if (flock($handle_archivo, LOCK_EX) === false) { throw new Exception('Imposible bloquear el archivo origen'); } } /** * Indica si el archivo se puede escribir. * Si el archivo no existe, devuelve false. * No es necesario estar abierto. * * @param string $nombre_archivo * * @return bool */ public static function isWritable($nombre_archivo) { if (!file_exists($nombre_archivo)) { return false; } return is_writable($nombre_archivo); } /** * Indica si el archivo se puede leer. * Si el archivo no existe, devuelve false. * No es necesario estar abierto. * * @param string $nombre_archivo * * @return bool */ function archivo_leible($nombre_archivo) { if (!file_exists($nombre_archivo)) { return false; } return is_readable($nombre_archivo); } /** * Devuelve el tamaño en bytes de un archivo. * Si el archivo no existe, devuelve -1 * * @param $nombre_archivo * * @return false|int * @throws Exception */ public static function getSizeBytes($nombre_archivo) { if (!file_exists($nombre_archivo)) { return -1; } $ret = filesize($nombre_archivo); if ($ret === false) { throw new Exception("No se puede obtener el tamaño del archivo {$nombre_archivo}"); } return $ret; } /** * Devuelve la posición actual del cursor * * @param resource $handle_archivo * * @return false|int * @throws Exception */ public static function getSeekPosition($handle_archivo) { $ret = ftell($handle_archivo); if ($ret === false) { throw new Exception('Imposible obtener la posición del cursor de dentro del archivo'); } return $ret; } /** * Reemplaza los separadores de directorio "\\" por "/" y elimina * los innecesarios * * @param string $path_archivo * * @return string */ public static function getSanitizedPath($path_archivo) { $path = HelpString::replaceAll($path_archivo, '\\', '/'); $path = HelpString::replaceAll($path, '//', '/'); return HelpString::replaceAll($path, '/./', '/'); } /** * Función que devuelde sólo el nombre del archivo, sin extensión * ni directorio. * Separador de directorio = '/' * Si sólo hay un directorio (último carácter es '/') implica que * no hay nombre de archivo y devuelve '' * * @param string $path_archivo * * @return string */ public static function getOnlyFileName($path_archivo) { $path_archivo = self::getSanitizedPath($path_archivo); $pos_ultimo = strlen($path_archivo) - 1; if ($path_archivo[ $pos_ultimo ] == '/') { return ''; } return pathinfo($path_archivo, PATHINFO_FILENAME); } /** * Función que devuelve sólo la extensión de un archivo * Si tiene más de una, devuelve la última y si no * tiene devuelve "" * * @param string $path_archivo * * @return string */ public static function getOnlyExtension($path_archivo) { return pathinfo($path_archivo, PATHINFO_EXTENSION); } /** * Función que devuelde sólo el directorio del archivo con path. * Si sólo hay el nombre del archivo, el directorio es "" * Si sólo hay directorio (sin nombre de archivo) devuelve el * mismo directorio * * @param string $path_archivo * * @return string */ public static function getOnlyDirName($path_archivo) { $path_archivo = self::getSanitizedPath($path_archivo); $pos_ultimo = strlen($path_archivo) - 1; if ($path_archivo[ $pos_ultimo ] == '/') { return substr($path_archivo, 0, $pos_ultimo); } if ($path_archivo[ 0 ] == '/') { $path_archivo = substr($path_archivo, 1); } $dir = pathinfo($path_archivo, PATHINFO_DIRNAME); if ($dir == "\\") { $dir = '/'; } elseif ($dir == '.') { $dir = ''; } return $dir; } /** * Devuelve el nombre del archivo al que apunta el link. * No es necesario estar abierto. * Si no es un link, devuelve '' * * @param string $nombre_link * * @return string */ public static function getLinkTarget($nombre_link) { if (!is_link($nombre_link)) { return ''; } return ''.readlink($nombre_link); } /** * Devuelve el nombre, path, tamaño y fechas de un archico * Opciones name, server_path, size, date, readable, writable, * executable, fileperms * * @param string path to file * @param mixed array or comma separated string of information * returned * * @return array */ public static function getInfo( $file, $returned_values = array('name', 'server_path', 'size', 'date') ) { $fileinfo = []; if (!file_exists($file)) { return $fileinfo; } if (is_string($returned_values)) { $returned_values = explode(',', $returned_values); } foreach ($returned_values as $key) { switch ($key) { case 'name': $fileinfo[ 'name' ] = substr( strrchr( $file, DIRECTORY_SEPARATOR), 1); break; case 'server_path': $fileinfo[ 'server_path' ] = $file; break; case 'size': $fileinfo[ 'size' ] = filesize($file); break; case 'date': $fileinfo[ 'date' ] = filectime($file); break; case 'readable': $fileinfo[ 'readable' ] = is_readable($file); break; case 'writable': // There are known problems using is_weritable on // IIS. It may not be reliable - consider // fileperms() $fileinfo[ 'writable' ] = is_writable($file); break; case 'executable': $fileinfo[ 'executable' ] = is_executable($file); break; case 'fileperms': $fileinfo[ 'fileperms' ] = fileperms($file); break; } } return $fileinfo; } /** * Crea y devuelve un nombre único de un archivo temporal en el * directorio temporal del sistema * Se le puede añadir un prefijo de 3 caracteres como máximo. * Lanza una excecpión si no se puede crear * * @param string $prefijo * * @return string * @throws Exception */ public static function getFileTmp($prefijo = '') { $nombre = tempnam(sys_get_temp_dir(), $prefijo); if ($nombre === false) { throw new Exception('Imposible crear archivo temporal'); } return $nombre; } /** * Función que devuelde el nombre completo (nombre + extensión) * del archivo, sin directorio * Si el archivo sólo tiene directorio, devuelve "" * SI el archivo sólo contiene nombre de vuelve el mismo nombre * * @param string $path_archivo * * @return string */ public static function getFileNameFull($path_archivo) { $path_archivo = self::getSanitizedPath($path_archivo); $pos_ultimo = strlen($path_archivo) - 1; if ($path_archivo[ $pos_ultimo ] == '/') { return ''; } return pathinfo($path_archivo, PATHINFO_BASENAME); } /** * Devuelve el contenido de un archivo. * Se puede indicar un offset y un máximi de bytes a devolver * Si el archivo no existe, lanza una excepción. * Saltos de lÃnea son \r\n * Si hay un offset es obligatorio un máximo de bytes a devolver * * @param string $path_archivo * @param int|null $offset * @param int|null $max_bytes * * @return false|string * @throws Exception */ public static function getAllContent($path_archivo, $offset = null, $max_bytes = null) { if (!is_null($offset) && !is_null($max_bytes)) { $ret = file_get_contents( $path_archivo, null, null, $offset, $max_bytes); } else { $ret = file_get_contents($path_archivo); } if ($ret === false) { throw new Exception("Imposible leer el contenido del archivo {$path_archivo}"); } return $ret; } /** * Fuerza la escritura del bufer al archivo. * Lanza una excepción si no puede realizarlo * * @param resource $handle_archivo * * @throws Exception */ public static function flush($handle_archivo) { if (fflush($handle_archivo) === false) { throw new Exception('No sd puede formazar la escriptura del archivo') } } /** * Indica si un archivo existe * * @param string $path_archivo * * @return mixed */ public static function exists($path_archivo) { return file_exists($path_archivo); } /** * Detecta el End Of File de un archivo * * @param $handle_archivo * * @return bool */ public static function eof($handle_archivo) { return feof($handle_archivo); } /** * Crea un link simbólico de un archio. No es necesario que esté * abierto * Lanza una excepción si no se ha podido crear * * @param string $nombre_archivo_origen * @param string $nombre_link_destino * * @throws Exception */ public static function createLink( $nombre_archivo_origen, $nombre_link_destino) { $ret = symlink($nombre_archivo_origen, $nombre_link_destino); if ($ret === false) { throw new Exception("Imposible crear link destino {$nombre_link_destino} del archivo origen {$nombre_archivo_origen}"); } } /** * Copa un archivo a otro. Por defecto no se sobreescribe. * Lanza una excecpión si no se ha copiado por algún motivo * Se puede copiar entre diferentes directorios * * @param string $archivo_origen * @param string $archivo_destino * @param bool $sobreescribir * * @throws Exception */ public static function copy( $archivo_origen, $archivo_destino, $sobreescribir = false) { if (!$sobreescribir && file_exists($archivo_destino)) { throw new Exception("El archivo destino {$archivo_destino} ya existe y no se ha de sobreescribir"); } if (copy($archivo_origen, $archivo_destino) === false) { throw new Exception("No se puede copiar el archivo origen {$archivo_origen} en el archivo destino {$archivo_destino}"); } } /** * Cierra el fichero * * @param $handle_file */ public static function close($handle_file) { @fclose($handle_file); } /** * Cambiamos la extensión de un archivo. * Si no tiene extensión, le asignamos la nueva. * * @param string $nombre_archivo * @param string $nueva_extension * * @return string */ public static function archivo_cambiar_extension($nombre_archivo, $nueva_extension) { if (HelpValidate::isEmpty($nueva_extension)) { return $nombre_archivo; } if ($nueva_extension[ 0 ] != '.') { $nueva_extension = '.'.$nueva_extension; } $dir = self::getOnlyDirName($nombre_archivo); $solo_nombre = self::getOnlyFileName($nombre_archivo); if ($solo_nombre == '') { return $nombre_archivo; } if ($dir == '' && $nombre_archivo[ 0 ] != '/') { return $dir.$solo_nombre.$nueva_extension; } return $dir.'/'.$solo_nombre.$nueva_extension; } }