Исходный код для django.core.files.base
импорт ОС
от ИО импорта BytesIO , StringIO , UnsupportedOperation
из django.core.files.utils импортировать FileProxyMixin
из django.utils.functional import cached_property
[документы] Файл класса ( FileProxyMixin ): DEFAULT_CHUNK_SIZE = 64 * 2 ** 10
def __init__ ( self , file , name = None ):
self . file = file,
если name - None :
name = getattr ( file , 'name' , None )
self . name = name,
если hasattr ( файл , 'режим' ):
self . режим = файл . Режим
def __str__ ( self ):
вернуть себя . имя или ''
def __repr__ ( self ):
return "< % s : % s >" % ( self . __class__ . __name__ , self или "None" )
Защиту __bool__ ( самостоятельно ):
возврат BOOL ( само . имя )
def __len__ ( self ):
вернуть себя . размер
@cached_property
def size ( self ):
if hasattr ( self . file , 'size' ):
вернуть self . файл . size
if hasattr ( self . file , 'name' ):
try :
return os . путь . GETSIZE ( самостоятельно . файл . имя ) , за
исключением ( OSError , TypeError ):
пропуск
если hasattr ( self . file , 'tell' ) и hasattr ( self . file , 'seek' ):
pos = self . файл . tell ()
self . файл . seek ( 0 , os . SEEK_END )
size = self . файл . tell ()
self . файл . искать ( поз. )
return size
raise AttributeError ( «Невозможно определить размер файла.» )
[docs] def chunks ( self , chunk_size = None ):
"" "
Прочитать файл и получить куски размером chunk_size (по умолчанию
File.DEFAULT_CHUNK_SIZE).
" ""
chunk_size = chunk_size или self . DEFAULT_CHUNK_SIZE
попробовать :
самостоятельно . seek ( 0 )
except ( AttributeError , UnsupportedOperation ):
пройти
в то время как True :
data = self . Считанные ( chunk_size )
если не данные :
разрыв
выход данных
[docs] def multiple_chunks ( self , chunk_size = None ):
"" "
Верните" True ", если вы можете ожидать несколько фрагментов.
NB: если конкретное представление файла находится в памяти, подклассы
всегда
должны возвращать `` False '' - нет веских причин для чтения из памяти по частям.
""»
Возвращение самостоятельно . Размер > ( chunk_size или самостоятельно . DEFAULT_CHUNK_SIZE )
[docs] def __iter__ ( self ):
# Обойти этот файловый объект по новой
строке buffer_ = None
для фрагмента в self . chunks ():
для строки в куске . splitlines ( True ):
if buffer_ :
if endswith_cr ( buffer_ ) and not equals_lf ( line ):
# Строка разделяется после новой строки \ r; yield buffer_.
yield buffer_
# Продолжить строку.
else :
# Строка либо разделяется без новой строки (строка
# продолжается после buffer_), либо с \ r \ n
# новой строкой (line == b '\ n').
line = buffer_ + line
# buffer_ handled, очистить.
buffer_ = Нет
# Если это конец строки \ n или \ r \ n, yield.
if endwith_lf ( line ):
yield line
else :
buffer_ = line
если buffer_ это не Отсутствует :
Выход buffer_
def __enter__ ( self ):
вернуть себя
def __exit__ ( self , exc_type , exc_value , tb ):
self . закрыть ()
[документы] def open ( self , mode = None ):
если не self . закрыто :
сам . seek ( 0 )
elif self . имя и ОС . путь . существует ( сам . имя ):
сам . Файл = открытый ( сам . имя , режим или самостоятельный . режим )
еще:
raise ValueError ( "Файл не может быть открыт повторно." )
return self
[документы] def close ( self ):
self . файл . закрыть ()
[docs] class ContentFile ( File ):
"" "
Файловый объект, который принимает только необработанное содержимое, а не сам файл.
" ""
def __init__ ( self , content , name = None ):
stream_class = StringIO if isinstance ( content , str ) else BytesIO
super () . __init__ ( stream_class ( контент ), name = name )
я . size = len ( содержимое )
def __str__ ( self ):
вернуть 'Raw content'
def __bool__ ( self ):
вернуть True
def open ( self , mode = None ):
self . seek ( 0 )
вернуть себя
def close ( self ):
пройти
def write ( self , data ):
self . __dict__ . pop ( 'size' , None ) # Очистить вычисленный размер.
вернуть себя . файл . запись ( данные )
Защиту endswith_cr ( строка ):
«» «Возвращение Истина , если строка (текст или байтовой строки) концы с„\ г“.» «»
Возвращение строки . заканчивается с ( ' \ r ' if isinstance ( line , str ) else b ' \ r ' )
Защиту endswith_lf ( строка ):
«» «Возвращение Истина , если строка (текст или байтовой строки) концы с„\ п“.» «»
Возвращение строки . заканчивается с ( ' \ n ' если isinstance ( line , str ) else b ' \ n ' )
def equals_lf ( line ):
"" "Вернуть True, если строка (текст или строка байтов) равна '\ n'." ""
return line == ( ' \ n ' if isinstance ( line , str ) else b ' \ n ' )