Cómo copiar un archivo en Python

Introducción

Cuando se trata de usar Python para copiar archivos, hay dos formas principales: usar el módulo shutil o el módulo os. Todos los métodos os que mostramos aquí son métodos que nos permiten ejecutar comandos de shell desde nuestro código Python, que usaremos para ejecutar el comando copy (Windows) o el comando cp (Unix).

Notará que muchos de estos métodos, tanto en el módulo shutil como en el módulo os, tienen una funcionalidad muy similar (lo que no debería sorprender), pero cada uno varía en funcionalidad entre sí muy ligeramente, lo que también explicaré.

Copiar archivos con el módulo shutil

El módulo shutil ofrece varios métodos de alto nivel para copiar archivos. A continuación, se enumeran las principales:

copyfile

Este método copia el contenido de un archivo en otro archivo. El destino que se le proporcione debe ser un archivo con escritura y tener un nombre diferente al del archivo de origen. Si los nombres son los mismos, generará un error. Si el archivo de destino ya existe, se reemplazará con el archivo recién copiado.

La sintaxis para este método es:

shutil.copyfile(src_file, dest_file, *, follow_symlinks=True)

Por ejemplo, el siguiente código copiará un archivo llamado «file1.txt «en un archivo llamado» file2.txt»:

import shutilshutil.copyfile('file1.txt', 'file2.txt')

Una interesante y potencialmente útil característica de shutil.copyfile es el follow_symlinks argumento Booleano. Si se establece en False, y el archivo de origen es un enlace simbólico, entonces en lugar de copiar el archivo, se creará un nuevo enlace simbólico.

copy

Este método es muy similar a copyfile, con la principal diferencia de que, además de copiar el contenido del archivo de origen, va un paso más allá y también copia los permisos del sistema de archivos del archivo. Copiar permisos de archivo no es una tarea trivial en la mayoría de los lenguajes de programación, por lo que esta es una buena característica.

la sintaxis es La siguiente:

shutil.copy(src_file, dest_file, *, follow_symlinks=True)

Cada uno de estos parámetros son los mismos que en el copyfile método. Por ejemplo, el siguiente código copiará «file1″.txt» a «archivo3.txt».

import shutilshutil.copy('file1.txt', 'file3.txt')

Nota: Asegúrese de no asignar a su script el mismo nombre que a uno de los módulos que está importando (lo que hice por error al probar el código de este artículo). Si lo hace, obtendrá un error al intentar importar ese módulo debido a un problema de importación circular.

copy2

Al igual que con los métodos anteriores, el método copy2 es idéntico al método copy, pero además de copiar el contenido del archivo, también intenta conservar todos los metadatos del archivo de origen. Si la plataforma no permite guardar metadatos completos, copy2 no devuelve el error y solo conservará los metadatos que pueda.

La sintaxis es la siguiente:

shutil.copy2(src_file, dest_file, *, follow_symlinks=True)

De nuevo, estos parámetros son los mismos que en los comandos anteriores que hemos mencionado hasta ahora.

Por ejemplo, el siguiente código copiará » file1.txt «en» archivo 4.txt», así como preservar los metadatos del archivo original, » file1.txt».

import shutilshutil.copy2('file1.txt', 'file4.txt')
$ python copy-files.py $ ls -ltotal 32-rw-r--r-- 1 scott staff 91 Oct 27 11:26 copy-files.py-rw-r--r-- 1 scott staff 6 Oct 27 11:27 file1.txt-rw-r--r-- 1 scott staff 6 Oct 27 11:29 file3.txt-rw-r--r-- 1 scott staff 6 Oct 27 11:27 file4.txt

Como podemos ver al ejecutar nuestro código anterior, «file1.txt «se copió al archivo» 4.txt». Sin embargo, es posible que haya notado que la fecha de creación se conservó en el nuevo archivo, a diferencia de shutil.copy, que copió «file1.txt» a «archivo3.txt » y le dio una nueva fecha de creación.

copyfileobj

Este método copia el contenido de un archivo de origen en un archivo de destino, desde la posición actual del archivo de origen. Lo que esto significa es que si lee datos de su objeto de archivo de origen, la posición en la que deja de leer es la posición desde la que copyfileobj comienza a copiar.

La sintaxis es la siguiente:

shutil.copyfileobj(src_file_object, dest_file_object)

Los significados de los parámetros de archivo de origen y destino son similares a los comandos anteriores, pero ahora se refieren a objetos. El parámetro length es opcional y representa el tamaño del búfer, que es el número de bocetos que se guardan en la memoria durante el proceso de copia. Esta opción puede ser útil al copiar archivos muy grandes, ya que puede acelerar el proceso de copia y evitar el uso incontrolado de la memoria.

Por ejemplo, el siguiente código copiará » file1.txt «en» archivo 5.txt»

import shutilfilename1 = 'file1.txt'fileA = open(filename1, 'rb')filename2 = 'file5.txt'fileB = open(filename2, 'wb')shutil.copyfileobj(fileA, fileB)

Como podemos ver, en orden a usar copyfileobj, necesitamos abrir los archivos en modo binario (que es la «b» parte de «rb» y «wb»). Además, el archivo de origen debe abrirse como legible y el archivo de destino debe abrirse como escribible (las partes» r «y» w», respectivamente).

Copiar archivos con el módulo de sistema operativo

El módulo de sistema operativo proporciona una forma de usar la funcionalidad del sistema operativo para copiar sus archivos. En la mayoría (si no en todos) de los ejemplos de aquí en adelante, proporcionamos ejemplos que funcionan tanto para Windows como para Unix. Los ejemplos son diferentes debido a los comandos de shell utilizados, así que asegúrese de prestar atención a cómo se etiqueta cada llamada a función en los comentarios de Python.

popen

Este método abre una tubería hacia o desde el comando. Sin embargo, tenga en cuenta que este método fue obsoleto en Python 2.6, por lo que no recomendamos usarlo a menos que tenga que hacerlo. Como alternativa, la documentación de Python nos aconseja usar métodos del módulo de subproceso en su lugar.

la sintaxis es La siguiente:

os.popen(cmd])

Aquí el valor devuelto es un objeto de archivo que está conectado a la tubería. Este objeto se puede leer o escribir en función del modo. El modo predeterminado es ‘r’, que permite leer el contenido del archivo.

El siguiente ejemplo copiará » file1.txt «en» archivo 6.txt»:

import os# Windowsos.popen('copy file1.txt file6.txt')# Unixos.popen('cp file1.txt file6.txt')

Ejecutar el comando de esta manera es exactamente lo mismo que si lo ejecutara directamente desde la línea de comandos de su terminal.

system

Este método ejecuta el comando especificado en una subcapa. Está disponible para Unix y Windows. La sintaxis es la siguiente:

os.system(command)

Aquí command es una cadena que contiene el comando de shell de DOS o Unix. En nuestro caso, aquí es donde pondremos el comando copy o cp.

Por ejemplo, el siguiente código copiará » file1.txt «en» archivo 7.txt «

import os# Windowsos.system('copy file1.txt file7.txt')# Unixos.system('cp file1.txt file7.txt')

Esto se ve idéntico al comando anterior os.popen que acabamos de usar, pero el comando se ejecuta en una subcapa, lo que significa que se ejecuta en un subproceso separado en paralelo a su código de ejecución. A esperar a su finalización, deberá llamar a .wait() en el objeto devuelto por os.system.

Copiar archivos con el módulo de subproceso

El módulo de subproceso pretende reemplazar algunos métodos en el módulo os (en particular, los métodos os.system y os.spawn*), y presenta dos métodos principales para acceder a los comandos del sistema operativo. Estos métodos son call y check_output. Una vez más, para sistemas Unix, el comando » copiar archivo1.txt archivo2.txt «debe ser reemplazado por» archivo cp1.txt archivo2.txt».

método de llamada

La documentación de Python nos recomienda usar el método call para iniciar un comando desde el sistema operativo.

la sintaxis es La siguiente:

subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)

El args parámetro incluirá el comando de la shell. Sin embargo, una advertencia, ya que la documentación de Python nos advierte que usar shell=True puede ser un riesgo de seguridad.

Usando esta llamada a función, podemos ejecutar nuestro comando copiar de la siguiente manera:

import subprocess# Windowsstatus = subprocess.call('copy file1.txt file8.txt', shell=True)# Unixstatus = subprocess.call('cp file1.txt file8.txt', shell=True)

Como se muestra en el ejemplo anterior, simplemente necesitamos pasar una cadena con el comando shell, como antes.

Y como se esperaba, el sistema operativo copiará » file1.txt «en un archivo llamado» file8.txt».

Método check_output

Este método también nos permite ejecutar un comando dentro de un shell. Es muy similar al comando subprocess.run, excepto que, por defecto, canaliza los datos de la salida estándar como bytes codificados. La sintaxis es la siguiente:

subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False)

Aquí args parámetro incluye el comando de shell que queremos usar. Una vez más, la documentación de Python nos advierte de usar shell=True, así que use este método con precaución.

En el siguiente código copiaremos » file1.txt » a » archivo 9.txt » usando el comando check_output:

import subprocess# Windowsstatus = subprocess.check_output('copy file1.txt file9.txt', shell=True)# Unixstatus = subprocess.check_output('cp file1.txt file9.txt', shell=True)

Y como con todos los comandos que hemos mostrado en este artículo, esto copiará el archivo » file1.txt » al destino que especificamos, que es «file9.txt» aquí.

Wrapping Up

Python nos ofrece muchas formas diferentes de copiar archivos, algunos de los cuales forman parte del conjunto de métodos de Python. Otros usan algunos de los poderosos métodos de Python para ejecutar comandos en un shell, que utilizan comandos de shell como copy o cp.

No está seguro de cuál es el adecuado para usted? Presentamos muchas formas diferentes de copiar archivos aquí, por lo que es comprensible. El método que utilice para copiar un archivo depende completamente de usted y dependerá de sus necesidades específicas. Aunque en la mayoría de los casos uno de los comandos shutil funcionará bien para usted. Intente comenzar con shutil.copy2 y vea si eso hace lo que necesita.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *