Python 如何用Python将手机内的文件(照片)批量导入电脑,并增加文件创建日期

Python 如何用Python将手机内的文件(照片)批量导入电脑,并增加文件创建日期



前言

随着手机内照片数量越来越多,手机内存储空间不够,就需要将手机内的照片或文件拷贝到电脑上,这种有很多第三方软件可以实现,但是又不想使用第三方软件,于是就试着用python实现文件或照片备份的目的,这里记录下如何实现批量拷贝手机内的文件到电脑上,给有需要的朋友提供思路。


一、拷贝文件的探索

最先想到的就是通过os库遍历文件后,用shutil库进行文件的拷贝,等到真正实现的时候发现,手机连接到电脑上后能看到手机文件夹的路径,用鼠标也能操作复制,但是如果想用os库遍历文件时会发现无法找到路径或路径不存在,根本没法遍历,所以也就没法复制,也试了其他很多库都是无法找到路径,最后只能用其他办法实现 。

二、shell接口

最后通过查找资料,发现shell接口可以实现此功能,这里记录下基本的操作

1.通过shell获取需要复制的文件夹对象,以下为具体代码,原理是通过遍历文件夹,通过比对找到所需复制的文件夹对象,path为需要复制的手机文件夹路径,如:path=r’此电脑\Apple iPhone\Internal Storage\DCIM’

def get_folder(path,folder=None):
    folder_name = path.split("\\", 1)
    base_folder = folder or shell.SHGetDesktopFolder()
    for pidl in base_folder:        
        if base_folder.GetDisplayNameOf(pidl, shellcon.SHGDN_NORMAL) == folder_name[0]:
            folder = base_folder.BindToObject(pidl, None, shell.IID_IShellFolder)
            break
    if len(folder_name) > 1:
        return get_folder(folder_name[1],folder)
    else:
        return folder

2.遍历此文件夹下的所有文件和文件夹,然后拷贝到电脑上即可,同时可读取文件创建日期,方便后面将文件创建日期增加到文件名上,查看文件创建日期,因为照片拷贝到电脑后创建日期将会被修改,后期想查看创建日期就看不到原始日期了,所以可以将此日期增加的文件名上,也可以将文件创建日期进行修改,但个人觉得没有修改文件名直观,以下为具体代码

def copy_files_to_computer(folder,phonefolderpath,computerdir,current_computer_dir=None,date_name=True):

    if folder:
        is_pfo=True
        # 遍历文件
        for file_pidl in folder:
            # 获取文件名
            file_name = folder.GetDisplayNameOf(file_pidl, shellcon.SHGDN_FORADDRESSBAR)
            # 判断是否为文件夹
            is_folder=folder.GetAttributesOf([file_pidl],shellcon.SFGAO_FOLDER)
            if is_folder==536870912:
                #生成电脑文件夹路径,将手机路径替换为电脑路径
                new_computerdir=file_name.replace(phonefolderpath,computerdir)
                # 如果电脑不存在文件夹则新建文件夹
                if not os.path.exists(new_computerdir):
                    os.makedirs(new_computerdir)
                new_folder = folder.BindToObject(file_pidl, None, shell.IID_IShellFolder)
                copy_files_to_computer(new_folder,phonefolderpath,computerdir,new_computerdir)
            # 如果是文件,则进行拷贝
            elif is_folder==0:

                if current_computer_dir is not None:
                    computerdirpidl,_=shell.SHILCreateFromPath(current_computer_dir, 0)
                else:
                    computerdirpidl,_=shell.SHILCreateFromPath(computerdir, 0)

                computerdiritem = shell.SHCreateItemFromIDList(computerdirpidl)
                phonefolderpidl = shell.SHGetIDListFromObject(folder)
                # 生成当前复制的文件的PIDL,手机文件夹的PIDL+文件的PIDL
                filepidl=phonefolderpidl+file_pidl
                pidlitem = shell.SHCreateItemFromIDList(filepidl,shell.IID_IShellItem2) 
                # 创建com对象
                pfo = pythoncom.CoCreateInstance(shell.CLSID_FileOperation, None, pythoncom.CLSCTX_ALL, shell.IID_IFileOperation)
                pfo.SetOperationFlags(shellcon.FOF_NOCONFIRMATION | shellcon.FOF_SILENT | shellcon.FOF_NOERRORUI)           
                
                # 是否给文件名增加日期前缀
                new_file_name=None                    
                if date_name:
                    new_file_name=f'{pidlitem.GetFileTime(("{EF6B490D-5CD8-437A-AFFC-DA8B60EE4A3C}", 18)).Format("%Y-%m-%d %H-%M-%S")}@{pidlitem.GetDisplayName(shellcon.SHGDN_NORMAL)}'
                # 拷贝文件    
                pfo.CopyItem(pidlitem, computerdiritem,new_file_name) # Schedule an operation to be performed
                pfo.PerformOperations()

三、完成代码

from win32com.shell import shell, shellcon
import os
import pythoncom

def get_folder(path,folder=None):
    folder_name = path.split("\\", 1)
    base_folder = folder or shell.SHGetDesktopFolder()
    for pidl in base_folder:        
        if base_folder.GetDisplayNameOf(pidl, shellcon.SHGDN_NORMAL) == folder_name[0]:
            folder = base_folder.BindToObject(pidl, None, shell.IID_IShellFolder)
            break
    if len(folder_name) > 1:
        return get_folder(folder_name[1],folder)
    else:
        return folder


def copy_files_to_computer(folder,phonefolderpath,computerdir,current_computer_dir=None,date_name=True):

    if folder:
        is_pfo=True
        # 遍历文件
        for file_pidl in folder:
            # 获取文件名
            file_name = folder.GetDisplayNameOf(file_pidl, shellcon.SHGDN_FORADDRESSBAR)
            # 判断是否为文件夹
            is_folder=folder.GetAttributesOf([file_pidl],shellcon.SFGAO_FOLDER)
            if is_folder==536870912:
                #生成电脑文件夹路径,将手机路径替换为电脑路径
                new_computerdir=file_name.replace(phonefolderpath,computerdir)
                # 如果电脑不存在文件夹则新建文件夹
                if not os.path.exists(new_computerdir):
                    os.makedirs(new_computerdir)
                new_folder = folder.BindToObject(file_pidl, None, shell.IID_IShellFolder)
                copy_files_to_computer(new_folder,phonefolderpath,computerdir,new_computerdir)
            # 如果是文件,则进行拷贝
            elif is_folder==0:

                if current_computer_dir is not None:
                    computerdirpidl,_=shell.SHILCreateFromPath(current_computer_dir, 0)
                else:
                    computerdirpidl,_=shell.SHILCreateFromPath(computerdir, 0)

                computerdiritem = shell.SHCreateItemFromIDList(computerdirpidl)
                phonefolderpidl = shell.SHGetIDListFromObject(folder)
                # 生成当前复制的文件的PIDL,手机文件夹的PIDL+文件的PIDL
                filepidl=phonefolderpidl+file_pidl
                pidlitem = shell.SHCreateItemFromIDList(filepidl,shell.IID_IShellItem2) 
                # 创建com对象
                pfo = pythoncom.CoCreateInstance(shell.CLSID_FileOperation, None, pythoncom.CLSCTX_ALL, shell.IID_IFileOperation)
                pfo.SetOperationFlags(shellcon.FOF_NOCONFIRMATION | shellcon.FOF_SILENT | shellcon.FOF_NOERRORUI)           
                
                # 是否给文件名增加日期前缀
                new_file_name=None                    
                if date_name:
                    new_file_name=f'{pidlitem.GetFileTime(("{EF6B490D-5CD8-437A-AFFC-DA8B60EE4A3C}", 18)).Format("%Y-%m-%d %H-%M-%S")}@{pidlitem.GetDisplayName(shellcon.SHGDN_NORMAL)}'
                # 拷贝文件    
                pfo.CopyItem(pidlitem, computerdiritem,new_file_name) # Schedule an operation to be performed
                pfo.PerformOperations()

if __name__ == '__main__':

    phonepath=r'此电脑\Apple iPhone\Internal Storage\DCI'
    computerdir=r'F:\test'
    date_name=True
    
    folder=get_folder(phonepath)    
    copy_files_to_computer(folder,phonepath,computerdir,date_name=date_name)

四、总结

以上代码实现了文件的遍历拷贝的基本流程,并未对拷贝过程中可能遇到的意外情况进行监控,如需监控需自定义实现FileOperationProgressSink类中的各种方法进行,同时此方法是会覆盖同名文件的并不会提示,如需提示可以设置此函数SetOperationFlags的相关参数,帮助中都能直接查到,很简单。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值