¿Cómo copio un archivo en Python?

3025

¿Cómo copio un archivo en Python?

No pude encontrar nada debajo os.

0
3730

shutiltiene muchos métodos que puede utilizar. Uno de los cuales es:

from shutil import copyfile
copyfile(src, dst)

# 2nd option
copy(src, dst)  # dst can be a folder; use copy2() to preserve timestamp
  • Copie el contenido del archivo nombrado srcen un archivo llamado dst. Ambos srcy dstdeben ser el nombre de archivo completo de los archivos, incluida la ruta.
  • La ubicación de destino debe poder escribirse; de lo contrario, se IOErrorgenerará una excepción.
  • Si dstya existe, será reemplazado.
  • Con esta función no se pueden copiar archivos especiales, como dispositivos de caracteres o bloques y tuberías.
  • Con copy, srcy dstson nombres de ruta dados como strs.

Otro shutilmétodo a considerar es shutil.copy2(). Es similar pero conserva más metadatos (por ejemplo, marcas de tiempo).

Si usa os.pathoperaciones, use en copylugar de copyfile. copyfilesolo aceptará cadenas.

12
  • 183
    ¿Cuál es la diferencia entre copiar y copiar archivo?
    Matt
    23 de septiembre de 2008 a las 19:47
  • 444
    en copia (src, dst) el dst puede ser un directorio.
    Owen
    23 de septiembre de 2008 a las 19:51
  • 49
    Tenga en cuenta que no se copiarán todos los metadatos, dependiendo de su plataforma. 19/10/09 a las 20:50
  • 19
    Tenga en cuenta que no es una operación atómica. Tenga cuidado al usarlo en una aplicación roscada. 22/10/18 a las 11:53
  • 9
    Tenga en cuenta que no puede manejar abreviaturas como ~, pero puede manejar rutas relativas
    zwep
    27 nov 2018 a las 10:00
1674
Función Copia
metadatos

Permisos de copias
Utiliza el objeto de archivo El destino
puede ser directorio
shutil.copy No No
shutil.copyfile No No No No
shutil.copy2 No
shutil.copyfileobj No No No
0
847

copy2(src,dst)suele ser más útil que copyfile(src,dst)porque:

  • permite dstser un directorio (en lugar del nombre completo del archivo de destino), en cuyo caso se usa el nombre base de srcpara crear el nuevo archivo;
  • conserva la información original de modificación y acceso (mtime y atime) en los metadatos del archivo (sin embargo, esto viene con una ligera sobrecarga).

A continuación, se muestra un breve ejemplo:

import shutil
shutil.copy2('/src/dir/file.ext', '/dst/dir/newname.ext') # complete target filename given
shutil.copy2('/src/file.ext', '/dst/dir') # target filename is /dst/dir/file.ext
1
  • 33
    Estoy tratando de copiar aleatoriamente 100k archivos de 1 millón de archivos. copyfilees considerablemente más rápido quecopy2
    Vijay
    7 de mayo de 2014 a las 8:31
163

Puede utilizar una de las funciones de copia del shutilpaquete:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Function              preserves     supports          accepts     copies other
                      permissions   directory dest.   file obj    metadata  
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
shutil.copy              ✔             ✔                 ☐           ☐
shutil.copy2             ✔             ✔                 ☐           ✔
shutil.copyfile          ☐             ☐                 ☐           ☐
shutil.copyfileobj       ☐             ☐                 ✔           ☐
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Ejemplo:

import shutil
shutil.copy('/etc/hostname', '/var/tmp/testhostname')
3
  • 23
    Solo por curiosidad, ¿cómo generaste esa tabla? 2 de diciembre de 2018 a las 7:40
  • 29
    @lightalchemist Acabo de usar vim como un bloc de notas, copié los símbolos unicode usados ​​de una tabla de wikipedia y copié el resultado en el editor de stackoverflow para el pulido final. 2 dic 2018 a las 17:02
  • 17
    está bien. YMMV, pero creo que los cambios cosméticos y las mejoras menores como esa se realizan mejor como ediciones en las respuestas existentes, en lugar de duplicar las respuestas.
    wim
    8/11/19 a las 22:04
159

En Python, puede copiar los archivos usando


import os
import shutil
import subprocess

1) Copiar archivos usando el shutilmódulo

shutil.copyfile firma

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

# example    
shutil.copyfile('source.txt', 'destination.txt')

shutil.copy firma

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

# example
shutil.copy('source.txt', 'destination.txt')

shutil.copy2 firma

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

# example
shutil.copy2('source.txt', 'destination.txt')  

shutil.copyfileobj firma

shutil.copyfileobj(src_file_object, dest_file_object[, length])

# example
file_src = 'source.txt'  
f_src = open(file_src, 'rb')

file_dest = 'destination.txt'  
f_dest = open(file_dest, 'wb')

shutil.copyfileobj(f_src, f_dest)  

2) Copiar archivos usando el osmódulo

os.popen firma

os.popen(cmd[, mode[, bufsize]])

# example
# In Unix/Linux
os.popen('cp source.txt destination.txt') 

# In Windows
os.popen('copy source.txt destination.txt')

os.system firma

os.system(command)


# In Linux/Unix
os.system('cp source.txt destination.txt')  

# In Windows
os.system('copy source.txt destination.txt')

3) Copiar archivos usando el subprocessmódulo

subprocess.call firma

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

# example (WARNING: setting `shell=True` might be a security-risk)
# In Linux/Unix
status = subprocess.call('cp source.txt destination.txt', shell=True) 

# In Windows
status = subprocess.call('copy source.txt destination.txt', shell=True)

subprocess.check_output firma

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

# example (WARNING: setting `shell=True` might be a security-risk)
# In Linux/Unix
status = subprocess.check_output('cp source.txt destination.txt', shell=True)

# In Windows
status = subprocess.check_output('copy source.txt destination.txt', shell=True)

5
  • 10
    El uso de comandos de una sola cadena es un estilo de codificación incorrecto (flexibilidad, confiabilidad y seguridad); en su lugar, use la ['copy', sourcefile, destfile]sintaxis siempre que sea posible, especialmente si los parámetros provienen de la entrada del usuario. 29/04/19 a las 3:03
  • 11
    ¿Por qué enumera tantas malas alternativas a las funciones de copia de shutil? 29/04/19 a las 11:08
  • 12
    shutil está integrado, no es necesario proporcionar alternativas no portátiles. La respuesta podría mejorarse eliminando las soluciones dependientes del sistema, y ​​después de esa eliminación, esta respuesta es solo una copia de las respuestas existentes / una copia de la documentación. 29/04/19 a las 17:19
  • 4
    os.popenestá en desuso por un tiempo. y check_outputno devuelve el estado sino la salida (que está vacía en el caso de copy/cp) 29/04/19 a las 18:12
  • 2
    shutil en realidad no copia archivos. Hay una gran advertencia en la parte superior de los documentos . "esto significa que el propietario y el grupo del archivo se pierden, así como las ACL. En Mac OS, la bifurcación de recursos y otros metadatos no se utilizan. Esto significa que los recursos se perderán y el tipo de archivo y los códigos de creador no serán correctos. En Windows, los propietarios de archivos, las ACL y los flujos de datos alternativos no se copian ".
    gman
    25 nov 2019 a las 3:03
105

Copiar un archivo es una operación relativamente sencilla como se muestra en los ejemplos a continuación, pero en su lugar debería usar el módulo shutil stdlib para eso.

def copyfileobj_example(source, dest, buffer_size=1024*1024):
    """      
    Copy a file from source to dest. source and dest
    must be file-like objects, i.e. any object with a read or
    write method, like for example StringIO.
    """
    while True:
        copy_buffer = source.read(buffer_size)
        if not copy_buffer:
            break
        dest.write(copy_buffer)

Si desea copiar por nombre de archivo, puede hacer algo como esto:

def copyfile_example(source, dest):
    # Beware, this example does not handle any edge cases!
    with open(source, 'rb') as src, open(dest, 'wb') as dst:
        copyfileobj_example(src, dst)
1
  • 25
    Hace un tiempo noté que el módulo se llama shutil (singular) y no shutils (plural), y de hecho está en Python 2.3. No obstante dejo aquí esta función como ejemplo.
    pi.
    31/03/09 a las 15:20
76

Utilice el módulo shutil .

copyfile(src, dst)

Copie el contenido del archivo llamado src a un archivo llamado dst. La ubicación de destino debe poder escribirse; de lo contrario, se generará una excepción IOError. Si dst ya existe, será reemplazado. Con esta función no se pueden copiar archivos especiales, como dispositivos de caracteres o bloques y tuberías. src y dst son nombres de ruta dados como cadenas.

Eche un vistazo a filesys para conocer todas las funciones de manejo de archivos y directorios disponibles en los módulos estándar de Python.

0
49

Ejemplo de copia de directorio y archivo: de las cosas de Python de Tim Golden:

http://timgolden.me.uk/python/win32_how_do_i/copy-a-file.html

import os
import shutil
import tempfile

filename1 = tempfile.mktemp (".txt")
open (filename1, "w").close ()
filename2 = filename1 + ".copy"
print filename1, "=>", filename2

shutil.copy (filename1, filename2)

if os.path.isfile (filename2): print "Success"

dirname1 = tempfile.mktemp (".dir")
os.mkdir (dirname1)
dirname2 = dirname1 + ".copy"
print dirname1, "=>", dirname2

shutil.copytree (dirname1, dirname2)

if os.path.isdir (dirname2): print "Success"
0
31

En primer lugar, hice una hoja de trucos exhaustiva de métodos shutil para su referencia.

shutil_methods =
{'copy':['shutil.copyfileobj',
          'shutil.copyfile',
          'shutil.copymode',
          'shutil.copystat',
          'shutil.copy',
          'shutil.copy2',
          'shutil.copytree',],
 'move':['shutil.rmtree',
         'shutil.move',],
 'exception': ['exception shutil.SameFileError',
                 'exception shutil.Error'],
 'others':['shutil.disk_usage',
             'shutil.chown',
             'shutil.which',
             'shutil.ignore_patterns',]
}

En segundo lugar, explique los métodos de copia en ejemplos:

  1. shutil.copyfileobj(fsrc, fdst[, length]) manipulate opened objects
In [3]: src = '~/Documents/Head+First+SQL.pdf'
In [4]: dst = '~/desktop'
In [5]: shutil.copyfileobj(src, dst)
AttributeError: 'str' object has no attribute 'read'
#copy the file object
In [7]: with open(src, 'rb') as f1,open(os.path.join(dst,'test.pdf'), 'wb') as f2:
    ...:      shutil.copyfileobj(f1, f2)
In [8]: os.stat(os.path.join(dst,'test.pdf'))
Out[8]: os.stat_result(st_mode=33188, st_ino=8598319475, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=13507926, st_atime=1516067347, st_mtime=1516067335, st_ctime=1516067345)
  1. shutil.copyfile(src, dst, *, follow_symlinks=True) Copy and rename
In [9]: shutil.copyfile(src, dst)
IsADirectoryError: [Errno 21] Is a directory: ~/desktop'
#so dst should be a filename instead of a directory name
  1. shutil.copy() Copy without preseving the metadata
In [10]: shutil.copy(src, dst)
Out[10]: ~/desktop/Head+First+SQL.pdf'
#check their metadata
In [25]: os.stat(src)
Out[25]: os.stat_result(st_mode=33188, st_ino=597749, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=13507926, st_atime=1516066425, st_mtime=1493698739, st_ctime=1514871215)
In [26]: os.stat(os.path.join(dst, 'Head+First+SQL.pdf'))
Out[26]: os.stat_result(st_mode=33188, st_ino=8598313736, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=13507926, st_atime=1516066427, st_mtime=1516066425, st_ctime=1516066425)
# st_atime,st_mtime,st_ctime changed
  1. shutil.copy2() Copy with preseving the metadata
In [30]: shutil.copy2(src, dst)
Out[30]: ~/desktop/Head+First+SQL.pdf'
In [31]: os.stat(src)
Out[31]: os.stat_result(st_mode=33188, st_ino=597749, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=13507926, st_atime=1516067055, st_mtime=1493698739, st_ctime=1514871215)
In [32]: os.stat(os.path.join(dst, 'Head+First+SQL.pdf'))
Out[32]: os.stat_result(st_mode=33188, st_ino=8598313736, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=13507926, st_atime=1516067063, st_mtime=1493698739, st_ctime=1516067055)
# Preseved st_mtime
  1. shutil.copytree()

Copie de forma recursiva un árbol de directorios completo enraizado en src, devolviendo el directorio de destino

0
29

Para archivos pequeños y usando solo elementos integrados de Python, puede usar el siguiente resumen:

with open(source, 'rb') as src, open(dest, 'wb') as dst: dst.write(src.read())

Como @maxschlepzig mencionó en los comentarios a continuación, esta no es la forma óptima para aplicaciones donde el archivo es demasiado grande o cuando la memoria es crítica, por lo que se debe preferir la respuesta de Swati .

0
17

Podrías usar os.system('cp nameoffilegeneratedbyprogram /otherdirectory/')

o como lo hice yo,

os.system('cp '+ rawfile + ' rawdata.dat')

donde rawfileestá el nombre que había generado dentro del programa.

Esta es una solución única para Linux

5
  • 11
    esto no es portátil e innecesario ya que solo puede usar shutil. 12/06/17 a las 14:05
  • 5
    Incluso cuando shutilno está disponible, subprocess.run() ( shell=True¡ sin !) Es la mejor alternativa a os.system(). 9/07/2017 a las 11:52
  • 2
    shutil es más portátil
    Hiadore
    12 mar 2019 a las 9:07
  • 2
    subprocess.run()como sugiere @maxschlepzig es un gran paso adelante, cuando se llaman programas externos. Sin embargo, para mayor flexibilidad y seguridad, utilice la ['cp', rawfile, 'rawdata.dat']forma de pasar la línea de comando. (Sin embargo, para copiar, shutilse recomienda a los amigos en lugar de llamar a un programa externo). 29/04/19 a las 3:09
  • 2
    intente eso con nombres de archivo con espacios en él. 29/04/19 a las 17:21
15

A partir de Python 3.5 , puede hacer lo siguiente para archivos pequeños (es decir, archivos de texto, jpegs pequeños):

from pathlib import Path

source = Path('../path/to/my/file.txt')
destination = Path('../path/where/i/want/to/store/it.txt')
destination.write_bytes(source.read_bytes())

write_bytes sobrescribirá lo que haya en la ubicación del destino

2
  • 2
    Y luego alguien usa el código (accidental o intencionalmente) en un archivo grande ... El uso de funciones de shutilmaneja todos los casos especiales por usted y le brinda tranquilidad. 29/04/19 a las 3:21
  • 7
    al menos no repite las mismas soluciones una y otra vez. 29/04/19 a las 18:16
13

Para archivos grandes, lo que hice fue leer el archivo línea por línea y leer cada línea en una matriz. Luego, una vez que la matriz alcanzó un cierto tamaño, agréguela a un nuevo archivo.

for line in open("file.txt", "r"):
    list.append(line)
    if len(list) == 1000000: 
        output.writelines(list)
        del list[:]
7
  • 2
    esto parece un poco redundante ya que el escritor debería manejar el almacenamiento en búfer. for l in open('file.txt','r'): output.write(l)debe encontrar trabajo; simplemente configure el búfer de flujo de salida según sus necesidades. o puede ir por los bytes haciendo un bucle en un intento con output.write(read(n)); output.flush()donde nes el número de bytes que le gustaría escribir a la vez. ambos tampoco tienen una condición para verificar cuál es una bonificación.
    owns
    12 jun 15 a las 17:30
  • 1
    Sí, pero pensé que tal vez esto podría ser más fácil de entender porque copia líneas completas en lugar de partes de ellas (en caso de que no sepamos cuántos bytes tiene cada línea). 13/06/15 a las 18:42
  • Muy cierto. La codificación para la enseñanza y la codificación para la eficiencia son muy diferentes.
    owns
    15/06/15 a las 17:47
  • 1
    mirando la fuente - writeelines llama a write, hg.python.org/cpython/file/c6880edaf6f3/Modules/_io/bytesio.c . Además, la secuencia de archivos ya está abierta, por lo que la escritura no necesitaría volver a abrirla cada vez.
    owns
    3 de mayo de 2017 a las 0:24
  • 2
    Esto es espantoso. Hace un trabajo innecesario sin una buena razón. No funciona para archivos arbitrarios. La copia no es idéntica en bytes si la entrada tiene finales de línea inusuales en sistemas como Windows. ¿Por qué cree que esto podría ser más fácil de entender que una llamada a una función de copia en shutil? Incluso cuando se ignora shutil, un bucle simple de lectura / escritura en bloque (usando E / S sin búfer) es sencillo, sería eficiente y tendría mucho más sentido que esto, y por lo tanto, seguramente es más fácil de enseñar y comprender. 29/04/19 a las 19:04
12

Use subprocess.callpara copiar el archivo

from subprocess import call
call("cp -p <file> <file>", shell=True)
5
  • dieciséis
    Esto depende de la plataforma, por lo que no lo usaría. 13 de septiembre de 2016 a las 10:02
  • 7
    Eso callno es seguro. Consulte el documento de subprocesos al respecto.
    buhtz
    2/04/2017 a las 7:57
  • 4
    esto no es portátil e innecesario ya que solo puede usar shutil. 12/06/17 a las 14:05
  • 4
    Hmm, ¿por qué Python, entonces? 7 de julio de 2017 a las 9:29
  • Quizás detecte el sistema operativo antes de comenzar (ya sea DOS o Unix, porque esos son los dos más usados) 9/11/18 a las 15:51
10
open(destination, 'wb').write(open(source, 'rb').read())

Abra el archivo de origen en modo de lectura y escriba en el archivo de destino en modo de escritura.

6
  • 2
    La idea es agradable y el código es hermoso, pero una función copy () adecuada puede hacer más cosas, como copiar atributos (+ x bit) o, por ejemplo, eliminar los bytes ya copiados en caso de que se encuentre una condición de disco lleno . 29/03/19 a las 11:06
  • 1
    Todas las respuestas necesitan explicación, incluso si es una oración. Ninguna explicación sienta un mal precedente y no ayuda a comprender el programa. ¿Qué pasa si un novato completo de Python llega y ve esto, quiere usarlo, pero no puede porque no lo entiende? Quieres ayudar a todos en tus respuestas. 30/03/19 a las 22:19
  • 3
    ¿No es eso que falta .close()en todas esas open(...)s? 22/04/19 a las 22:37
  • No es necesario .close (), ya que NO ESTAMOS ALMACENANDO el objeto del puntero del archivo en ningún lugar (ni para el archivo src ni para el archivo de destino). 23/04/19 a las 21:19
  • 2
    El mismo enfoque de pérdida de memoria subóptimo que la respuesta de yellow01 . 29/04/19 a las 11:04
6

Aquí tienes una forma sencilla de hacerlo, sin ningún módulo. Es similar a esta respuesta , pero tiene la ventaja de que también funciona si es un archivo grande que no cabe en la RAM:

with open('sourcefile', 'rb') as f, open('destfile', 'wb') as g:
    while True:
        block = f.read(16*1024*1024)  # work by blocks of 16 MB
        if not block:  # end of file
            break
        g.write(block)

Dado que estamos escribiendo un archivo nuevo, no conserva el tiempo de modificación, etc.
Entonces podemos usarlo os.utimepara esto si es necesario.

6

En caso de que hayas llegado tan abajo. La respuesta es que necesita la ruta completa y el nombre del archivo.

import os

shutil.copy(os.path.join(old_dir, file), os.path.join(new_dir, file))
3

De manera similar a la respuesta aceptada, el siguiente bloque de código puede ser útil si también desea asegurarse de crear carpetas (inexistentes) en la ruta al destino.

from os import path, makedirs
from shutil import copyfile
makedirs(path.dirname(path.abspath(destination_path)), exist_ok=True)
copyfile(source_path, destination_path)

Como indican las respuestas aceptadas, estas líneas sobrescribirán cualquier archivo que exista en la ruta de destino, por lo que a veces puede ser útil agregar también: if not path.exists(destination_path):antes de este bloque de código.

-3

Python proporciona funciones integradas para copiar archivos fácilmente utilizando las utilidades Shell del sistema operativo.

El siguiente comando se usa para copiar archivo

shutil.copy(src,dst)

El siguiente comando se usa para copiar archivos con información de metadatos

shutil.copystat(src,dst)
1
  • copyLuego, debe ejecutarlo copystatpara conservar los metadatos del archivo. En Python 3.3+ copystattambién copia atributos extendidos. 22 de mayo de 2020 a las 17:25