Foros del Web » Programando para Internet » PHP »

Leer archivo grande y manipularlo

Estas en el tema de Leer archivo grande y manipularlo en el foro de PHP en Foros del Web. Hola. Tengo un archivo de texto grande de 100mb. El archivo posee 1600000 lineas, en cada linea hay un proveedor con sus porcentajes de impuestos. ...
  #1 (permalink)  
Antiguo 18/12/2015, 11:27
Avatar de chucky2083  
Fecha de Ingreso: octubre-2014
Ubicación: Buenos Aires
Mensajes: 9
Antigüedad: 9 años, 6 meses
Puntos: 0
Pregunta Leer archivo grande y manipularlo

Hola. Tengo un archivo de texto grande de 100mb. El archivo posee 1600000 lineas, en cada linea hay un proveedor con sus porcentajes de impuestos. Necesito manipular 1600 proveedores que tengo en la DB y actualizar sus impuestos. Es decir los 1600 proveedores de la DB los tiene que comparar 1 a 1 con cada linea del archivo.

Intento solo leer el archivo e imprimirlos y se me muere el programa. Llega a procesar unos 7 minutos y medio y tira un error 500. Pero en el log de apache no aparece el error.

Hay alguna forma de leer el archivo por partes? Ya le subi los tiempos en los archivos de configuracion pero aun asi el programa muere.
  #2 (permalink)  
Antiguo 18/12/2015, 15:01
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: Leer archivo grande y manipularlo

¿A quién en el mundo se le ocurre almacenar tanta información en un archivo de texto plano?

Mal ahí, de entrada ya comenzaste con el pie izquierdo.
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #3 (permalink)  
Antiguo 18/12/2015, 15:25
Colaborador
 
Fecha de Ingreso: mayo-2008
Ubicación: $MX['VZ']['Xalapa']
Mensajes: 3.005
Antigüedad: 15 años, 11 meses
Puntos: 528
Respuesta: Leer archivo grande y manipularlo

¿Acaso por cada proveedor de tu BD relees el archivo completo?

No estoy muy seguro de entender para qué requieres la lectura del archivo, pero 1600 datos no son muchos.

Podrías meter esos 1600 proveedores en un arreglo en memoria, y al leer el archivo (sólo una vez) cuando encuentres uno que esté en tu arreglo lo actualizas. Pero deberías dar más datos sobre la utilidad de ese archivo, y el procedimiento que realizas para actualizar tus datos, ya que podría no estar optimizado.

Si no son 1600 si no los 1600000 que dices que tiene el archivo, entonces quizá si sea necesario plantear otra estrategia.

Por cierto, 7 minutos no es mucho tiempo, yo he tenido que importar datos en formato texto de forma similar y cuando son realmente muchos datos, pueden tomar hasta unos 20 minutos, por lo que igualmente puede que sea necesario que aumentes el tiempo de ejecución de tu script.
  #4 (permalink)  
Antiguo 21/12/2015, 05:40
Avatar de chucky2083  
Fecha de Ingreso: octubre-2014
Ubicación: Buenos Aires
Mensajes: 9
Antigüedad: 9 años, 6 meses
Puntos: 0
Respuesta: Leer archivo grande y manipularlo

A la afip. El archivo de retenciones. No cree yo el archivo, es lo que te da la afip.

Cita:
Iniciado por pateketrueke Ver Mensaje
¿A quién en el mundo se le ocurre almacenar tanta información en un archivo de texto plano?

Mal ahí, de entrada ya comenzaste con el pie izquierdo.
  #5 (permalink)  
Antiguo 21/12/2015, 06:07
Avatar de chucky2083  
Fecha de Ingreso: octubre-2014
Ubicación: Buenos Aires
Mensajes: 9
Antigüedad: 9 años, 6 meses
Puntos: 0
Respuesta: Leer archivo grande y manipularlo

Eso intente, pero solo quise leerlo e imprimirlo en el navegador. Y muere.

El funcionamiento es asi. Tengo 1600 proveedores cargados en la base de datos, y cada mes bajo un archivo de retenciones de la AFIP (Administracion Federal de Ingresos Publicos). El archivo que bajo pesa unos 100Mb y posee aproximadamente 1600000 lineas. En cada linea hay un proveedor (CUIT, % de RETENCION, y otros datos mas).



Lo que tengo que hacer es comparar cada uno de los 1600 proveedores de mi base de datos, con los que estan en el archivo, para actualizar el % de la retencion.

Quisiera hacerlo como decis, cargar los proveedores en un arreglo y comparar cada linea del txt con el arreglo, pero con solo imprimir el archivo muere. Los tiempos de ejecucion los puse con numeros grandes pero igual a los 7:30 min, me lanza un error 500.




Cita:
Iniciado por ocp001a Ver Mensaje
¿Acaso por cada proveedor de tu BD relees el archivo completo?

No estoy muy seguro de entender para qué requieres la lectura del archivo, pero 1600 datos no son muchos.

Podrías meter esos 1600 proveedores en un arreglo en memoria, y al leer el archivo (sólo una vez) cuando encuentres uno que esté en tu arreglo lo actualizas. Pero deberías dar más datos sobre la utilidad de ese archivo, y el procedimiento que realizas para actualizar tus datos, ya que podría no estar optimizado.

Si no son 1600 si no los 1600000 que dices que tiene el archivo, entonces quizá si sea necesario plantear otra estrategia.

Por cierto, 7 minutos no es mucho tiempo, yo he tenido que importar datos en formato texto de forma similar y cuando son realmente muchos datos, pueden tomar hasta unos 20 minutos, por lo que igualmente puede que sea necesario que aumentes el tiempo de ejecución de tu script.

Última edición por chucky2083; 21/12/2015 a las 06:34
  #6 (permalink)  
Antiguo 21/12/2015, 07:43
 
Fecha de Ingreso: enero-2015
Mensajes: 35
Antigüedad: 9 años, 3 meses
Puntos: 1
Respuesta: Leer archivo grande y manipularlo

Creo que lo podrías lograr desde la consola php, es decir en tu servidor y sin el navegador (en un script php), podrías procesar los 1.600.000Reg del txt y extraerlo a otro archivo txt con el identificador del proveedor (en mi pais Reg.Unico. Contrib.) y los %, entonces te queda un archivo mucho mas chico y manejable y luego actualizarlo a tu BD los que coincidan, debes hacer el bucle verbose o sea mostrando la linea y algunos datos para saber si avanza y con que tiempo procesa una cant. de lineas asi podrás hacer el calculo de tiempo que te llevara la totalidad, o bien utilizas otro lenguaje que extraiga esas informaciones del txt grande a otro y luego lo procesas con tu BD, no se que otro lenguaje te convendria porque no se que BD usas.

Funciones utiles fopen, fclose, fgets, substr, etc.

Recomiendo extraer los datos necesarios del txt a otro txt primero porque lanzar una consulta SQL por cada uno de los 1.600.000 reg creo que forzarias innecesariamente los recursos de tu server.

Tambien en lugar de otro txt mas pequeño podrías cargarlo en una tabla temporal en tu BD si se te hace mas facil manejarlo con SQL.
  #7 (permalink)  
Antiguo 22/12/2015, 16:46
Colaborador
 
Fecha de Ingreso: mayo-2008
Ubicación: $MX['VZ']['Xalapa']
Mensajes: 3.005
Antigüedad: 15 años, 11 meses
Puntos: 528
Respuesta: Leer archivo grande y manipularlo

Es que no necesitas mandar a pantalla el contenido del archivo, te sugiero lo siguiente:

Tomas los id o bien el código identificador de tus proveedores de la base de datos, mediante un ciclo aloja estos datos en un arreglo estructurado más o menos así:

Código PHP:
Ver original
  1. while($fila=mysqli_fetch_assoc($resultado))
  2.     $arreglo[$fila['id']]=array();//creas un arreglo con los campos llave de tus proveedores.


Luego, lees el archivo linea por linea, no necesitas pasarlo a pantalla:

Código PHP:
Ver original
  1. while(!feof($archivoafip)){//mientras no llegues al fin del archivo
  2.       $linea=fgets($archivoafip, 1024);//tomas una linea
  3.       $linea=explode(';',$linea);//la separas. Puedes hacerlo en un paso con fgetsvc
  4.       if(isset($arreglo[$linea[0]])){//Si existe en tu bd el proveedor, en este caso supuse que el identificador está en el campo 0, pero tú usa el que requieres.
  5.  
  6.          $arreglo[$linea[0]]=array($linea[1],$linea[2],$linea[3]);//tomas los datos que quieres actualizar.
  7.       }
  8. }

finalmente, actualizas tu bd con los datos obtenidos en el arreglo.

Código PHP:
Ver original
  1. foreach($arreglo as $idprov =>$m)
  2.    mysqli_query($con,"UPDATE  mi_tabla set .......");//los datos nuevos estarán dentro de $m
  #8 (permalink)  
Antiguo 23/12/2015, 06:48
Avatar de Jilti  
Fecha de Ingreso: abril-2007
Mensajes: 47
Antigüedad: 17 años
Puntos: 4
Respuesta: Leer archivo grande y manipularlo

Saludos....
Veo que cada "campo" de cada linea del archivo de texto está separado por ";" (punto y coma).
Yo creo que sería factible crear una tabla en la base de datos, importar los datos del txt e indexando en campo de proveedores la búsqueda sería mas rápida.

Saludos
  #9 (permalink)  
Antiguo 23/12/2015, 07:05
 
Fecha de Ingreso: mayo-2013
Mensajes: 169
Antigüedad: 10 años, 10 meses
Puntos: 25
Respuesta: Leer archivo grande y manipularlo

Este tema me interesa ya que una vez tuve que procesar un archivo de tamaño similar pero con más datos.

¿Ya has modificado estos valores?:
Código PHP:
Ver original
  1. ini_set('memory_limit', '-1');
  2. ini_set('max_execution_time', 300);
Básicamente pones esto al principio del SCRIPT y no debería petarte. Es importante el memory_limit sin limite, y el max_execution_time con el tiempo en segundos que creas necesario que vaya a tardar.

Cita:
Iniciado por pateketrueke Ver Mensaje
¿A quién en el mundo se le ocurre almacenar tanta información en un archivo de texto plano?

Mal ahí, de entrada ya comenzaste con el pie izquierdo.
pateketrueke como se nota que no has tenido que hacer movidas como estas. Como si los datos que te dan ciertas empresas, te los dieran en el formato que tu les pidas...

Lamentablemente no es así.
  #10 (permalink)  
Antiguo 23/12/2015, 09:36
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: Leer archivo grande y manipularlo

Cita:
Iniciado por Amiancht Ver Mensaje
pateketrueke como se nota que no has tenido que hacer movidas como estas. Como si los datos que te dan ciertas empresas, te los dieran en el formato que tu les pidas...
Claro que he tenido que trabajar con menudos archivos de texto, pero jamás lo hago a través del navegador web.

Para eso existen los procesos de sistema y la linea de comandos.
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.

Etiquetas: ficheros, grandes, lectura
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 12:00.