在适当的位置更改python文件

时间:2009-07-17 19:41:38

标签: python file

我有一个大的xml文件(40 Gb),我需要拆分成更小的块。我正在使用有限的空间,所以当我将它们写入新文件时,有没有办法从原始文件中删除行?

谢谢!

7 个答案:

答案 0 :(得分:7)

假设您要将文件拆分为N个片段,然后只需从文件背面开始阅读(或多或少)并反复拨打truncate

  

截断文件的大小。如果存在可选的大小参数,则文件将截断为(最多)该大小。大小默认为当前位置。当前文件位置未更改。 ...

import os
import stat

BUF_SIZE = 4096
size = os.stat("large_file")[stat.ST_SIZE]
chunk_size = size // N 
# or simply set a fixed chunk size based on your free disk space
c = 0

in_ = open("large_file", "r+")

while size > 0:
    in_.seek(-min(size, chunk_size), 2)
    # now you have to find a safe place to split the file at somehow
    # just read forward until you found one
    ...
    old_pos = in_.tell()
    with open("small_chunk%2d" % (c, ), "w") as out:
        b = in_.read(BUF_SIZE)
        while len(b) > 0:
            out.write(b)
            b = in_.read(BUF_SIZE)
    in_.truncate(old_pos)
    size = old_pos
    c += 1

小心,因为我没有测试任何这个。截断调用后可能需要调用flush,我不知道文件系统实际释放空间的速度有多快。

答案 1 :(得分:2)

如果您使用的是Linux / Unix,为什么不使用this guy之类的split命令呢?

split --bytes=100m /input/file /output/dir/prefix

编辑:然后使用csplit

答案 2 :(得分:1)

我很确定有,因为我甚至可以编辑/读取我运行的脚本的源文件,但最大的问题可能是如果你开始的话会做的所有转移在文件的开头。另一方面,如果您浏览文件并记录行的所有起始位置,则可以按相反的位置顺序复制行;一旦完成,您可以返回,一次一个地获取新文件,并且(如果它们足够小),使用readlines()生成列表,颠倒列表的顺序,然后寻找开头然后用新的行覆盖旧文件中的行。

(在使用truncate()方法从末尾读取第一个行后,你会截断文件,如果在没有任何参数的情况下使用,除了文件对象之外,它会截断当前文件位置之外的所有数据,假设您正在使用其中一个类或io包中某个类的子类来读取您的文件。您只需要确保当前文件位置在结束时开始。要写入新文件的最后一行。)

编辑:根据您对必须在正确的结束标记处进行分色的注释,您可能还需要开发一种算法来检测此类标记(可能使用peek方法),可能使用正则表达式。

答案 3 :(得分:0)

如果时间不是主要因素(或磁盘驱动器磨损):

  1. 打开文件句柄
  2. 读取分区/逻辑断点的大小(由于xml)
  3. 将文件的其余部分保存到磁盘(不确定python如何直接覆盖文件或内存使用情况)
  4. 将分区写入磁盘
  5. 转到1
  6. 如果Python没有为您提供这种级别的控制,您可能需要深入了解C.

答案 4 :(得分:0)

你总是可以解析XML文件并写出来说每个10000个元素都有自己的文件。请查看此链接的“增量分析”部分。 http://effbot.org/zone/element-iterparse.htm

答案 5 :(得分:0)

这是我的剧本......

import string
import os
from ftplib import FTP

# make ftp connection
ftp = FTP('server')
ftp.login('user', 'pwd')
ftp.cwd('/dir')

f1 = open('large_file.xml', 'r')

size = 0
split = False
count = 0

for line in f1:
  if not split:
    file = 'split_'+str(count)+'.xml'
    f2 = open(file, 'w')
    if count > 0:
      f2.write('<?xml version="1.0"?>\n')
      f2.write('<StartTag xmlns="http://www.blah/1.2.0">\n')
    size = 0
    count += 1 
    split = True    
  if size < 1073741824:
      f2.write(line)
      size += len(line)
  elif str(line) == '</EndTag>\n':
      f2.write(line)
      f2.write('</EndEndTag>\n')
      print('completed file %s' %str(count))
      f2.close()
      f2 = open(file, 'r')
      print("ftp'ing file...")
      ftp.storbinary('STOR ' + file, f2)
      print('ftp done.')
      split = False
      f2.close()
      os.remove(file)
  else:
    f2.write(line)
    size += len(line)

答案 6 :(得分:-1)

是购买新硬盘的时候了!

您可以在尝试所有其他答案之前进行备份,并且不会丢失数据:)