Nueva pregunta

Pregunta:

Fecha: 25-05-2017 22:40:47 (En Español)

¿Cómo cortar un fichero en partes con PHP?[Resuelta]

Me refiero a cortar / dividir ficheros (archivos) en partes con tamaños proporcionales con respecto a la longitud del fichero original.

Tengo ideas de realizarlo con fopen, haciendo lectura al binario, considerando de esta forma obtener un puntero que hace referencia a este, para luego darle lectura a cierto trozo de información, pero no sé realmente como generar los ficheros finales ya en partes.

Estoy intentando separar un diccionario en partes para hacer auditoría de red.

Desde ya, muchas gracias a todos los lectores y a los que comparten un poco de su tiempo, de sentarse para ayudar a resolver problemas de novatos como yo.

¡Saludos!.
Etiquetas: PHP - Pregunta - Web Votos: 1 - Respuestas: 7 - Vistas: 18 Compartir en: Google Facebook Twitter LinkedIn Link
 

Respuestas:

  • Fecha: 26-05-2017 09:54:49 Hola Jerson, ante todo bienvenido a la comunidad!

    Mira, aquí he desarrollado una función para cortar un archivo en la cantidad de partes que tu designes según su parametrización. He descripto el código para que puedas comprender que hago en cada momento y modificarlo si fuera necesario.

    Veamos el código:
    <?php
    /**
     * Función splitFile para PHP, corta un archivo en partes
     * @author Fernando Mosquera [www.phpcentral.com]
     * @date 26/05/2017
     * @param string $archivoOrigen ruta completa del archivo origen a ser cortado en partes
     * @param string $pathDestino ruta destino, debe terminar con /
     * @param int $cantidadPartes cantidad de partes en las que se debe cortar el archivo origen
     */
    function splitFile($archivoOrigen, $pathDestino, $cantidadPartes) {
        //obtengo el nombre
        $nombreArchivo = basename($archivoOrigen);
        //obtengo el tamaño del archivo
        $fileSize = filesize($archivoOrigen);
        //calculo el buffer a leer en base a la cantidad de partes
        $buffer = $fileSize / $cantidadPartes;
        //abro el archivo en modo lectura
        $fileHandle = fopen($archivoOrigen, "r");
    
        for ($nroParte = 1; $nroParte <= $cantidadPartes; $nroParte++) {
            //leo una parte del archivo
            $filePart = fread($fileHandle, $buffer);
            //armo el path destino de la parte a ser persistida
            $filePartDestino = $pathDestino . $nombreArchivo . ".part" . str_pad($nroParte, 10, '0', STR_PAD_LEFT);
            //creo el archivo y lo abro
            $filePartNew = fopen($filePartDestino, 'w+');
            //escribo la parte en el archivo
            fwrite($filePartNew, $filePart);
            //cierro el puntero del archivo parte
            fclose($filePartNew);
        }
        //cierro el puntero del archivo leido
        fclose($fileHandle);
    }
    


    Un ejemplo de uso podría ser:
    $archivoOrigen = $_SERVER['DOCUMENT_ROOT'] . '/cortar_archivo/archivo.txt';
    $pathDestino = $_SERVER['DOCUMENT_ROOT'] . '/cortar_archivo/part/';
    $cantidadPartes = 5;
    splitFile($archivoOrigen, $pathDestino, $cantidadPartes);
    

    Nota: deberá existir el path '/cortar_archivo/part/' y obviamente el archivo /cortar_archivo/archivo.txt.

    Un ejemplo de contenido para el archivo.txt podría ser el siguiente (10 párrafos, 873 palabras, 5829 bytes de Lorem Ipsum):
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut nunc augue, ultrices at leo vitae, tincidunt interdum mauris. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nullam lacinia felis mi, in facilisis risus sagittis sit amet. Suspendisse fermentum dapibus purus vel pretium. Donec sollicitudin vestibulum gravida. Sed a aliquam massa. Suspendisse a turpis massa. Nam aliquet vel ipsum a pellentesque. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse nulla turpis, pharetra ut bibendum eu, ultricies quis metus. Curabitur dignissim, nisl quis dignissim pretium, enim risus laoreet purus, a eleifend est lacus ac odio. Phasellus pharetra dolor at faucibus tincidunt. Integer mattis venenatis ante in lacinia.
    
    Vestibulum ut posuere lorem. Quisque tempus et lorem sed blandit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Maecenas a congue nisi. Nunc suscipit aliquam enim, vitae imperdiet lacus pretium ut. Morbi mattis fringilla ultrices. Proin congue lectus nec justo tincidunt ullamcorper. Vestibulum lacinia ultricies iaculis. Nullam a rhoncus est. Nullam lectus felis, suscipit id arcu quis, finibus maximus sem.
    
    Nullam in porttitor leo. Nam ornare neque enim, nec tempus est fermentum sit amet. Sed pulvinar lacus quam, ac interdum leo facilisis et. Donec in ante dapibus odio egestas scelerisque. Nullam auctor rutrum urna, nec egestas eros. Integer vel magna eu erat rutrum molestie. Integer et dui ornare, imperdiet lacus a, tincidunt purus. Nullam pharetra diam id dictum scelerisque. Aenean nunc justo, fringilla vitae nunc quis, pharetra auctor turpis. Sed vitae finibus leo, in vulputate arcu.
    
    Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla sollicitudin quam ac turpis placerat hendrerit. Donec at libero blandit, placerat velit non, placerat nisl. Pellentesque elementum, enim id euismod gravida, nibh eros faucibus ex, eget sodales tortor mauris a velit. Phasellus sit amet lectus erat. Donec diam neque, volutpat et eleifend nec, tempor nec velit. Nulla eu neque maximus, finibus ante sed, dapibus odio. Sed non magna sed ex suscipit venenatis vel a diam. Vivamus hendrerit vel nisl ac interdum. Integer ac tincidunt nulla, at placerat erat. Sed magna velit, suscipit sed mi in, finibus cursus eros. Sed congue tortor quis justo mollis mollis. Nam orci ante, vehicula sit amet bibendum a, egestas in nibh. Phasellus porttitor felis a tellus tristique viverra. Duis quis porta felis.
    
    Suspendisse sed lorem id ante sagittis condimentum sit amet eu dolor. Curabitur sollicitudin dolor a nibh tincidunt dignissim. Curabitur rutrum, leo a egestas lacinia, mi metus venenatis ante, facilisis tincidunt ex risus sollicitudin nisl. Nulla vitae eros a est vehicula ornare vitae sed enim. In porttitor purus accumsan nisl pharetra, a porta arcu convallis. Vivamus at purus in turpis rhoncus mollis. Proin maximus mauris mauris, eu ultrices tellus blandit vel. Praesent pellentesque fermentum blandit. In hac habitasse platea dictumst. Integer vulputate ac est quis tempor. Cras gravida tellus et ligula aliquam tincidunt. Nam cursus dapibus nunc et imperdiet. Aliquam erat volutpat.
    
    Donec diam elit, pellentesque eget nisl vel, interdum sagittis felis. Donec scelerisque mauris velit, at venenatis felis venenatis vel. Sed finibus turpis eget diam auctor, quis suscipit est finibus. Suspendisse rhoncus ante sem, quis aliquet est euismod et. Nam et dapibus lorem, in aliquam libero. Donec risus libero, vehicula nec purus sed, imperdiet molestie enim. Aliquam scelerisque ligula porttitor massa finibus suscipit. Etiam suscipit sodales auctor. Pellentesque congue laoreet nisi sit amet eleifend. Cras euismod nisi non mi iaculis vestibulum facilisis eget libero. Curabitur molestie ex eget fringilla placerat. In imperdiet metus vel tortor mattis, ut pretium tortor finibus.
    
    Donec vitae tempor nibh. Fusce at nulla ipsum. Suspendisse eleifend sed nibh vitae tristique. In consectetur imperdiet lorem at porta. Vestibulum non sem at quam tempus interdum. Pellentesque ut est non odio dignissim maximus. Nulla eget neque non ante rutrum tincidunt. Vivamus tellus arcu, mattis sit amet ornare a, varius sit amet neque. Nulla maximus dui neque. Mauris non justo vel sapien euismod aliquet sit amet ut nulla.
    
    Integer sollicitudin a lorem quis suscipit. Ut quis ex lacinia, volutpat leo in, facilisis libero. Aliquam vulputate, felis quis posuere tempus, dolor enim dictum turpis, et semper nulla sem sed ipsum. Morbi malesuada diam a nisi dictum congue. Phasellus id mollis est. Vestibulum ut nunc et ex viverra elementum nec a enim. Duis sagittis maximus turpis, a consectetur tortor imperdiet quis. In fringilla dignissim ex, a dignissim dolor dictum nec. In urna erat, finibus eget erat et, gravida laoreet diam. Ut lacus nulla, finibus eu aliquam id, tristique ut sem.
    
    Fusce imperdiet diam lectus, eget sollicitudin tellus pellentesque sit amet. Praesent a dolor magna. In fringilla placerat sapien ut vestibulum. Sed malesuada laoreet turpis. Sed molestie, erat quis iaculis viverra, odio urna pulvinar dui, non egestas lectus libero at lectus. Duis eget tristique libero. In id nisi placerat, tincidunt nibh mollis, aliquam purus. Mauris dapibus sem nisl, in convallis sapien congue at. Vestibulum id tellus nulla.
    
    Nullam sed augue nulla. Nam ac molestie urna. Sed sodales gravida nibh non dignissim. Sed maximus fringilla auctor. Phasellus congue tortor quis turpis eleifend, vitae finibus massa egestas. Morbi non semper tellus. Vestibulum quis ultricies nisl. Donec rhoncus vitae ante at faucibus. Vivamus congue dictum vestibulum. Cras fermentum nulla quam, at lacinia sapien sodales eget. Sed fermentum ipsum varius nibh lacinia mattis. 
    


    Claro esta que esta función puede ser mejorada, por ejemplo se me ocurre que se podría validar la existencia del path destino, y si no existe crearlo, y también lanzar excepciones si por ejemplo no se pudiera abrir el archivo origen, entre otras...

    Espero que mi respuesta te sea de ayuda, me he divertido codificando la función (lindo ejercicio para un viernes).

    Saludos y buen código!
      Votos: 1 - Link respuesta
     
  • Fecha: 26-05-2017 20:12:26 Hola Fernando, gracias por la bienvenida.

    Excelente algoritmo, gracias por compartirlo, muy entendible.

    Viendo un poco su código, me ha llamado la atención el uso de la función: str_pad.
    ¿Cuál es su función en la resolución de este problema?.
    str_pad($nroParte, 10, '0', STR_PAD_LEFT);
    

    El resultado que encuentro de acuerdo a su concepto es rellenar un string hasta una longitud determinada, en este caso 10 (0) empezando desde la izquierda.

    Me ha inspirado a mejorar la función, claro, con la señal que me ha dado en validar el directorio donde se alojarán las partes, además de asignarle un poco más de estética a los ficheros resultantes.

    Veamos su código con un par de cosas agregadas.
    function splitFile($archivoOrigen, $cantidadPartes) {
        /*Información que contiene información de la ruta del fichero (Array)*/
        $PathFile = pathinfo($archivoOrigen);
    
        /*Se crea un directorio con el mismo nombre del fichero, sólo en caso de que no exista*/
        $pathDestino = $PathFile['dirname']."/".$PathFile['filename']."/";
        if (!file_exists($pathDestino))
            @mkdir($pathDestino, 0744);
    
        /*Se apertura el fichero en modo lectura*/
        $fileHandle = fopen($archivoOrigen, "r");
    
        /*Se recorre la cantidad de partes en las que se dividirá el fichero*/
        for ($nroParte = 1; $nroParte <= $cantidadPartes; $nroParte++) {
    
            /*Se lee una parte del fichero*/
            $filePart = fread($fileHandle, (filesize($archivoOrigen) / $cantidadPartes));
    
            /*Se crea el fichero y se ejecuta*/
            $filePartNew = fopen($pathDestino.$PathFile['filename'].$nroParte.".".$PathFile['extension'], 'w+');
    
            /*Se hace un volcado de la información limite que extrajo del fichero original a la parte*/
            fwrite($filePartNew, $filePart);
    
            /*Se cierra la parte aperturada*/
            fclose($filePartNew);
        }
    
        /*Se cierra el fichero original*/
        fclose($fileHandle);
    }
    

    El ejemplo es prácticamente el mismo, la única diferencia es que ahora sólo se le pasan 2 parámetros.
    #Parámetro 1: Ruta del fichero a dividir, Parámetro 2: Cantidad de partes
    splitFile($_SERVER['DOCUMENT_ROOT']."/splitfile/archivo.txt", 3);
    

    Me gustó mucho el código, es lo que necesitaba. Le agradezco mucho la solución.
    Sería excelente intentar hacer el algoritmo en reverso, que teniendo las partes, este las recorra obteniendo como resultado 1 único fichero.

    Gracias por la bienvenida.
    ¡Saludos!.
      Votos: 1 - Link respuesta
     
  • Fecha: 27-05-2017 04:16:13 Hola Jerson, me alegra que mi respuesta te haya sido de ayuda y que ya este trabajando en su adaptación y nuevas ideas. Es correcta tu apreciación sobre el uso/aplicación de la función str_pad.

    Te dejo una frase que me gusta mucho "...el mejor vino no es necesariamente el más caro, sino el que se comparte..." :)

    Saludos y buen código!
      Votos: 2 - Link respuesta
     
  • Fecha: 27-05-2017 08:04:08 Muy agradecido con usted, seguiré por el sitio intercambiando y compartiendo algunas ideas.

    Grande George Brassens!.

    En esta nueva era, lo que te hace libre es el conocimiento, no el trabajo. -- (Elfriede Jelinek)

    Pregunta resuelta. Gracias, buen Finde.
      Votos: 1 - Link respuesta
     
  • Fecha: 29-05-2017 12:21:56 Hola nuevamente a todos los lectores.

    He realizado un pequeño código para luego unir los ficheros que fueron partidos y crear un sólo fichero que podría suponer ser el original.

    Es tan sencillo como utilizar una par de funciones.

    file_get_contents:
    Transmite un fichero entero a una cadena.
    file_put_contents: Escribe una cadena a un fichero.

    Se le pasa la ruta del fichero y obtiene la información, luego se agrega a la misma variable el segundo contenido del fichero número 2. Se pueden agregar más ficheros, sólo es adjuntar más rutas.
    <?php
    	$PathFile = file_get_contents($_SERVER['DOCUMENT_ROOT']."/splitfile/Document/Document1.pdf");
    	$PathFile .= file_get_contents($_SERVER['DOCUMENT_ROOT']."/splitfile/Document/Document2.pdf");
    
    	file_put_contents($_SERVER['DOCUMENT_ROOT']."/splitfile/document_completo.pdf", $PathFile);
    
    ?>

    Luego el file_put_contents hace su trabajo, que es escribir un nuevo binario y el contenido obtenido de los ficheros a unificar en el.

    Esto se puede mejorar mucho, haciendo un algoritmo que con solo pasarle la ruta de un directorio tome los ficheros que tengan enumarado al final, dando como resultado un único fichero final.

    Algo que notar, los partes que le paso son .pdf y dejo claro que obtengo excelentes resultados.

    Si mejoro el código, entonces lo estaré compartiendo.

    ¡Saludos!.
      Votos: 1 - Link respuesta
     
  • Fecha: 06-05-2018 18:07:43 Acá, recordando la solución que me dio, Fernando Mosquera, sobre este tema. He continuado el proyecto y lo he compartido por YouTube, donde se puede apreciar la instalación y uso.

    PHP | CORTAR y UNIR archivos o ficheros



    También he compartido el código fuente en GitHub: Split-Files

    También pueden encontrar un estudio extendido sobre este tema en Crashell.

    ¡Saludos cordiales!
      Votos: 0 - Link respuesta
     
  • Fecha: 27-04-2023 05:57:09 Hola, he querido unir documentos word (doc) o pdf con el codigo proporcionado:

    $PathFile = file_get_contents($_SERVER['DOCUMENT_ROOT']."/FUSIONDOC/DOCS/E2023000001.doc");
    $PathFile.=file_get_contents($_SERVER['DOCUMENT_ROOT']."/FUSIONDOC/DOCS/E2023000002.doc");

    file_put_contents($_SERVER['DOCUMENT_ROOT']."/FUSIONDOC/DOCS/document_completo.pdf", $PathFile);

    El problema es que cuando ingres al archivo generado solo me muestra el segundo archivo no los dos unidos, revise el peso de documento y es el doble como si hubiera unificado los archivos pero no me muestra el primero.
    esto me pasa en ambos formatos ya se doc o pdf.
    cuando hago un echo $PathFile puedo ver que su contenido tiene los datos de ambos documentos pero el resultado final solo me muestra el ultimo archivo con el peso de ambos.


    Espero alguien pueda compartir una solución.

    Gracias.
      Votos: 0 - Link respuesta
     
Para participar activamente de la comunidad primero debes autenticarte, ingresa al sistema.Iniciar Sesión
 
frjcbbae garagebible.com