zoukankan      html  css  js  c++  java
  • 文件操作

    文件操作

    文件操作

    冯诺依曼体系架构

        CPU由控制器和运算器组成.

        运算器: 完成各种算数运算,逻辑运算,数据传输等数据加工处理;

        控制器: 控制程序的执行;

        存储器: 用于记忆程序和数据,例如内存等;

        输入设备: 将数据或者程序输入到计算机中,例如键盘,鼠标等;

        输出设备: 将数据或程序的处理结果展示给用户,例如显示器,打印机等.

        一般的IO操作, 指文件IO, 如果指的是网络IO,都会直接说网络IO.

    文件操作

        文件IO常用操作:

        open, read, write, close

        readline: 行读取;

        readlines: 多行读取;

        seek: 文件指针操作;

        tell: 指针位置.

    打开操作:

        open(file, mode='r', buffering=-1, encoding=None, newline=None, closefd=True, opener=None)

    打开一个文件,返回一个文件对象(流对象)和文件描述符,打开文件失败,则返回异常.

    文件操作中, 最常用的操作就是读和写.

    文件访问的模式有两种: 文本模式和和二进制模式, 不同模式,操作函数不同,表现结果也不一样.

    open操作的参数:

        file: 打开或者要创建的文件名, 如果不指定路径,默认是当前路径.

        mode模式:

    r: 缺省,表示只读打开, 文件不存在或使用write方法, 会抛异常.

    w: 只写打开,读取则抛异常,文件不存在则创建,反之清空文件内容.

    x: 创建并写入一个新文件,只读方式打开, 文件存在则抛异常.

    a: 写入打开,文件存在则追加;

    b: 二进制模式; 将文件按字节理解,与字符编码无关,二进制模式操作时,字节操作使用bytes类型.

    t: 缺省的,文本模式,字符流,将文件字节按某种字符编码理解,按字符操作,open的默认mode是rt.

    +: 读写打开一个文件, 给原来只读,只写文件打开提供缺失的读或写的功能,不能单独使用.    

    rb 二进制文件

    w或wt 文本模式写,打开前文件存储被清空;

    wb 二进制写,文件存储同样被清空;

    a+ 可读写模式,写只能写在文件末尾;

    w+ 可读写,与a+的区别是要清空文件内容;

    r+ 可读写,与a+的区别是可以写到文件任何位置;

       

    文件指针:

        mode=r, 指针起始在0;

        mode=a, 指针起始在EOF;

        tell(), 显示指针当前位置.

       

        seek(offset[, whence])

        移动文件指针位置. offset偏移多少字节, whence从哪里开始.

        文本模式下:

        whence 0 缺省值,表示从头开始, offset只能是正整数.

        whence 1 表示从当前位置, offset只接受0.

        whence 2 表示从EOF开始,offset只接受0.

       

        二进制模式下:

        whence 0 缺省值, 表示从头开始, offset只能是正整数.

        whence 1 表示从当前位置, offset可正可负.

        whence 2 表示从EOF开始, offset可正可负.

    二进制模式支持任意起点的偏移,从头,从尾,从中间位置开始.

    向后seek可以超界,但是向前seek的时候,不能超界,否则抛异常.

    bufferint: 缓冲区

        -1表示使用缺省大小的buffer.如果是二进制模式,使用io.DEFAULT_BUFFER_SIZE值,默认是4096或者8192.如果是文本模式/终端设备,是行缓存方式,反之则使用二进制模式策略.

        0只在二进制模式使用,表示关buffer.

        1只在文本模式使用,表示使用行缓冲,意思是见到换行符就flush.

        大于1用于指定buffer的大小.

       

        buffer缓存区:

           缓冲区一个内存空间,一般来说是一个FIFO队列,到缓冲区满了或达到阈值,数据才会flush到磁盘.

           flush()将缓冲区数据写入磁盘.

           close()关闭前会调用flush().

           io.DEFAULT_BUFFER_SIZE缺省缓冲区大小,字节.

      

        总结:

           1, 文本模式,一般都用默认缓冲区大小;

           2, 二进制模式,是一个个字节的操作,可以指定buffer的大小;

           3, 一般,默认缓冲区大小是个比较好的选择,除非明确知道,否则不调用它;

           4, 一般编程中,明确知道需要写磁盘了,都会手动调用一次flush,而不是等到自动flush或者close的时候.

       

    encoding:编码, 仅文本模式使用.

    encoding表示的是返回的数据采用何种编码,一般采用utf8或者gbk;

    Nome表示使用缺省编码,依赖操作系统.

    其他参数:

    errors: 什么样的编码错误将被捕获.

    None和strict表示有编码错误将抛出ValueError异常; ignore表示忽略.

    newline: 文本模式中,换行的转换. 可以为None, '', ' ', ' ', ' '.

        读时, None表示' ', ' ', ' '都会被转换成' '; ''表示不会自动转换通用换行符;其他合法字符表示换行符就是指定字符,就会按照指定字符分行.

        写时, None表示' '都会被替换为系统缺省分隔符os.sleep; ' '或表示' '不替换; 其他合法字符表示' '会被替换为指定的字符.

    closefd: 关闭文件描述符,True表示关闭它, False会在文件关闭后保持这个描述符.

    fileobj.fileno() 查看.

    read:

        read(size = -1)

           size表示读取的多少个字符或字节; 负数或者None表示读取到EOF.

    行读取:

        readline(size = -1)

           一行行读取文件内容. size设置一次能读取行内几个字符或字节;

        readlines(hint = -1)

           读取所有行的列表, 指定hint则返回指定的行数.

        write:

           write(s), 把字符串s写入到文件中并返回字符的个数;

       

        flush:

           将文件写入到硬盘.

       

        close:

           flush并关闭文件对象;

           文件已经关闭, 再次关闭没有任何效果.

       

        其他:

           seekable(), 是否可seek.

           readable(), 是否可读写.

           writeable(), 是否可写.

           closed(), 是否已经关闭.

       

        上下文管理:

        问题:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    # Linux下执行:

    (env353) [ames@ames python3.5.3]$ ipython3

    Python 3.5.3 (default, Sep 11 2017, 14:06:47)

    Type 'copyright', 'credits' or 'license' for more information

    IPython 6.2.1 -- An enhanced Interactive Python. Type '?' for help.

     

    In [1]: lst = []

     

    In [2]: for _ in range(100000):

       ...:     lst.append(open('test'))

       ...:    

    ---------------------------------------------------------------------------

    OSError                                   Traceback (most recent call last)

    <ipython-input-2-dbd507030346> in <module>()

          1 for _ in range(100000):

    ----> 2     lst.append(open('test'))

          3

     

    OSError: [Errno 24] Too many open files: 'test'

     

    In [3]:

       

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

     

    (env353) [ames@ames python3.5.3]$ lsof -p 1399 | grep test | wc -l

    0

    (env353) [ames@ames python3.5.3]$ ulimit -a

    core file size          (blocks, -c) 0

    data seg size           (kbytes, -d) unlimited

    scheduling priority             (-e) 0

    file size               (blocks, -f) unlimited

    pending signals                 (-i) 7283

    max locked memory       (kbytes, -l) 64

    max memory size         (kbytes, -m) unlimited

    open files                      (-n) 65535

    pipe size            (512 bytes, -p) 8

    POSIX message queues     (bytes, -q) 819200

    real-time priority              (-r) 0

    stack size              (kbytes, -s) 8192

    cpu time               (seconds, -t) unlimited

    max user processes              (-u) 7283

    virtual memory          (kbytes, -v) unlimited

    file locks                      (-x) unlimited

    (env353) [ames@ames python3.5.3]$

     解决办法:

        1, 异常处理:

           当出现异常时,拦截异常,但是因为很多代码都可能出现OSError异常,不好判断异常就是因为资源限制产生的.

           使用finally可以保证打开的文件可以被关闭.

    1

    2

    3

    4

    5

    f = open('test'):

    try:

        f.write('abc')  # 文件只读,写入失败.

    finally:

        f.close()  # 这样才行.

       

        2, 上下文管理:

           一种特殊的语法,交给解释器去释放文件对象.

         上下文管理:

           1, 使用with ... as关键字.

           2, 上下文管理的语句并不会开启新的作用域.

           3, with语句执行完时,会自动关闭文件对象.

          另一种写法:

    1

    2

    3

    4

    5

    6

    f1 = open('test')

    with f1:

        f1.write('abc')  # 文件只读, 写入失败.

     

    # 测试f是否关闭.

    f1.closed  # f1的作用域.

    对于类似于文件对象的IO对象,一般来说都需要在不使用时关闭,注销,以释放资源. IO被打开时,会获得一个文件描述符. 计算机资源有限,所以操作系统都会做限制.

    就是为了保护计算机的资源不要被完全耗尽,计算资源是共享的,非独占. 一般情况下,除非特别明确知道资源情况,否则不要提高资源的限制值来解决此类问题

    StringIO和BytesIO

        StringIO:  

              IO模块中的类: from io import StringIO

              内存中,开辟一个文本模式的buffer,可以像文件对象一样操作它.

              当close方法被调用时,这个buffer会被释放.

        StringIO操作:

              getvalue()获取全部内容,跟文件指针没有关系.

          

    1

    2

    3

    4

    5

    6

    7

    8

    from io import StringIO

    # 内存中构建.

    sio = StringIO()  # 像文件对象一样操作.

    print(sio.readable(), sio.writable(), sio.seekable())

    sio.seek(0)

    print(sio.readline())

    print(sio.getvalue())  # 无视指针,输出全部内容.

    sio.close()

        StringIO好处:     

           一般来说,磁盘操作比内存操作要慢很多,内存足够情况下,一般的优化思路是少落地,减少磁盘IO的过程,可以大大提高程序的运行效率.

        BytesIO:

           io模块中的类: from io import BytesIO

           内存中,开辟一个二进制模式的buffer,可以像文件对象一样操作它.

           当close方法被调用时,这个buffer会被释放.

       bytesIO操作:

    1

    2

    3

    4

    5

    6

    7

    8

    from io import BytesIO  # 内存中构建.

     

    bio = BytesIO()

    print(bio.readable(), bio.writable(), bio.seekable())

    bio.seek(0)

    print(bio.readline())

    print(bio.getvalue())  # 无视指针,输出全部内容.

    bio.close()

        file-like对象:

           类文件对象, 可以像文件对象一样操作;

           socket对象, 输入输出对象(stdin, stdout)都是类文件对象.

       

    1

    2

    3

    4

    from sys import stdout

    f = stdout

    print(type(f))

    f.write('python')

    路径操作          

        3.4版本开始, 建议使用pathlib模块, 提供Path对象来操作, 包括目录和文件.

        pathlib模块: from pathlib import Path

       目录操作:

       初始化:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    In [2]: from pathlib import Path

     

    In [3]: p = Path()  # 等同于 p = Path('.')

     

    In [4]: p

    Out[4]: PosixPath('.')

     

    In [5]: p = Path('a', 'b', 'c/d')

     

    In [6]: p

    Out[6]: PosixPath('a/b/c/d')

     

    In [7]: p = Path('/etc')

     

    In [8]: p

    Out[8]: PosixPath('/etc')

     

    In [9]:

        路径拼接和分解:  

        操作符: '/'

            Path对象/Path对象.

            Path对象/字符串 或者 字符串/Path对象.

        分解:

           parts属性,可以返回路径中的每一个部分;

        joinpath: 

        joinpath(*other) 连接多个字符串到Path对象中;

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    In [9]: p = Path()

     

    In [10]: p = p / 'a'

     

    In [11]: p

    Out[11]: PosixPath('a')

     

    In [12]: p1 = 'b' / p

     

    In [13]: p1

    Out[13]: PosixPath('b/a')

     

    In [14]: p2 = Path('c')

     

    In [15]: p2

    Out[15]: PosixPath('c')

     

    In [16]: p3 = p2 / p1

     

    In [17]: p3

    Out[17]: PosixPath('c/b/a')

     

    In [18]: p3.parts

    Out[18]: ('c', 'b', 'a')

     

    In [19]: p3.joinpath('etc', 'init.d', Path('httpd'))

    Out[19]: PosixPath('c/b/a/etc/init.d/httpd')

     

    In [20]:

        获取路径:

           str获取路径字符串.

           bytes获取路径字符串的bytes.

    1

    2

    3

    4

    5

    6

    In [20]: p = Path('/etc')

     

    In [21]: str(p), bytes(p)

    Out[21]: ('/etc', b'/etc')

     

    In [22]:

       

        父目录:

           parent目录的逻辑父目录;

           parents父目录序列.

    1

    2

    3

    4

    5

    6

    7

    8

    9

    In [22]: p = Path('/a/b/c/d')

     

    In [23]: p.parent.parent

    Out[23]: PosixPath('/a/b')

     

    In [24]: [x for x in p.parents]

    Out[24]: [PosixPath('/a/b/c'), PosixPath('/a/b'), PosixPath('/a'), PosixPath('/')]

     

    In [25]:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    In [25]: p = Path('/etc/mysqlinstall/mysql.tar.gz')

     

    In [26]: p.name

    Out[26]: 'mysql.tar.gz'

     

    In [27]: p.suffix

    Out[27]: '.gz'

     

    In [28]: p.suffixes

    Out[28]: ['.tar', '.gz']

     

    In [29]: p.stem

    Out[29]: 'mysql.tar'

     

    In [30]: p.with_name('mysql-5.tar')

    Out[30]: PosixPath('/etc/mysqlinstall/mysql-5.tar')

     

    In [31]: p = Path('README')

     

    In [32]: p.with_suffix('.txt')

    Out[32]: PosixPath('README.txt')

     

    In [33]:

    name, stem, suffix, suffixes, with_suffix(suffix), with_name(name)

     

    name目录的最后一个部分.

     

    suffix目录中最后一个部分的扩展名;

     

    stem目录最后一个部分,没有后缀;

     

    suffixes返回多个扩展名列表;

     

    with_suffix(suffix)补充扩展名到路径尾部,返回新的路径,扩展名存在则无效;

     

    with_name(name)替换目录最后一个部分并返回一个新的路径;

        cwd()返回当前工作目录;

        home()返回当前家目录;

       

        is_dir()  是否是目录;

        is_file() 是否是普通文件;

        is_symlink() 是否是软链接;

        is_socket()  是否是socket文件;

        is_block_device()  是否是块设备;

        is_char_device()  是否是字符设备;

        is_absolute()  是否是绝对路径;

       

        resolve()  返回一个新的路径, 这个新路径就是当前Path对象的绝对路径,如果是软链接则直接被解析;

        absolute()  也可以获取绝对路径,但是推荐使用resolve().

       

        exists()  目录或文件是否存在.

        rmdir()  删除空目录, 没有提供判断目录为空的方法;

        touch(mode=0o666, exist_ok=True)  创建一个文件;

        as_uri()  将路径返回成URI, 例如'file:///etc/passwd'.

       

    mkdir(mode=0o777, parents=False, exist_ok=False)

    parents, 是否创建父目录, True等同于mkdir -p; False时, 父目录不存在,则抛出FileNotFoundError.

     exist_ok参数,在3.5版本加入; False时,路径存在,抛出FileExistsError; True时,FileExistsError被忽略.

    iterdit()  迭代当前目录;

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    64

    65

    66

    67

    68

    69

    70

    71

    72

    73

    74

    75

    76

    77

    78

    79

    80

    81

    82

    83

    84

    85

    86

    87

    88

    89

    90

    91

    92

    93

    94

    95

    96

    97

    98

    99

    100

    101

    102

    103

    104

    In [34]: p = Path()

     

    In [35]: p

    Out[35]: PosixPath('.')

     

    In [36]: p /= 'a/b/c/d'   # p = p / 'a/b/c/d'

     

    In [37]: p

    Out[37]: PosixPath('a/b/c/d')

     

    In [38]: p.exists()

    Out[38]: False

     

    In [39]:

     

    In [39]: p.mkdir()

    ---------------------------------------------------------------------------

    FileNotFoundError                         Traceback (most recent call last)

    <ipython-input-39-4c751e65273b> in <module>()

    ----> 1 p.mkdir()

     

    ~/.pyenv/versions/3.5.3/lib/python3.5/pathlib.py in mkdir(self, mode, parents, exist_ok)

       1212         if not parents:

       1213             try:

    -> 1214                 self._accessor.mkdir(self, mode)

       1215             except FileExistsError:

       1216                 if not exist_ok or not self.is_dir():

     

    ~/.pyenv/versions/3.5.3/lib/python3.5/pathlib.py in wrapped(pathobj, *args)

        369         @functools.wraps(strfunc)

        370         def wrapped(pathobj, *args):

    --> 371             return strfunc(str(pathobj), *args)

        372         return staticmethod(wrapped)

        373

     

    FileNotFoundError: [Errno 2] No such file or directory: 'a/b/c/d'

     

    In [40]: p.mkdir(parents=True)

     

    In [41]: p.exists()

    Out[41]: True

     

    In [42]: p.mkdir(parents=True)

    ---------------------------------------------------------------------------

    FileExistsError                           Traceback (most recent call last)

    <ipython-input-42-09435c472033> in <module>()

    ----> 1 p.mkdir(parents=True)

     

    ~/.pyenv/versions/3.5.3/lib/python3.5/pathlib.py in mkdir(self, mode, parents, exist_ok)

       1218         else:

       1219             try:

    -> 1220                 self._accessor.mkdir(self, mode)

       1221             except FileExistsError:

       1222                 if not exist_ok or not self.is_dir():

     

    ~/.pyenv/versions/3.5.3/lib/python3.5/pathlib.py in wrapped(pathobj, *args)

        369         @functools.wraps(strfunc)

        370         def wrapped(pathobj, *args):

    --> 371             return strfunc(str(pathobj), *args)

        372         return staticmethod(wrapped)

        373

     

    FileExistsError: [Errno 17] File exists: 'a/b/c/d'

     

    In [43]: p.mkdir(parents=True, exist_ok=True)

     

    In [44]: p /= 'readme.txt'

     

    In [45]: p

    Out[45]: PosixPath('a/b/c/d/readme.txt')

     

    In [46]: p.parent.rmdir()

     

    In [47]: p.parent.exists()

    Out[47]: False

     

    In [48]: p.mkdir()

    ---------------------------------------------------------------------------

    FileNotFoundError                         Traceback (most recent call last)

    <ipython-input-48-9edfab0e3b54> in <module>()

    ----> 1 p.mkdir()

     

    ~/.pyenv/versions/3.5.3/lib/python3.5/pathlib.py in mkdir(self, mode, parents, exist_ok)

       1212         if not parents:

       1213             try:

    -> 1214                 self._accessor.mkdir(self, mode)

       1215             except FileExistsError:

       1216                 if not exist_ok or not self.is_dir():

     

    ~/.pyenv/versions/3.5.3/lib/python3.5/pathlib.py in wrapped(pathobj, *args)

        369         @functools.wraps(strfunc)

        370         def wrapped(pathobj, *args):

    --> 371             return strfunc(str(pathobj), *args)

        372         return staticmethod(wrapped)

        373

     

    FileNotFoundError: [Errno 2] No such file or directory: 'a/b/c/d/readme.txt'

     

    In [49]: p.mkdir(parents=True)

     

    In [50]: p

    Out[50]: PosixPath('a/b/c/d/readme.txt')

     

    In [51]:

         遍历, 并判断文件类型,如果为目录,是否可以判断其是否为空:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

     

    from pathlib import Path

     

    p = Path()

    p /= 'a/b/c/d'

     

    for x in p.parents[len(p.parents)-1].iterdir():

        print(x, end=' ')

        if x.is_dir():

            flag = False

            for _ in x.iterdir():

                flag = True

                break

            # for是否可以使用else子句?

            print('dir', 'Not Empty' if flag else 'Empty', sep=' ')

        elif x.is_file():

            print('file')

        else:

            print('other file')

    通配符:

        glob(pattern) 通配给定的模式;

        rglob(pattern) 通配给定的模式,递归目录;

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    In [4]: from pathlib import Path

     

    In [5]: p = Path()

     

    In [6]: list(p.glob('test*'))   # 返回当前目录对象下的test开头的文件;

    Out[6]: [PosixPath('test')]

     

    In [7]: list(p.glob('**/*.py'))   # 递归所有目录,等同于rglob.

    Out[7]: []

     

    In [8]: list(p.rglob('*.py'))

    Out[8]: []

     

    In [9]:

            匹配:

           match(pattern)

           模式匹配,成功返回True.

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    In [1]: from pathlib import Path

     

    In [2]: Path('/a/b/c.py').match('b/*.py')

    Out[2]: True

     

    In [3]: Path('/a/b.py').match('*.py')

    Out[3]: True

     

    In [4]: Path('/a/b/c.py').match('a/*.py')

    Out[4]: False

     

    In [5]: Path('/a/b/c.py').match('a/*/*.py')

    Out[5]: True

     

    In [6]: Path('/a/b/c.py').match('a/**/*.py')

    Out[6]: True

     

    In [7]: Path('/a/b/c.py').match('**/*.py')

    Out[7]: True

     

    In [8]:

        文件操作:

           open(mode='r', buffering=-1, ending=None, errors=None, newline=None)

           使用方法类似内建函数open. 返回一个文件对象.

        py3.5增加的新函数:

           read_bytes()

               以'rb'读取路径对应文件,并返回二进制流. 具体看源码.

              

           read_text(encoding=None, errors=None)

               以'rt'方式读取路径对应文件,返回文本.

          

           Path.write_bytes(data)

               以'wb'方式写入数据到路径对应文件.

       

           write_text(data, encoding=None, errors=None)

               以'wt'方式写入字符串到路径对应文件.

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

     

    from pathlib import Path

     

    p = Path('my_binary_file')

    p.write_bytes(b'Binary file contents')

    p.read_bytes()  # b'Binary file contents'

     

    p = Path('my_text_file')

    p.write_text('Text file contents')

    p.read_text()  # 'Text file contents'

     

    p = Path(r'C:Users31948Desktop est.py')

    p.write_text('hello python')

    print(p.read_text)

    with p.open() as f:

        print(f.read(5))

    shutil, csv, ini

        os.name -> windows是nt, linux是posix.

        os.uname() -> Linux支持显示.

        sys.platform  -> windows显示win32, linux显示linux.

       

        os.listdir('o:/temp')  -> 返回目录内容文件.

       

        os也有open, read, write等方法, 但太低级,建议使用内建函数open, read, write.

        os.stat(path, *, dir_fd=None, follow_symlinks=True)

           调用linux系统的stat.

           path: 路径的string或者bytes, 后者fd.

           follow_symlinks True 返回文件本身信息, False且如果是软链接则显示软链接本身.

        os.chown(path, uid, gid)  -> 改变文件的属主,属组,但需要足够的权限.

     shutil模块

           目前为止,文件的拷贝,使用打开2个文件对象,源文件读取内容,写入目标文件中来完成拷贝过程,但这样会丢失stat数据信息(权限等),因为根本就没复制过去.

           python提供了一个方便的库shutil(高级文件操作).

    copy复制:

        copyfileobj(fsrc, fdst[, length])

        文件对象的复制,fsrc和fdst是open打开的文件对象,复制内容,fdst要求可写.

        length指定了表示buffer的大小;

    1

    2

    3

    4

    5

    6

    7

    8

    import shutil

     

    with open(r'C:Users31948Desktop estone.txt', 'r+') as f1:

        f1.write('abcd 1234')

        f1.seek(0)

        f1.flush()

        with open(r'C:Users31948Desktop estfirst.txt', 'w+') as f2:

            shutil.copyfileobj(f1, f2)

           copyfile(src, dst, *, follow_symlinks=True)

        复制文件内容,不含元数据; src, dst为文件的路径字符串;

        本质上调用的就是coppyfileobj, 所以不带元数据二进制内容复制.

         copymode(src,dst,*,follow_symlinks=True)  -> 仅仅复制权限.

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    # windows下,进入src和dst文件的父目录下:

    In [1]: import shutil, os

     

    In [2]: shutil.copymode('one.txt', 'first.txt')

     

    In [3]: os.stat('one.txt')

    Out[3]: os.stat_result(st_mode=33206, st_ino=23643898043816899, st_dev=3188908737, st_nlink=1, st_uid=0, st_gid=0, st_size=10, st_atime=1509104520, st_mtime=1509109637, st_ctime=1509104520)

     

    In [4]: os.stat('first.txt')

    Out[4]: os.stat_result(st_mode=33206, st_ino=37999121856060367, st_dev=3188908737, st_nlink=1, st_uid=0, st_gid=0, st_size=10, st_atime=1509104525, st_mtime=1509109637, st_ctime=1509104520)

     

    In [5]:

        copystat(src, dst, *, follow_symlinks=True)  -> 复制元数据,stat包含权限.

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    # Linux下操作:

    (env353) [python@ames test]$ stat ont.txt

    stat: cannot stat ‘ont.txt’: No such file or directory

    (env353) [python@ames test]$ ls

    first.txt  one.txt  Untitled.ipynb

    (env353) [python@ames test]$

    (env353) [python@ames test]$ stat one.txt

      File: ‘one.txt’

      Size: 0         Blocks: 0          IO Block: 4096   regular empty file

    Device: fd00h/64768d    Inode: 1087835     Links: 1

    Access: (0664/-rw-rw-r--)  Uid: ( 1001/  python)   Gid: ( 1001/  python)

    Context: unconfined_u:object_r:user_home_t:s0

    Access: 2017-10-27 09:55:08.379019965 -0400

    Modify: 2017-10-27 09:55:08.379019965 -0400

    Change: 2017-10-27 09:55:08.379019965 -0400

     Birth: -

    (env353) [python@ames test]$ stat first.txt

      File: ‘first.txt’

      Size: 0         Blocks: 0          IO Block: 4096   regular empty file

    Device: fd00h/64768d    Inode: 1087717     Links: 1

    Access: (0664/-rw-rw-r--)  Uid: ( 1001/  python)   Gid: ( 1001/  python)

    Context: unconfined_u:object_r:user_home_t:s0

    Access: 2017-10-27 09:56:08.836225291 -0400

    Modify: 2017-10-27 09:56:08.836225291 -0400

    Change: 2017-10-27 09:56:08.836225291 -0400

     Birth: -

    (env353) [python@ames test]$

    # 打开ipython

    In [1]: import shutil

     

    In [2]: shutil.copystat('first.txt', 'one.txt')

     

    In [3]:

     

    # 再次查看:

    (env353) [python@ames test]$ stat one.txt

      File: ‘one.txt’

      Size: 0         Blocks: 0          IO Block: 4096   regular empty file

    Device: fd00h/64768d    Inode: 1087835     Links: 1

    Access: (0664/-rw-rw-r--)  Uid: ( 1001/  python)   Gid: ( 1001/  python)

    Context: unconfined_u:object_r:user_home_t:s0

    Access: 2017-10-27 09:56:08.836225291 -0400

    Modify: 2017-10-27 09:56:08.836225291 -0400

    Change: 2017-10-27 10:01:04.778385230 -0400

     Birth: -

    (env353) [python@ames test]$

        copy(src, dst, *, follow_symlinks=True)  -> 复制文件内容,权限和部分元数据,不包括创建时间和修改时间;

        本质上调用的是:

           copyfile(src, dst, follow_symlinks=follow_symlinks)

           copymode(src, dst, follow_symlinks=follow_symlinks)

        copy2比copy多了复制全部元数据,但需要平台支持.

        本质上调用的是:

           copyfile(src, dst, follow_symlinks=follow_symlinks)

           copystat(src, dst, follow_symlinks=follow_symlinks)

        copytree(src, dst, symlinks=False, ignore=Nore, copy_function=copy2, ignore_dangling_symlinks=False)

           递归复制目录. 默认使用copy2, 也就是带更多的元数据复制.

        src, dst必须是目录, src必须存在, dst必须不存在.

        ignore=func, 提供一个callable(src, names)  -> ignore_names. 提供一个函数, 它会被调用. src是源目录, names是os.listdir(src)的结果, 就是列出src中的文件名, 返回值是要被过滤的文件名的set类型数据.

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    # Linux下操作:

    (env353) [python@ames test]$ tree tmp

    tmp

    ├── a

    └── b

     

    2 directories, 0 files

    (env353) [python@ames test]$

    (env353) [python@ames test]$ tree tt

    tt [error opening dir]

     

    0 directories, 0 files

    (env353) [python@ames test]$

    (env353) [python@ames test]$ ipython

    Python 3.5.3 (default, Sep 12 2017, 03:35:37)

    Type 'copyright', 'credits' or 'license' for more information

    IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help.

     

    In [1]: import shutil

     

    In [2]: def ignore(src, names):

       ...:     ig = filter(lambda x: x.startswith('a'), names)

       ...:     return set(ig) 

       ...:

     

    In [3]:  shutil.copytree('tmp', 'tt/o', ignore=ignore)

    Out[3]: 'tt/o'

    (env353) [python@ames test]$ tree tt

    tt

    └── o

        └── b

     

    2 directories, 0 files

    (env353) [python@ames test]$

    rm删除

        shutil.rmtree(path, ignore_errors=False, onerror=None)  

        递归删除. 如同rm -rf一样危险,慎用.

        它不是原子操作,有可能删除错误,就会中断,已经删除的就删除了.

        ignore_errors为true,忽略错误. 当为False或omitted时, onerror生效.

        onerror为callable,接受函数function, path和execinfo.

    1

    Shutil.rmtree('o:/tmp')  # 类似 rm -rf操作.

    move移动

        move(src, dst, copy_function=copy2)

        递归移动文件/目录到目标, 返回目标.

        本身使用的是os.rename方法.

        如果不支持rename,如果是目录则想copytree再删除源目录.

        默认使用copy2方法.

    1

    2

    os.rename('o:/t.txt', 'o:/temp/t')

    os.rename('test3', '/tmp/py/test300')

       

        shutil还支持打包功能,生成tar并压缩,支持zip,gz,bz,xz.

    csv文件

        csv文件简介:

           逗号分隔符 Comma-Separated Values.

           CSV是一个被行分割符,列分割符划分成行和列的文本文件.

           没有指定的字符编码.

           参考: http://www.ietf.org/rfc/rfc4180.txt

           行分隔符为 ,最后一行可以没有换行符.

           列分隔符常为逗号或制表符.

           每一行成为一条记录record.

           字段可以使用双引号括起来,也可不使用.如果字段中出现双引号/逗号,换行符必须用双引号括起来,如果字段值是双引号,使用两个双引号表示一个转义.

           表头可选,和字段列对齐.

           手动生成csv文件:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    In [5]: pwd

    Out[5]: '/home/python/test'

     

    In [6]: from pathlib import Path

     

    In [7]: p = Path('/home/python/test/t.csv')

     

    In [8]: parent = p.parent

     

    In [9]: if not parent.exists():

       ...:     parent.mkdir(parents=True)

       ...:     

     

    In [10]: csv_body = '''

        ...: id, name, age, comment

        ...: 1, zs, 18, "I'm 18"

        ...: 2, ls, 20, "this is a ""test"" string."

        ...: 3, www, 23, "中国

        ...: 国庆

        ...: "

        ...: '''

     

    In [11]: p.write_text(csv_body)

    Out[11]: 108

     

    In [12]: cat t.csv

    id, name, age, comment

    1, zs, 18, "I'm 18"

    2, ls, 20, "this is a ""test"" string."

    3, www, 23, "中国

    国庆

    "

     

    In [13]:

        csv模块:

           reader(csvfile, dialect='excel', **fmtparams)

           返回DictReader的实例,是个行迭代器.

           delimiter列分隔符,逗号.

           lineterminator行分隔符 .

           quuotechar字段的引用符号,缺省为双引号("").

           双引号的处理:

               doublequote双引号的处理,默认为True.如果和quotechar为同一个,True则使用2个双引号表示,False表示使用转义字符将作为双引号的前缀.

               escapechar一个转义字符,默认为None.

               quoting指定双引号的规则. QUOTE_ALL所有字段; QUOTE_MINIMAL特殊字符字段;

               QUOTE_NONNUMERIC非数字字段; QUOTE_NONE都不使用引号.

           writer(csvfile, dialect='excel', **fmtparams)

           返回DictWriter的实例.

            主要方法有writerow, writerows.

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    # linux下:

    In [15]: import csv

     

    In [16]: from pathlib import Path

     

    In [17]: p = Path('t.csv')  

     

    In [19]: row = [4, 'tom', 22, 'tom']

     

    In [20]: rows = [(5, 'jerry', 24, 'jerry'), (6, 'justin', 22, 'just "int')]

     

    In [21]: with open(str(p), 'a+') as f:

        ...:     writer = csv.writer(f)

        ...:     writer = writerow(row)

        ...:     writer.writerows(rows)

        ...:    

    ---------------------------------------------------------------------------

    NameError                                 Traceback (most recent call last)

    <ipython-input-21-2dde75aff59c> in <module>()

          1 with open(str(p)) as f:

          2     writer = csv.writer(f)

    ----> 3     writer = writerow(row)

          4     writer.writerows(rows)

          5

     

    NameError: name 'writerow' is not defined

     

    In [23]: with open(str(p), 'a+') as f:

        ...:     writer = csv.writer(f)

        ...:     # writer = writerow(row)

        ...:     writer.writerows(rows)

        ...:    

     

    In [24]:

    (env353) [python@ames test]$ cat t.csv

     

    5,jerry,24,jerry

    6,justin,22,"just   ""int"

    (env353) [python@ames test]$

    ini文件处理:

        作为配置文件,ini格式的文件很流行:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    [root@ames ~]# cat /etc/my.cnf

    [client]

    #password = your_password

    port      = 3306

    socket    = /tmp/mysql.sock

     

    [mysqldump]

    quick

    max_allowed_packet = 16M

     

    [mysql]

    no-auto-rehash

     

    [myisamchk]

    key_buffer_size = 8M

    sort_buffer_size = 8M

     

    [mysqlhotcopy]

    interactive-timeout

        中括号里面的部分称为section.

        每一个section内,都是key-value形成的键值对,key称为option选项. 

  • 相关阅读:
    DEM地形渲染中光源的方向
    python GDAL安装运行后提示找不到proj.db
    AO——将函数栅格数据集保存到磁盘
    arcgis影像分幅图裁剪
    arcgis判断线是否穿过面
    WSL 使用vscode写python
    python-gdal支持filegdb读写
    Chapter5 生长因子、受体和癌症
    Chapter6 胞内信号网络
    【转】B树、B+树、B*树
  • 原文地址:https://www.cnblogs.com/amesy/p/7920308.html
Copyright © 2011-2022 走看看