0
点赞
收藏
分享

微信扫一扫

day31 第八章 贪心算法 part01● 理论基础 ● 455.分发饼干 ● 376. 摆动序列 ● 53. 最大子序和

树下的老石头 03-18 18:00 阅读 2

Core.Files 模块

Django 的核心模块之一,封装文件操作,提供对文件的上传、下载、删除、查看大小等功能。

提供的功能

  1. 存储后端解耦,支持多种存储后端,使得在不同存储后端中的文件数据都能以相同的方式操作
  2. 文件上传、下载、删除、查看大小等功能

支持的文件存储后端

  • FileSystemStorage:基于本地文件系统的存储后端,适用于开发环境和小型项目。
  • MemoryStorage:基于内存的存储后端,适用于开发环境,小型项目,处理一些临时文件。
第三方存储后端库
  • django-storages:支持 S3, LibCloud, Azure, DigitalOcean, Google Cloud Storage, Backblaze B2, SFTP, FTP, Dropbox, Oracle Cloud 等云存储服务。
  • django-oss-storage: 支持阿里云 OSS 对象存储服务, 可能已经失效但仍可以 fork 修改。
  • django-qiniu-storage: 支持七牛云对象存储服务, 可能已经失效但仍可以 fork 修改。

支持的文件类型

  • File:普通文件,可以是任何类型的文件,如图片、视频、文档等。
  • ImageFile:图片文件,继承自 File,提供图片处理的功能,也没什么功能就多了,height,width 两个方法,需要安装 Pillow 库。
  • UploadedFile: 抽象类,提供文件上传的基本功能,主要是满足 form-data 上传的文件。
  • TemporaryUploadedFile(继承自 UploadedFile): 存放在临时文件中
  • InMemoryUploadedFile(继承自 UploadedFile): 存储在内存中

可以学习的地方

  1. 自定义文件存储后端
class Storage:
    # 文件存储后端无关的接口,可以提供默认实现
    def open(self, name, mode="rb"): ...

    def save(self, name, content, max_length=None): ...

    def get_valid_name(self, name): ...

    def get_alternative_name(self, file_root, file_ext): ...

    def get_available_name(self, name, max_length=None): ...

    def generate_filename(self, filename): ...

    def path(self, name): ...

    # 与文件存储后端相关的接口,需要子类实现
    def _open(self, name, mode="rb"):
        raise NotImplementedError(
            "subclasses of Storage must provide an _open() method"
        )

    def delete(self, name):
        """
        Delete the specified file from the storage system.
        """
        raise NotImplementedError(
            "subclasses of Storage must provide a delete() method"
        )

    def exists(self, name):
        """
        Return True if a file referenced by the given name already exists in the
        storage system, or False if the name is available for a new file.
        """
        raise NotImplementedError(
            "subclasses of Storage must provide an exists() method"
        )

    def listdir(self, path):
        """
        List the contents of the specified path. Return a 2-tuple of lists:
        the first item being directories, the second item being files.
        """
        raise NotImplementedError(
            "subclasses of Storage must provide a listdir() method"
        )

    def size(self, name):
        """
        Return the total size, in bytes, of the file specified by name.
        """
        raise NotImplementedError("subclasses of Storage must provide a size() method")

    def url(self, name):
        """
        Return an absolute URL where the file's contents can be accessed
        directly by a web browser.
        """
        raise NotImplementedError("subclasses of Storage must provide a url() method")

    def get_accessed_time(self, name):
        """
        Return the last accessed time (as a datetime) of the file specified by
        name. The datetime will be timezone-aware if USE_TZ=True.
        """
        raise NotImplementedError(
            "subclasses of Storage must provide a get_accessed_time() method"
        )

    def get_created_time(self, name):
        """
        Return the creation time (as a datetime) of the file specified by name.
        The datetime will be timezone-aware if USE_TZ=True.
        """
        raise NotImplementedError(
            "subclasses of Storage must provide a get_created_time() method"
        )

    def get_modified_time(self, name):
        """
        Return the last modified time (as a datetime) of the file specified by
        name. The datetime will be timezone-aware if USE_TZ=True.
        """
        raise NotImplementedError(
            "subclasses of Storage must provide a get_modified_time() method"
        )

  1. 文件读写锁

def _fd(f):
    """Get a filedescriptor from something which could be a file or an fd."""
    return f.fileno() if hasattr(f, "fileno") else f


if os.name == "nt":
    import msvcrt
    from ctypes import (
        POINTER,
        Structure,
        Union,
        WinDLL,
        byref,
        c_int64,
        c_ulong,
        c_void_p,
        sizeof,
    )
    from ctypes.wintypes import BOOL, DWORD, HANDLE

    LOCK_SH = 0  # the default
    LOCK_NB = 0x1  # LOCKFILE_FAIL_IMMEDIATELY
    LOCK_EX = 0x2  # LOCKFILE_EXCLUSIVE_LOCK

    # --- Adapted from the pyserial project ---
    # detect size of ULONG_PTR
    if sizeof(c_ulong) != sizeof(c_void_p):
        ULONG_PTR = c_int64
    else:
        ULONG_PTR = c_ulong
    PVOID = c_void_p

    # --- Union inside Structure by stackoverflow:3480240 ---
    class _OFFSET(Structure):
        _fields_ = [("Offset", DWORD), ("OffsetHigh", DWORD)]

    class _OFFSET_UNION(Union):
        _anonymous_ = ["_offset"]
        _fields_ = [("_offset", _OFFSET), ("Pointer", PVOID)]

    class OVERLAPPED(Structure):
        _anonymous_ = ["_offset_union"]
        _fields_ = [
            ("Internal", ULONG_PTR),
            ("InternalHigh", ULONG_PTR),
            ("_offset_union", _OFFSET_UNION),
            ("hEvent", HANDLE),
        ]

    LPOVERLAPPED = POINTER(OVERLAPPED)

    # --- Define function prototypes for extra safety ---
    kernel32 = WinDLL("kernel32")
    LockFileEx = kernel32.LockFileEx
    LockFileEx.restype = BOOL
    LockFileEx.argtypes = [HANDLE, DWORD, DWORD, DWORD, DWORD, LPOVERLAPPED]
    UnlockFileEx = kernel32.UnlockFileEx
    UnlockFileEx.restype = BOOL
    UnlockFileEx.argtypes = [HANDLE, DWORD, DWORD, DWORD, LPOVERLAPPED]

    def lock(f, flags):
        hfile = msvcrt.get_osfhandle(_fd(f))
        overlapped = OVERLAPPED()
        ret = LockFileEx(hfile, flags, 0, 0, 0xFFFF0000, byref(overlapped))
        return bool(ret)

    def unlock(f):
        hfile = msvcrt.get_osfhandle(_fd(f))
        overlapped = OVERLAPPED()
        ret = UnlockFileEx(hfile, 0, 0, 0xFFFF0000, byref(overlapped))
        return bool(ret)

else:
    try:
        import fcntl

        LOCK_SH = fcntl.LOCK_SH  # shared lock
        LOCK_NB = fcntl.LOCK_NB  # non-blocking
        LOCK_EX = fcntl.LOCK_EX
    except (ImportError, AttributeError):
        # File locking is not supported.
        LOCK_EX = LOCK_SH = LOCK_NB = 0

        # Dummy functions that don't do anything.
        def lock(f, flags):
            # File is not locked
            return False

        def unlock(f):
            # File is unlocked
            return True

    else:

        def lock(f, flags):
            try:
                fcntl.flock(_fd(f), flags)
                return True
            except BlockingIOError:
                return False

        def unlock(f):
            fcntl.flock(_fd(f), fcntl.LOCK_UN)
            return True

总结

对于 web 服务端开发,文件操作是日常。但是文件的用途有很多,处置方式也很多。例如不同的文件类型放置在不同的存储后端,以及文件的访问控制、时效性也可以通过拓展存储后端来实现。
利用 django 这种分离文件操作和存储后端的框架,在开发中可以很好的解决大部分文件类需求。

举报

相关推荐

贪心算法。力扣:53. 最大子序和

0 条评论