[Python-es] Leer fichero al mismo tiempo que se está escribiendo por otro proceso.

lasizoillo lasizoillo en gmail.com
Vie Jul 5 03:19:57 EDT 2019


Buenas,

El código que has mandado tiene pinta de ser un corta y pega de tu código
real, por lo que nadie mas que tu va a poder reproducirlo. Así que lo único
que veo viable es hablarte de las herramientas que usaría para investigarlo
y que lo hagas tu mismo por tu cuenta.

Usa un depurador
--------------------------
Python viene con pdb incluido, aquí tienes un depurador para usarlo
https://www.pybonacci.org/2013/06/14/como-depurar-un-programa-python-con-pdb/
Si usas algún IDE (por ejemplo pycharm) esto lo podrás hacer de una forma
más visual. Con esto podrás ver si te está lanzando alguna excepción que
estés enmascarando o ponerte a ejecutar código para ver información del
fichero con os.stat() o lo que sea.

Evalúa las llamadas al sistema
----------------------------------------------
Dices tener un código en node.js que funciona, pero en python no. Es
posible que analizando llamadas al sistema de uno y otro código encuentres
alguna diferencia que te sea inspiradora para encontrar tu problema. Puedes
usar el comando de linux strace o el truss de freebsd u otros unix para
encontrar las llamadas que se hacen.

Prueba un cambio de paradigma
-----------------------------------------------
Quieres leer un fichero que está constantemente cambiando por lo que usar
llamadas a sistema como kqueue en freebsd o inotify en linux pueden
ayudarte a recibir eventos cuando el fichero cambie y leerlo entonces. Hay
librerias dependiendo de tu SO (algunas son multiplataforma) para hacer un
poco más fácil esta tarea (por ejemplo pyinotify para linux). Con esto
evitas tener que hacer pollings para ver si hay nuevos datos o no y solo
lees cuando sabes que tienes nuevos datos en el fichero.

Espero que algo de esto te sirva.

Un saludo,

Javi

El jue., 4 jul. 2019 a las 21:17, Raúl Alexis Betancor Santana (<
rabs en dimension-virtual.com>) escribió:

> El archivo no está vacío ... le he puesto un sleep de 2s para hacer
> pruebas ANTES de abrir el fichero, y veo que en el FS tiene tamaño, así que
> de vacio nada. Lo que no entiendo es porqué no lee absolutamente nada.
>
> ------------------------------
>
> *De: *"Daπid" <davidmenhur en gmail.com>
> *Para: *"python-es" <python-es en python.org>
> *Enviados: *Jueves, 4 de Julio 2019 19:29:52
> *Asunto: *Re: [Python-es] Leer fichero al mismo tiempo que se está
> escribiendo por otro proceso.
>
> El archivo está vacío, así que chunk es una cadena vacía. Esa función
> asume que el archivo no está creciendo, así que cuando no lee más, el
> archivo está terminado.
>
> On Thu, 4 Jul 2019, 7:56 pm Raúl Alexis Betancor Santana, <
> rabs en dimension-virtual.com> wrote:
>
>> Haciendo más pruebas, he llegado a la conclusión, de que lo que está mal
>> es la función de read_in_chunks ... ya que nunca lee nada y siempre acaba
>> dentro del if not chunk: break ... y no entiendo porque narices.
>>
>> En todos los ejemplos que encuentro por la red para leer un fichero
>> binario por porciones, siempre usan mas o menos el mismo estilo de código
>> para la función, pero esta parece que nunca lee nada.
>>
>> ¿Que estoy haciendo rematadamente mal, que no soy capaz de leer un
>> fichero binario a trozos? ... :-(
>>
>> ------------------------------
>>
>> *De: *"Raúl Alexis Betancor Santana" <rabs en dimension-virtual.com>
>> *Para: *"python-es" <python-es en python.org>
>> *Enviados: *Jueves, 4 de Julio 2019 13:55:56
>> *Asunto: *Re: [Python-es] Leer fichero al mismo tiempo que se está
>> escribiendo por otro proceso.
>>
>> No puedo, los ficheros los genera Asterisk y no voy a estar tocando el
>> código para eso.
>>
>> He probado añadiendo un delay de 250ms al inicio de la lectura, para
>> darle tiempo a que haga un flush a disco, pero tampoco me vá.
>>
>> En realidad lo que me mosquea, es que un ejemplo que tengo en Node.js y
>> que hace exactamente lo mismo, funciona perfectamente, pero el código de
>> python se me queda en el for response in responses: ... osea, no llega
>> nunca a recibir respuesta de GCS o el generador del read_in_chunks no está
>> resolviendo o algo raro.
>>
>> Ahora lo estoy intentando con ARI, porque llevo días intentandolo con un
>> script en python que ejecutaba desde el EAGI y tampoco había forma, o
>> escuchaba el stream de audio y lo interpretaba o reproducía una locución
>> del IVR, pero no ambas cosas al mismo tiempo y hacerlo vía threads, se me
>> complicaba la cosa, hacerlo vía multiprocess y pipes, tenía el problema de
>> que tenía que estar leyendo desde el proceso hijo el FD 3 del proceso
>> padre, un coñazo.
>>
>> Si ha alguien se le ocurre como resolver esto ... estoy abierto a ideas.
>>
>> ------------------------------
>>
>> *De: *"Daπid" <davidmenhur en gmail.com>
>> *Para: *"python-es" <python-es en python.org>
>> *Enviados: *Jueves, 4 de Julio 2019 11:57:11
>> *Asunto: *Re: [Python-es] Leer fichero al mismo tiempo que se está
>> escribiendo por otro proceso.
>>
>> Creo que has encontrado la solución, pero la has puesto en el lugar
>> equivocado.
>>
>> #audio_file = io.open(stream_file+'.sln16','rb',buffering=0)
>>
>> El proceso que está escribiendo al archivo está probablemente usando un
>> buffer, lo que quiere decir que sólo escribe al disco duro de vez en
>> cuando, cuando haya acumulado una cierta cantidad de datos. Si tienes
>> acceso al programa que escribe el archivo, tienes que o bien desactivar el
>> buffer (¡cuidado con el rendimiento!), usar uno más pequeño, o vaciarlo
>> explícitamente con un flush() más a menudo.
>>
>>
>>
>> On Thu, 4 Jul 2019 at 12:28, Raúl Alexis Betancor Santana <
>> rabs en dimension-virtual.com> wrote:
>>
>>> Buenas, estoy intentando hechar a andar el Google Cloud Speech, he
>>> intento leer en stream de un fichero que está siendo escrito por otro
>>> proceso, que contiene la grabación del audio, para enviarla al GCS, pero
>>> sin éxito.
>>>
>>> ¿Alguien me puede comentar que estoy haciendo mal?, con el ejemplo que
>>> da GCS para hacer lo mismo con un fichero directamente, que lo que hace es
>>> leerlo completo en memoria y enviarlo, no me da problemas y transcribe bien
>>> el texto.
>>>
>>> Basandome en el código de ejemplo de GCS para streaming
>>>
>>> def read_in_chunks(file_object,chunk_size):
>>>    """Lazy function (generator) to read a file piece by piece.
>>>    while True:
>>>      chunk = file_object.read(chunk_size)
>>>      if not chunk:
>>>        return
>>>      data = [chunk]
>>>      yield b''.join(data)
>>>
>>> def transcribe_streaming(stream_file,language,timeout):
>>> """Streams transcription of the given audio file."""
>>> from google.cloud import speech
>>> from google.cloud.speech import enums
>>> from google.cloud.speech import types
>>> import io
>>> client = speech.SpeechClient()
>>>
>>> #audio_file = io.open(stream_file+'.sln16','rb',buffering=0)
>>> audio_file = io.open(stream_file+'.sln16','rb')
>>> # In practice, stream should be a generator yielding chunks of audio
>>> data.
>>> requests = (types.StreamingRecognizeRequest(audio_content=chunk)
>>> for chunk in read_in_chunks(audio_file,3200))
>>>
>>> config = types.RecognitionConfig(
>>> encoding=enums.RecognitionConfig.AudioEncoding.LINEAR16,
>>> sample_rate_hertz=16000,
>>> language_code=language)
>>> #streaming_config =
>>> types.StreamingRecognitionConfig(config=config,single_utterance=True)
>>> streaming_config = types.StreamingRecognitionConfig(config=config)
>>>
>>> # streaming_recognize returns a generator.
>>> responses = client.streaming_recognize(streaming_config, requests)
>>> for response in responses:
>>>    # Once the transcription has settled, the first result will contain
>>> the
>>>    # is_final result. The other results will be for subsequent portions
>>> of
>>>    # the audio.
>>>    for result in response.results:
>>>       if result.is_final:
>>>          print('Finished: {}'.format(result.is_final))
>>>          print('Stability: {}'.format(result.stability))
>>>          alternatives = result.alternatives
>>>          ### The alternatives are ordered from most likely to least.
>>>          for alternative in alternatives:
>>>             print('Confidence: {}'.format(alternative.confidence))
>>>             print(u'Transcript: {}'.format(alternative.transcript))
>>> (null)
>>> _______________________________________________
>>> Python-es mailing list
>>> Python-es en python.org
>>> https://mail.python.org/mailman/listinfo/python-es
>>>
>>
>> _______________________________________________
>> Python-es mailing list
>> Python-es en python.org
>> https://mail.python.org/mailman/listinfo/python-es
>>
>>
>> _______________________________________________
>> Python-es mailing list
>> Python-es en python.org
>> https://mail.python.org/mailman/listinfo/python-es
>>
>> _______________________________________________
>> Python-es mailing list
>> Python-es en python.org
>> https://mail.python.org/mailman/listinfo/python-es
>>
>
> _______________________________________________
> Python-es mailing list
> Python-es en python.org
> https://mail.python.org/mailman/listinfo/python-es
>
> _______________________________________________
> Python-es mailing list
> Python-es en python.org
> https://mail.python.org/mailman/listinfo/python-es
>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://mail.python.org/pipermail/python-es/attachments/20190705/85150d24/attachment.html>


Más información sobre la lista de distribución Python-es