zoukankan      html  css  js  c++  java
  • 3 [文件]-修改文件

    1. r+ seek 修改文件

     以r+模式打开文件,默认会把新增的内容追加到文件最后面。但我想要的是修改中间的内容 

    我擦,好像我的[路飞学城] 把后面的内容覆盖啦

    #1 问:为什么这样子?
    
    这是硬盘的存储原理导致的,当你把文件存到硬盘上,就在硬盘上划了一块空间,存数据,等你下次打开这个文件 ,seek到一个位置,每改一个字,就是把原来的覆盖掉,如果要插入,是不可能的,因为后面的数据在硬盘上不会整体向后移。所以就出现 当前这个情况 ,你想插入,却变成了会把旧内容覆盖掉。
    
    #2 问:但是人家word, vim 都可以修改文件 呀,你这不能修改算个什么玩意?
    
    我并没说就不能修改了,你想修改当然可以,就是不要在硬盘上修改,把内容全部读到内存里,数据在内存里可以随便增删改查,修改之后,把内容再全部写回硬盘,把原来的数据全部覆盖掉。vim word等各种文本编辑器都是这么干的。
    
    #3 问:说的好像有道理,但你又没看过word软件的源码,你凭什么这么笃定?
    
    哈哈,我不需要看源码,硬盘 的存储原理决定了word必须这么干 ,不信的话,还有个简单的办法来确认我说的,就是用word or vim读一个编辑一个大文件 ,至少几百MB的,你 会发现,加载过程会花个数十秒,这段时间干嘛了? cpu 去玩了?去上厕所啦? 当然不是,是在努力把数据 从硬盘上读到内存里。
    
    # 4问:但是文件如果特别大,比如5个GB,读到内存,就一下子吃掉了5GB内存,好费资源呀,有没有更好的办法呢?
    
    如果不想占内存,只能用另外一种办法啦,就是边读边改, 什么意思? 不是不能改么?是不能改原文件 ,但你可以打开旧文件 的同时,生成一个新文件呀,边从旧的里面一行行的读,边往新的一行行写,遇到需要修改就改了再写到新文件 ,这样,在内存里一直只存一行内容。就不占内存了。 但这样也有一个缺点,就是虽然不占内存 ,但是占硬盘,每次修改,都要生成一份新文件,虽然改完后,可以把旧的覆盖掉,但在改的过程中,还是有2份数据 的。
    
    # 5问:还有更好的方式 么?
    
    有完没完? 没了。

    2.占硬盘修改方式

     

    new_str = 'hhhh'
    old_str = '2'
    
    f1 = open('file_1.bak', 'r')
    f2 = open('file_2.bak', 'w')
    for line in f1:
        if old_str in line:
            new_line = line.replace(old_str,new_str)   # 替换
        else:
            new_line = line
        f2.write(new_line)
    f1.close()

      (2)原文件不动,若想覆盖原文件 os.rename()

    import os
    
    f_name = "兼职白领学生空姐模特护士联系方式utf8.txt"
    f_new_name = "%s.new" % f_name
    
    old_str = "乔亦菲"
    new_str = "[乔亦菲 Yifei Qiao]"
    
    f = open(f_name,'r',encoding="utf-8")
    f_new = open(f_new_name,'w',encoding="utf-8")
    
    for line in f:
        if old_str in line:
            new_line = line.replace(old_str,new_str)
        else:
            new_line = line
    
        f_new.write(new_line)
    
    f.close()
    f_new.close()
    
    os.rename(f_new_name,f_name) #把新文件名字改成原文件 的名字,就把之前的覆盖掉了

    3.占内存修改方式

    old_name = 'file_1.bak'
    old_str = '2'
    new_str = 'A'
    
    with open(old_name, 'r+') as f1:
        data = f1.read()
        new_data = data.replace(old_str, new_str)
    
    with open(old_name, 'r+') as f2:
        f2.write(new_data)

    Read 全部  data.replace(

    原文件1G 修改后剩下800M  文件truncate截断后,  write

    4.5G大文件读到内存

    思路:while循环
             f.read(1024)           #f.read()  f.readlines()不可用
     file_name = input("请输入文件名:")
     f1 = open(file_name,"r")
     position = file_name.rfind(".")
     new_file_name = file_name[0:position] + "[大文件]" + file_name[position:]
     
     f2 = open(new_file_name,"w")
     
     while True: 
         result = f1.read(1024)    #切记不可以用f.read()  f.readlines()
         if len(result) == 0:
             break
    
     f2.write(result)
     
     f1.close()
     f2.close()
  • 相关阅读:
    反射实现Model修改前后的内容对比
    [C#] 将NLog输出到RichTextBox,并在运行时动态修改日志级别过滤
    C#远程调用技术WebService葵花宝典
    C# winform实现右下角弹出窗口结果的方法
    C# / VB.NET合并PDF指定页
    C# Word转PDF/HTML/XML/XPS/SVG/EMF/EPUB/TIFF
    C# 将PDF转为SVG的3种情况
    C# 如何将PDF转为多种图像文件格式(Png/Bmp/Emf/Tiff)
    C# 按指定范围拆分Excel工作表
    Powershell如何在Start-Job的Scriptblock里传参?
  • 原文地址:https://www.cnblogs.com/venicid/p/8405124.html
Copyright © 2011-2022 走看看