gpt4 book ai didi

How to copy files(如何复制文件)

转载 作者:bug小助手 更新时间:2023-10-22 16:39:01 32 4
gpt4 key购买 nike



How do I copy a file in Python?

如何在Python中复制文件?


更多回答

It would be nice if you specify a reason for copy. For many applications hard linking may be a viable alternative. And people looking for such solutions may also think about this "copy" opportunity (like me, but my answer here was downvoted).

如果您指定复制的原因,那就太好了。对于许多应用程序来说,硬链接可能是一种可行的替代方案。寻求此类解决方案的人可能也会考虑这个“复制”机会(和我一样,但我在这里的回答被否决了)。

优秀答案推荐

shutil has many methods you can use. One of which is:

shutil有很多方法可以使用。其中之一是:


import shutil

shutil.copyfile(src, dst)

# 2nd option
shutil.copy(src, dst) # dst can be a folder; use shutil.copy2() to preserve timestamp


  • Copy the contents of the file named src to a file named dst. Both src and dst need to be the entire filename of the files, including path.

  • The destination location must be writable; otherwise, an IOError exception will be raised.

  • If dst already exists, it will be replaced.

  • Special files such as character or block devices and pipes cannot be copied with this function.

  • With copy, src and dst are path names given as strs.


Another shutil method to look at is shutil.copy2(). It's similar but preserves more metadata (e.g. time stamps).

另一个shutil方法是shutil.copy2()。它很相似,但保留了更多的元数据(例如时间戳)。


If you use os.path operations, use copy rather than copyfile. copyfile will only accept strings.

如果使用os.path操作,请使用copy而不是copyfile。复制文件将只接受字符串。












































Function Copies
metadata
Copies
permissions
Uses file object Destination
may be directory
shutil.copy No Yes No Yes
shutil.copyfile No No No No
shutil.copy2 Yes Yes No Yes
shutil.copyfileobj No No Yes No


copy2(src,dst) is often more useful than copyfile(src,dst) because:

copy2(src,dst)通常比copyfile(src,gst)更有用,因为:




  • it allows dst to be a directory (instead of the complete target filename), in which case the basename of src is used for creating the new file;

  • it preserves the original modification and access info (mtime and atime) in the file metadata (however, this comes with a slight overhead).



Here is a short example:

下面是一个简短的例子:



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


In Python, you can copy the files using

在Python中,可以使用





import os
import shutil
import subprocess



1) Copying files using shutil module


shutil.copyfile signature

shutil.copyfile签名


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

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



shutil.copy signature

shutil.copy签名


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

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



shutil.copy2 signature

shutil.copy2签名


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

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



shutil.copyfileobj signature

shutil.copyfileobj签名


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) Copying files using os module


os.popen signature

os.popen签名


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 signature

操作系统签名


os.system(command)


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

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



3) Copying files using subprocess module


subprocess.call signature

subprocess.call签名


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 signature

子进程检查输出签名


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)




You can use one of the copy functions from the shutil package:

您可以使用shutil包中的复制功能之一:




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


Example:

示例:



import shutil
shutil.copy('/etc/hostname', '/var/tmp/testhostname')


Copying a file is a relatively straightforward operation as shown by the examples below, but you should instead use the shutil stdlib module for that.

如下面的示例所示,复制文件是一个相对简单的操作,但您应该使用shutil stdlib模块。



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)


If you want to copy by filename you could do something like this:

如果你想按文件名复制,你可以这样做:



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)


Use the shutil module.

使用shutil模块。


copyfile(src, dst)

Copy the contents of the file named src to a file named dst. The destination location must be writable; otherwise, an IOError exception will be raised. If dst already exists, it will be replaced. Special files such as character or block devices and pipes cannot be copied with this function. src and dst are path names given as strings.

将名为src的文件的内容复制到名为dst的文件中。目标位置必须是可写的;否则,将引发IOError异常。如果dst已经存在,它将被替换。使用此功能无法复制字符或块设备和管道等特殊文件。src和dst是以字符串形式给出的路径名。


Take a look at filesys for all the file and directory handling functions available in standard Python modules.

查看filesys,了解标准Python模块中可用的所有文件和目录处理功能。



Directory and File copy example, from Tim Golden's Python Stuff:

目录和文件复制示例,来自Tim Golden的Python Stuff:


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"


For small files and using only Python built-ins, you can use the following one-liner:

对于小文件和仅使用Python内置程序,您可以使用以下一行:


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

This is not optimal way for applications where the file is too large or when memory is critical, thus Swati's answer should be preferred.

对于文件太大或内存很关键的应用程序来说,这不是最佳方式,因此应该首选Swati的答案。



Firstly, I made an exhaustive cheat sheet of the shutil methods for your reference.

首先,我做了一个详尽的shutil方法的备忘单供您参考。


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',]
}

Secondly, explaining methods of copy in examples:

其次,举例说明复制的方法:



  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)


  2. 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


  3. 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


  4. shutil.copy2() Copy with preserving 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)
    # Preserved st_mtime


  5. shutil.copytree()


    Recursively copy an entire directory tree rooted at src, returning the destination directory.





As of Python 3.5 you can do the following for small files (ie: text files, small jpegs):

从Python 3.5开始,您可以对小文件(即:文本文件、小jpegs)执行以下操作:



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 will overwrite whatever was at the destination's location

write_bytes将覆盖目标位置的内容



You could use os.system('cp nameoffilegeneratedbyprogram /otherdirectory/').

你可以使用os.system('cp-nameofflegendatedbyprogram/otherdirectory/')。


Or as I did it,

或者就在我做的时候,


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

where rawfile is the name that I had generated inside the program.

其中rawfile是我在程序中生成的名称。


This is a Linux-only solution.

这是一个仅限Linux的解决方案。



There are two best ways to copy file in Python.

在Python中复制文件有两种最好的方法。


1. We can use the shutil module


Code Example:

代码示例:


import shutil
shutil.copyfile('/path/to/file', '/path/to/new/file')

There are other methods available also other than copyfile, like copy, copy2, etc, but copyfile is best in terms of performance,

除了复制文件,还有其他可用的方法,如复制、复制2等,但复制文件的性能最好,


2. We can use the OS module


Code Example:

代码示例:


import os
os.system('cp /path/to/file /path/to/new/file')

Another method is by the use of a subprocess, but it is not preferable as it’s one of the call methods and is not secure.

另一种方法是使用子流程,但这不是最好的方法,因为它是调用方法之一,不安全。



Use

使用


open(destination, 'wb').write(open(source, 'rb').read())

Open the source file in read mode, and write to the destination file in write mode.

在读取模式下打开源文件,在写入模式下写入目标文件。



Use subprocess.call to copy the file

使用subprocess.call复制文件


from subprocess import call
call("cp -p <file> <file>", shell=True)


For large files, I read the file line by line and read each line into an array. Then, once the array reached a certain size, append it to a new file.

对于大文件,我逐行读取文件,并将每一行读取到一个数组中。然后,一旦数组达到一定的大小,就将其附加到一个新文件中。


for line in open("file.txt", "r"):
list.append(line)
if len(list) == 1000000:
output.writelines(list)
del list[:]


In case you've come this far down. The answer is that you need the entire path and file name

万一你已经走了这么远了。答案是您需要完整的路径和文件名


import os

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


Here is a simple way to do it, without any module. It's similar to this answer, but has the benefit to also work if it's a big file that doesn't fit in RAM:

这里有一个简单的方法,不需要任何模块。它与这个答案类似,但如果它是一个不适合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)

Since we're writing a new file, it does not preserve the modification time, etc.

We can then use os.utime for this if needed.

由于我们正在编写一个新文件,它不会保留修改时间等。如果需要,我们可以使用os.utime。



Similar to the accepted answer, the following code block might come in handy if you also want to make sure to create any (non-existent) folders in the path to the destination.

与公认的答案类似,如果您还想确保在目标路径中创建任何(不存在的)文件夹,下面的代码块可能会派上用场。


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

As the accepted answers notes, these lines will overwrite any file which exists at the destination path, so sometimes it might be useful to also add: if not path.exists(destination_path): before this code block.

正如接受的答案所指出的,这些行将覆盖目标路径中存在的任何文件,因此有时也可以在此代码块之前添加:if not path.exists(destination_path):。



I would like to propose a different solution.

我想提出一个不同的解决方案。


def copy(source, destination):
with open(source, 'rb') as file:
myFile = file.read()
with open(destination, 'wb') as file:
file.write(myFile)

copy("foo.txt", "bar.txt")

The file is opened, and it's data is written to a new file of your choosing.

文件被打开,它的数据被写入到您选择的新文件中。



For the answer everyone recommends, if you prefer not to use the standard modules, or have completely removed them as I've done, preferring more core C methods over poorly written python methods

对于每个人建议的答案,如果你不喜欢使用标准模块,或者像我所做的那样完全删除了它们,那么你更喜欢核心的C方法,而不是写得不好的python方法


The way shutil works is symlink/hardlink safe, but is rather slow due to os.path.normpath() containing a while (nt, mac) or for (posix) loop, used in testing if src and dst are the same in shutil.copyfile()

shutil的工作方式是符号链接/硬链接安全的,但由于os.path.normpath()包含while(nt,mac)或for(posix)循环(用于测试shutil.copyfile()中的src和dst是否相同),因此速度相当慢


This part is mostly unneeded if you know for certain src and dst will never be the same file, otherwise a faster C approach could potentially be used.

(note that just because a module may be C doesn't inherently mean it's faster, know that what you use is actually written well before you use it)

如果您知道某些src和dst永远不会是同一个文件,那么这部分基本上是不需要的,否则可能会使用更快的C方法。(请注意,模块可能是C并不意味着它本质上更快,在使用之前要知道你使用的东西实际上已经写好了)


After that initial testing, copyfile() runs a for loop on a dynamic tuple of (src, dst), testing for special files (such as sockets or devices in posix).

在初始测试之后,copyfile()在(src,dst)的动态元组上运行for循环,测试特殊文件(如posix中的套接字或设备)。


Finally, if follow_symlinks is False, copyfile() tests if src is a symlink with os.path.islink(), which varies between nt.lstat() or posix.lstat() (os.lstat()) on Windows and Linux, or Carbon.File.ResolveAliasFile(s, 0)[2] on Mac.

If that test resolves True, the core code that copies a symlink/hardlink is:

最后,如果follow_symlinks为False,则copyfile()将测试src是否为os.path.islink()的符号链接,该符号链接在Windows和Linux上的nt.lsta()或posix.lstat()(os.lstat)之间变化,在Mac上的Carbon.File.RevolveAliasFile(s,0)[2]之间变化。如果该测试解析为True,则复制符号链接/硬链接的核心代码为:


        os.symlink(os.readlink(src), dst)

Hardlinks in posix are done with posix.link(), which shutil.copyfile() doesn't call, despite being callable through os.link().

(probably because the only way to check for hardlinks is to hashmap the os.lstat() (st_ino and st_dev specifically) of the first inode we know about, and assume that's the hardlink target)

posix中的硬链接是用posix.link()完成的,尽管shutil.copyfile()可以通过os.link(


Else, file copying is done via basic file buffers:

否则,文件复制是通过基本文件缓冲区完成的:


       with open(src, 'rb') as fsrc:
with open(dst, 'wb') as fdst:
copyfileobj(fsrc, fdst)

(similar to other answers here)

(与此处的其他答案类似)


copyfileobj() is a bit special in that it's buffer safe, using a length argument to read the file buffer in chunks:

copyfileobj()有点特别,因为它是缓冲区安全的,使用长度参数来读取文件缓冲区的块:


def copyfileobj(fsrc, fdst, length=16*1024):
"""copy data from file-like object fsrc to file-like object fdst"""
while 1:
buf = fsrc.read(length)
if not buf:
break
fdst.write(buf)

Hope this answer helps shed some light on the mystery of file copying using core mechanisms in python. :)

希望这个答案有助于揭示python中使用核心机制复制文件的奥秘。:)


Overall, shutil isn't too poorly written, especially after the second test in copyfile(), so it's not a horrible choice to use if you're lazy, but the initial tests will be a bit slow for a mass copy due to the minor bloat.

总的来说,shutil写得并不太差,尤其是在copyfile()中的第二次测试之后,所以如果你懒惰的话,使用它并不是一个可怕的选择,但由于小的膨胀,对于大规模复制来说,最初的测试会有点慢。


更多回答

In Python 3.8 this has received some significant speed boosts (~50% faster, depending on OS).

在Python 3.8中,这获得了一些显著的速度提升(大约快50%,具体取决于操作系统)。

does the destination folder need to exist?

目标文件夹需要存在吗?

@KansaiRobot: Yes, otherwise you get an exception: FileNotFoundError: Directory does not exist: foo/

@KansaiRobot:是的,否则你会得到一个异常:FileNotFoundError:目录不存在:foo/

It does not copy file metadata like the file owner's group on POSIX OSes (GNU/Linux, FreeBSD, ..).

它不会像POSIX操作系统(GNU/Linux、FreeBSD等)上的文件所有者组那样复制文件元数据。

Note that even the shutil.copy2() function cannot copy all file metadata.

请注意,即使是shutil.copy2()函数也无法复制所有文件元数据。

Thanks for many options you listed. IMHO, "os.popen('cp source.txt destination.txt') " (with its likes) is bad design. Python is a platform-independent language, and with code like this you destroy this great feature.

感谢您列出的许多选项。IMHO,“os.popen('cpsource.txt destination.txt')”(及其类似内容)是一个糟糕的设计。Python是一种独立于平台的语言,有了这样的代码,你就破坏了这个伟大的功能。

Only the first example answers the question. Running shell commands isn't portable and also isn't really performing actions.

只有第一个例子回答了这个问题。运行shell命令是不可移植的,也不是真正执行操作。

What does this add over jezrael answer from 2 years earlier?

这比两年前的耶斯拉回答又增加了什么?

@wim you have to compare my answer with jesrael's answer at the time I posted mine. So i added another column, used better column headers and less distracting table layout. I also added an example for the most common case. You are not the first one who asked this and I've answered this question several times already, but unfortunately, some moderator deleted the old comments here. After checking my old notes it even appears that you, wim, already had asked me this question in the past, and your question with my answer was deleted, too.

@你必须把我的答案和我发布我的答案时jesrael的答案进行比较。所以我添加了另一列,使用了更好的列标题和更少的表布局。我还为最常见的情况添加了一个示例。你不是第一个问这个问题的人,我已经回答了好几次了,但不幸的是,一些主持人删除了这里的旧评论。在查看了我的旧笔记后,你,维姆,似乎过去已经问过我这个问题,你的问题和我的答案也被删除了。

@wim I also added links into the Python documentation. The added column contains information about directory destinations, Jezrael's answer didn't include.

@wim我还在Python文档中添加了链接。添加的列包含有关目录目的地的信息,但Jezrael的回答没有包括这些信息。

Oh dear, that's funny that I already asked. Yes I agree that the doc links and extra column are improvements, however, it may have been better to edit them into other answer. Looks like some users subsequently did so, and now we have two answers which aren't significantly different apart from the formatting - recommend deletion?

哦,天哪,我已经问了,真有趣。是的,我同意文档链接和额外的列是改进,然而,将它们编辑成其他答案可能会更好。看起来有些用户随后这样做了,现在我们有两个答案,除了格式之外没有明显区别——建议删除?

not safe towards symlinks or hardlinks as it copies the linked file multiple times

对符号链接或硬链接不安全,因为它多次复制链接的文件

Why only small files?

为什么只有小文件?

@Kevin my mistake I should have written down the why when it was fresh. I'll have to review again and update this as I can't remember anymore ¯_(ツ)_/¯

@凯文我的错误我应该在它新鲜的时候写下原因。我必须再次复习并更新,因为我已经记不清了_(ツ)_/

@Kevin because this loads all the content in memory.

@Kevin,因为这会加载内存中的所有内容。

this is not portable, and unnecessary since you can just use shutil.

这是不可移植的,而且没有必要,因为您可以直接使用shutil。

Even when shutil is not available - subprocess.run() (without shell=True!) is the better alternative to os.system().

即使在shutil不可用的情况下,subprocess.run()(不带shell=True!)也是os.system()的更好选择。

shutil is more portable

shutil更便携

subprocess.run() as suggested by @maxschlepzig is a big step forward, when calling external programs. For flexibility and security however, use the ['cp', rawfile, 'rawdata.dat'] form of passing the command line. (However, for copying, shutil and friends are recommended over calling an external program.)

在调用外部程序时,@maxschlepzig建议的subprocess.run()是向前迈出的一大步。然而,为了灵活性和安全性,请使用['cp',rawfile,'rawdata.dat']形式传递命令行。(但是,对于复制,建议shutil和朋友不要调用外部程序。)

try that with filenames with spaces in it.

尝试使用带有空格的文件名。

It ought to link to documentation (but not naked links).

它应该链接到文档(但不是裸链接)。

Why do we need a new answer?

为什么我们需要一个新的答案?

@PeterMortensen, added links. The answer would add value as other answers are either too broad or either too straight, this answer contains the helpful information that can be used easiy.

@PeterMortensen,添加了链接。这个答案会增加价值,因为其他答案要么过于宽泛,要么过于直白,这个答案包含了可以轻松使用的有用信息。

I think you may be confused? The python docs for os.system note: "The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; using that module is preferable to using this function." You note that there are potential security issues with subprocess. However, that is only true if shell=True (shell=False is default), plus those same sec issues exist when using os.system (unsanitised user input). Rather than your os.system example, this is preferable: subprocess.run([''cp', dst, src]).

我想你可能很困惑?os.system的python文档指出:“子流程模块为生成新流程和检索其结果提供了更强大的功能;使用该模块比使用此功能更可取。”您注意到,子流程存在潜在的安全问题。然而,只有当shell=true(shell=False是默认值),并且在使用os.system(未初始化的用户输入)时存在相同的sec问题时,情况才是真的。与其使用os.system示例,不如使用subprocess.run([''cp',dst,src])。

All answers need explanation, even if it is one sentence. No explanation sets bad precedent and is not helpful in understanding the program. What if a complete Python noob came along and saw this, wanted to use it, but couldn't because they don't understand it? You want to be helpful to all in your answers.

所有的答案都需要解释,即使是一句话。任何解释都不会开创坏的先例,也无助于理解程序。如果一个完整的Python noob看到了这一点,想使用它,但因为不理解而无法使用,该怎么办?你想在你的回答中对所有人都有所帮助。

Isn't that missing the .close() on all of those open(...)s?

这不是所有打开的(…)都缺少.close()吗?

No need of .close(), as we are NOT STORING the file pointer object anywhere(neither for the src file nor for the destination file).

不需要.close(),因为我们不会将文件指针对象存储在任何位置(无论是src文件还是目标文件)。

AFAIK, it is undefined when the files are actually closed, @SundeepBorra. Using with (as in the example above) is recommended and not more complicated. Using read() on a raw file reads the entire file into memory, which may be too big. Use a standard function like from shutil so that you and whoever else is involved in the code does not need to worry about special cases. docs.python.org/3/library/io.html#io.BufferedReader

AFAIK,当文件实际关闭时,它是未定义的,@SundeepBorra。建议使用with(如上面的示例中所示),而不是更复杂。对原始文件使用read()将整个文件读入内存,内存可能太大。使用一个标准函数,比如from shutil,这样你和代码中的其他人就不需要担心特殊情况。docs.python.org/3/library/io.html#io.BufferdReader

Same suboptimal memory-wasting approach as yellow01's answer.

与yellow01的答案相同的次优内存浪费方法。

This depends on the platform, so i would not use is.

这取决于平台,所以我不会使用is。

Such a call is unsecure. Please refere to the subproces docu about it.

这样的呼吁是不安全的。请参阅子流程文档。

this is not portable, and unnecessary since you can just use shutil.

这是不可移植的,而且没有必要,因为您可以直接使用shutil。

Hmm why Python, then?

嗯,为什么是Python?

Maybe detect the operating system before starting (whether it's DOS or Unix, because those are the two most used)

也许在启动之前检测一下操作系统(无论是DOS还是Unix,因为这是最常用的两种)

this seems a little redundant since the writer should handle buffering. for l in open('file.txt','r'): output.write(l) should work find; just setup the output stream buffer to your needs. or you can go by the bytes by looping over a try with output.write(read(n)); output.flush() where n is the number of bytes you'd like to write at a time. both of these also don't have an condition to check which is a bonus.

这似乎有点多余,因为编写器应该处理缓冲。对于open中的l('file.txt','r'):output.write(l)应该可以查找;只需根据您的需要设置输出流缓冲区。或者,您可以通过在带有output.write(read(n))的try上循环来遍历字节;output.flush(),其中n是一次要写入的字节数。这两者都没有一个条件来检查哪一个是奖金。

Yes, but I thought that maybe this could be easier to understand because it copies entire lines rather than parts of them (in case we don't know how many bytes each line is).

是的,但我认为这可能更容易理解,因为它复制整行而不是部分行(以防我们不知道每行有多少字节)。

@owns To add to this question a year later, writelines() has shown slightly better performance over write() since we don't waste time consistently opening a new filestream, and instead write new lines as one large bytefeed.

@一年后,writelines()显示出比write()稍好的性能,因为我们没有浪费时间持续打开新的文件流,而是将新行作为一个大型字节源写入。

looking at the source - writelines calls write, hg.python.org/cpython/file/c6880edaf6f3/Modules/_io/bytesio.c. Also, the file stream is already open, so write wouldn't need to reopen it every time.

查看源代码-writelines调用write,hg.python.org/cpython/file/c6880edaf6f3/Modules/io/bytesio.c。此外,文件流已经打开,因此write不需要每次都重新打开它。

This is awful. It does unnecessary work for no good reason. It doesn't work for arbitrary files. The copy isn't byte-identical if the input has unusual line endings on systems like Windows. Why do you think that this might be easier to understand than a call to a copy function in shutil? Even when ignoring shutil, a simple block read/write loop (using unbuffered IO) is straight forward, would be efficient and would make much more sense than this, and thus is surely easier to teach and understand.

这太可怕了。它毫无理由地做不必要的工作。它不适用于任意文件。如果在像Windows这样的系统上输入有不寻常的行结尾,则副本的字节数就不相同。为什么你认为这可能比在shutil中调用复制函数更容易理解?即使忽略shutil,一个简单的块读/写循环(使用无缓冲IO)也是直接的,会很有效,而且比这更有意义,因此肯定更容易教授和理解。

if show importing of os, you should import shutil as well

如果显示导入操作系统,您也应该导入shutil

in Linux, this is not safe towards symlinks or hardlinks, the linked file is rewritten multiple times

在Linux中,这对于符号链接或硬链接来说是不安全的,链接的文件会被多次重写

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com