Чтобы расширить мой комментарий: вы не хотите читать файл в память сразу, а обрабатывать его небольшими блоками.
С любым производственным шифром (, который XOR определенно не является ), вам также придется иметь дело с заполнением выходного файла, если исходные данные не кратны размеру блока шифра. Этот скрипт не имеет с этим дело, отсюда и утверждение о размере блока.
Кроме того, мы больше необратимо (ну, кроме того факта, что шифр XOR фактически является обратимым), перезаписывая файлы их зашифрованными версиями. (Если вы хотите сделать это, лучше добавить код для удаления оригинала, а затем переименовать зашифрованный файл на его место. Таким образом, вы не получите полузаписанный, полушифрованный файл. )
Также я убрал бесполезную кодировку Base64.
Но - не используйте этот код для чего-либо серьезного. Пожалуйста, не надо. Друзья не друзья раскручивают свои собственные крипто.
from Crypto.Cipher import XOR
import os
def encrypt_file(cipher, source_file, dest_file):
# this toy script is unable to deal with padding issues,
# so we must have a cipher that doesn't require it:
assert cipher.block_size == 1
while True:
src_data = source_file.read(1048576) # 1 megabyte at a time
if not src_data: # ran out of data?
break
encrypted_data = cipher.encrypt(src_data)
dest_file.write(encrypted_data)
def insecurely_encrypt_directory(enpath, key):
for filename in os.listdir(enpath):
file_path = os.path.join(enpath, filename)
dest_path = file_path + ".encrypted"
with open(file_path, "rb") as source_file, open(dest_path, "wb") as dest_file:
cipher = XOR.new(key)
encrypt_file(cipher, source_file, dest_file)
В первую очередь, попытайтесь не злоупотребить контейнер МОК. Его великое для "обеспечения электричеством" контроллеров, представлений и услуг, но объектов, которые должны быть созданы во время времени выполнения, должно быть создано объектами фабрики а не контейнером. Иначе Вы получаете Контейнер. Твердость звонит на всем протяжении Вашего кода, связывая его с Вашим контейнером. Эти дополнительные зависимости побеждают цель использовать МОК. В большинстве случаев я могу продвинуться, только разрешив одну или две зависимости на верхнем уровне моего приложения. Контейнер МОК затем рекурсивно разрешит большинство зависимостей.
Когда мне нужен контейнер в другом месте в моей программе, вот прием, который я часто использую.
public class Container : IContainer
{
readonly IWindsorContainer container;
public Container()
{
// Initialize container
container = new WindsorContainer(new XmlInterpreter(new FileResource("castle.xml")));
// Register yourself
container.Kernel.AddComponentInstance<IContainer>(this);
}
public T Resolve<T>()
{
return container.Resolve<T>();
}
}
Я переношу контейнер в Контейнерный класс как это. Это добавляет себя к перенесенному контейнеру в конструкторе. Теперь классам, которым нужен контейнер, можно было ввести IContainer. (пример для замка Windsor, но он может, вероятно, быть адаптирован к AutoFac),
Обычный способ сделать это состоит в том, чтобы сохранить контейнер в статической переменной в Вашем Глобальном классе приложения.
"Способ" Autofac - иметь параметр конструктора IContext
. Autofac внедрит объект, который можно использовать для определения типов.
Контекст обычно является скрытым контейнером, IContainer
реализует интерфейс IContext
, хотя IContext
ограничен только выполнением разрешений.
I знаю, что контейнер не должен быть «чрезмерным», но у меня как OP есть классы, требующие разрешения типов, которые не известны заранее (и, следовательно, не могут использоваться в качестве параметров конструктора). В этих случаях я считаю полезным рассматривать контейнер как еще одну службу, которую можно использовать для разрешения других служб, и внедрять ее, как любую другую службу.
Ответ Питера Лиллевольда, приведенный выше, правильный - вы можете получить доступ к контейнеру из любого компонента, взяв зависимость от интерфейса IContext.
Если вам действительно действительно нужен ссылку на контейнер, см. Autofac.Integration.Web.IContainerProviderAccessor.
Having IOC container globally available is not a best practice. Even passing container is not encouraged.
If dependency injection can not be used (you need to create\request objects after component has been created) then you can: