Какие коды ошибок могут произойти с CopyFileEx?

, Если Ваш компьютер, ОС и Python 64-разрядные , то можно использовать mmap модуль , чтобы отобразить содержание файла в память и получить доступ к нему с индексами и частями. Здесь пример из документации:

import mmap
with open("hello.txt", "r+") as f:
    # memory-map the file, size 0 means whole file
    map = mmap.mmap(f.fileno(), 0)
    # read content via standard file methods
    print map.readline()  # prints "Hello Python!"
    # read content via slice notation
    print map[:5]  # prints "Hello"
    # update content using slice notation;
    # note that new content must have same size
    map[6:] = " world!\n"
    # ... and read again using standard file methods
    map.seek(0)
    print map.readline()  # prints "Hello  world!"
    # close the map
    map.close()

, Если или Ваш компьютер, ОС или Python 32-разрядные , то mmap-луг большие файлы может зарезервировать значительные части Вашего адресного пространства и , исчерпали ресурсы Ваша программа памяти.

7
задан Rob Kennedy 4 September 2009 в 14:57
поделиться

2 ответа

Microsoft не предоставляет список всех кодов ошибок, которые может возвращать API, по той простой причине, что список может меняться со временем и различными реализациями Windows, установленными драйверами или простым контролем (часто API-интерфейсы возвращать ошибки, вызванные другими API, вызванными в том, который вы вызвали).

Иногда в документации указываются конкретные ошибки, которые представляют особый интерес для пользователей этого API, но в целом они не содержат окончательного полного списка ошибок. И они не должны, что прискорбно, но это факт жизни.

Я сочувствую вашему положению - много раз мне хотелось получить такую ​​информацию, чтобы я мог лучше понять, как решать проблемы, которые должны можно ожидать - особенно тех, у которых есть разумный путь восстановления. Обычно я пытаюсь справиться с этим путем тестирования, чтобы найти отказ API-интерфейсов, и я бы хотел избежать этого, потому что это больно и мало помогает в обеспечении того, чтобы я рассмотрел все сценарии или на будущее.

Однако охват всех сценариев (с исчерпывающим списком кодов ошибок) или защита от будущих изменений - действительно невыполнимая цель. Подумайте, как Microsoft могла бы управлять документированием всех возможных кодов ошибок в Win32:

Скажем, Win32 API имеет только 2 функции: foo () и bar () . foo () может генерировать собственную ошибку, ERROR_FOO и bar () могут генерировать собственную ошибку, ERROR_BAR . Однако foo () вызывает bar () , поэтому foo () может также вернуть ERROR_BAR , если его вызов bar () возвращает эту ошибку.

В документации отражено следующее:

  • foo () может вернуть либо ERROR_FOO , либо ERROR_BAR
  • bar () может вернуть ERROR_BAR

Теперь, когда API v2 выпущен, bar () был расширен, чтобы также возвращать ERROR_BAZ . для чего-то размером с этот API легко управлять тем, что необходимо обновить документацию для bar (), чтобы добавить новый код ошибки (однако обратите внимание, что для API такого размера, как реальный Win32, и для организации размером с MS, то же самое может быть неверным, но давайте предположим, что это так).

Однако парень, добавляющий новую ошибку в bar () , не имеет прямого представления о том, что foo () ' поведение s также изменилось с точки зрения того, какие ошибки оно может возвращать. В таком маленьком API это, вероятно, не имеет большого значения - в чем-то вроде Win32 это будет беспорядок. Теперь добавьте тот факт, что Win32 может зависеть от стороннего кода (драйверов, плагинов, COM-объектов и т. Д.), И задача теперь практически невыполнима.

На самом деле это не обязательно отличный пример, поскольку если ошибка коды были частью контракта API ERROR_BAZ никогда не должны были появляться.

Итак, вот другой сценарий: API имеет функцию OpenObject () , которая может возвращать ERROR_NO_MEMORY или ERROR_NOT_FOUND . Когда эта система была впервые разработана, в ней не было концепции безопасности (скажем, как MS-DOS), но в новой версии добавлены элементы управления доступом. Теперь мы' Мне нравится OpenObject () , чтобы иметь возможность возвращать ERROR_ACCESS_DENIED , но он не может, потому что это изменит контракт, поэтому новый API OpenObjectEx () добавлен, чтобы справиться с этой ситуацией. Здесь есть как минимум две проблемы:

  • Со временем вы получите взрывное развитие API, которые действительно мало или совсем не добавят ценности по сравнению со старыми API
  • , что должно произойти с устаревшим приложением, которое вызывает старый OpenObject () API и не работает из-за ограничений доступа? Ни один из возвращенных сообщений об ошибке не может сказать правду о том, в чем проблема.

Эта проблема является одной из причин того, что спецификации исключений (в C ++ или Java), по мнению многих, были плохой идеей.

поэтому добавлен новый API OpenObjectEx () , чтобы справиться с этой ситуацией. Здесь есть как минимум две проблемы:

  • Со временем вы получите взрывное развитие API, которые действительно мало или совсем не добавят ценности по сравнению со старыми API
  • , что должно произойти с устаревшим приложением, которое вызывает старый OpenObject () API и не работает из-за ограничений доступа? Ни один из возвращенных сообщений об ошибке не может сказать правду о том, в чем проблема.

Эта проблема является одной из причин того, что спецификации исключений (в C ++ или Java), по мнению многих, были плохой идеей.

поэтому добавлен новый API OpenObjectEx () , чтобы справиться с этой ситуацией. Здесь есть как минимум две проблемы:

  • Со временем вы получите взрывное развитие API, которые действительно мало или совсем не добавят ценности по сравнению со старыми API
  • , что должно произойти с устаревшим приложением, которое вызывает старый OpenObject () API и не работает из-за ограничений доступа? Ни один из возвращенных сообщений об ошибке не может сказать правду о том, в чем проблема.

Эта проблема является одной из причин того, что спецификации исключений (в C ++ или Java), по мнению многих, были плохой идеей.

со временем получу взрывной рост API-интерфейсов, которые действительно мало или вообще не добавляют ценности по сравнению со старыми API
  • . Что должно произойти с устаревшим приложением, которое вызывает старый OpenObject () API и не работает из-за ограничений доступа? Ни один из возвращенных сообщений об ошибке не может сказать правду о том, в чем проблема.
  • Эта проблема является одной из причин того, что спецификации исключений (в C ++ или Java), по мнению многих, были плохой идеей.

    со временем получу взрывной рост API-интерфейсов, которые действительно мало или вообще не добавляют ценности по сравнению со старыми API
  • . Что должно произойти с устаревшим приложением, которое вызывает старый OpenObject () API и не работает из-за ограничений доступа? Ни один из возвращенных сообщений об ошибке не говорит правду о проблеме.
  • Эта проблема является одной из причин того, что спецификации исключений (в C ++ или Java) считаются многими плохой идеей.

    6
    ответ дан 7 December 2019 в 01:23
    поделиться

    Здесь есть список кодов ошибок Windows , но он не указывает коды ошибок для каждого вызова API. Тем не менее, сайт MSDN предоставляет много полезной информации о большинстве методов API, включая возможные коды ошибок, которые они могут вернуть.

    Функция FormatMessage может использоваться для преобразования ошибки в правильное сообщение об ошибке. с учетом текущего языка Windows. Часто отображения такого сообщения об ошибке должно быть достаточно. Вам нужно только добавить логику для ошибок, которых вы можете ожидать, и даже тогда вы просто захотите показать сообщение об ошибке.

    Читая о CopyFileEx , вы прочтете следующее, помимо части о получении вызова GetLastError ():

    Замечания

    Эта функция не работает с ERROR_ACCESS_DENIED, если целевой файл уже существует и имеет установленный атрибут FILE_ATTRIBUTE_HIDDEN или FILE_ATTRIBUTE_READONLY.

    Когда зашифрованные файлы копируются с помощью CopyFileEx, функция пытается зашифровать целевой файл с помощью используемых ключей в шифровании исходного файла. Если это невозможно сделать, эта функция пытается зашифровать целевой файл ключами по умолчанию. Если оба этих метода не могут быть выполнены, CopyFileEx завершается с ошибкой с кодом ERROR_ENCRYPTION_FAILED. Если вы хотите, чтобы CopyFileEx завершил операцию копирования, даже если целевой файл не может быть зашифрован, включите COPY_FILE_ALLOW_DECRYPTED_DESTINATION в качестве значения параметра dwCopyFlags при вызове CopyFileEx.

    По сути, это ошибки, которые вы обычно могли ожидать.

    3
    ответ дан 7 December 2019 в 01:23
    поделиться
    Другие вопросы по тегам:

    Похожие вопросы: