Module (44%)
Section (78%)

Копирование файлов - простой и функциональный инструмент

Теперь Вы собираетесь объединить все эти новые знания, добавить в него некоторые свежие элементы и использовать его для написания реального кода, способного фактически копировать содержимое файла.

Конечно, цель состоит не в том, чтобы сделать лучшую замену таким командам, как copy (MS Windows) или cp (Unix/Linux), а в том, чтобы найти один из возможных путей создания рабочего инструмента, даже если никто не хочет его использовать.

Посмотрите на код в редакторе. Давайте проанализируем его:

  • строки с 3 по 8: спросить у пользователя имя файла для копирования и попробовать открыть его для чтения; прекратить выполнение программы, если открытие не удалось; примечание: используйте функцию exit(), чтобы остановить выполнение программы и передать код завершения в ОС; любой код завершения, кроме 0, говорит о том, что в программе возникли некоторые проблемы; используйте значение errno, чтобы указать природу проблемы;
  • строки с 10 по 16: повторить то же самое действие, но на этот раз для выходного файла;
  • строка 18: подготовить фрагмент памяти для передачи данных из исходного файла в целевой; такая область передачи часто называется буфером, отсюда и название переменной; размер буфера произвольный - в этом случае мы решили использовать 64 килобайта; технически, больший буфер быстрее копирует элементы, так как больший буфер означает меньше операций ввода-вывода; на самом деле, всегда есть предел, пересечение которого не дает дальнейших улучшений; проверьте сами, если хотите.
  • строка 19: считать скопированные байты - это счетчик и его начальное значение;
  • строка 21: попытаться заполнить буфер в первый раз;
  • строка 22: пока Вы получаете ненулевое число байтов, повторяйте те же действия;
  • строка 23: записать содержимое буфера в выходной файл (примечание: мы использовали фрагмент, чтобы ограничить количество записываемых байтов, так как write() всегда предпочитает записывать весь буфер);
  • строка 24: обновить счетчик;
  • строка 25: считать следующий фрагмент файла;
  • строки с 30 по 32: некоторая окончательная очистка - работа выполнена.


Code

from os import strerror

source_file_name = input("Enter the source file name: ")
try:
source_file = open(source_file_name, 'rb')
except IOError as e:
print("Cannot open the source file: ", strerror(e.errno))
exit(e.errno)

destination_file_name = input("Enter the destination file name: ")
try:
destination_file = open(destination_file_name, 'wb')
except Exception as e:
print("Cannot create the destination file: ", strerror(e.errno))
source_file.close()
exit(e.errno)

buffer = bytearray(65536)
total = 0
try:
readin = source_file.readinto(buffer)
while readin > 0:
written = destination_file.write(buffer[:readin])
total += written
readin = source_file.readinto(buffer)
except IOError as e:
print("Cannot create the destination file: ", strerror(e.errno))
exit(e.errno)

print(total,'byte(s) succesfully written')
source_file.close()
destination_file.close()
{{ dockerServerErrorMsg }} ×
{{ errorMsg }} ×
{{ successMsg }} ×