extraer archivos comprimidos de la extensión .gz mientras los descarga del servidor ftp [duplicado]

Aug 20 2020

He creado una función que descarga archivos .gz de un servidor ftp determinado y quiero extraerlos sobre la marcha mientras descargo y elimino archivos comprimidos posteriormente. ¿Cómo puedo hacer eso?

sinex_domain = "ftp://cddis.gsfc.nasa.gov/gnss/products/bias/2013"

def download(sinex_domain):
    user = getpass.getuser()
    sinex_parse = urlparse(sinex_domain)

    sinex_connetion = FTP(sinex_parse.netloc)
    sinex_connetion.login()
    sinex_connetion.cwd(sinex_parse.path)
    sinex_files = sinex_connetion.nlst()
    sinex_userpath = "C:\\Users\\" + user + "\\DCBviz\\sinex"
    pathlib.Path(sinex_userpath).mkdir(parents=True, exist_ok=True)

    for fileName in sinex_files:
        local_filename = os.path.join(sinex_userpath, fileName)
        file = open(local_filename, 'wb')
        sinex_connetion.retrbinary('RETR '+ fileName, file.write, 1024)
        
        #want to extract files in this loop

        file.close()

    sinex_connetion.quit()

download(sinex_domain)

Respuestas

1 alani Aug 20 2020 at 02:09

Aunque probablemente haya una forma más inteligente de evitar almacenar todos los datos en la memoria para cada archivo, estos parecen ser archivos bastante pequeños (unas pocas decenas de kilobytes sin comprimir), por lo que sería suficiente leer los datos comprimidos en un BytesIObúfer, luego descomprímalo en la memoria antes de escribirlo en el archivo de salida. (Los datos comprimidos nunca se guardan en el disco).

Agregaría estas importaciones:

import gzip
from io import BytesIO

y luego su bucle principal se convierte en:

    for fileName in sinex_files:
        local_filename = os.path.join(sinex_userpath, fileName)
        if local_filename.endswith('.gz'):
            local_filename = local_filename[:-3]
        data = BytesIO()
        sinex_connetion.retrbinary('RETR '+ fileName, data.write, 1024)
        data.seek(0)
        uncompressed = gzip.decompress(data.read())
        with open(local_filename, 'wb') as file:
            file.write(uncompressed)

(Tenga en cuenta que file.close()no es necesario).