2017-01-02 22 views
0

大きなファイルを50Mbのチャンクに分割して別のファイルに保存しようとしています。いくつかの読み書き操作を実行した後、私のチャンクの一部は50Mb(43Mb、17Mbなど)よりも小さくなりました。私はJavaで同じコードを書いていましたが、同じ問題があります。なにが問題ですか?私のコードは次の通りです:大きなファイルを分割するときに空きチャンク

ちなみに、このコードをスピードアップしてチャンクに分割する速度を上げるためにできることはありますか?

try: 
    f = open(self.__filename, 'rb') 
except (OSError, IOError), e: 
    raise FileSplitterException, str(e) 

bname = (os.path.split(self.__filename))[1] 

fsize = os.path.getsize(self.__filename) 

self.__chunksize = int(float(fsize)/float(self.__numchunks)) 

chunksz = self.__chunksize 
total_bytes = 0 

for x in range(self.__numchunks): 
    chunkfilename = bname + '-' + str(x+1) + self.__postfix 

    if x == self.__numchunks - 1: 
     chunksz = fsize - total_bytes 

    try: 
     print 'Writing file',chunkfilename 
     data = f.read(chunksz) 
     total_bytes += len(data) 
     chunkf = file(chunkfilename, 'wb') 
     chunkf.write(data) 
     chunkf.close() 
    except (OSError, IOError), e: 
     print e 
     continue 
    except EOFError, e: 
     print e 
     break 
+0

注:型変換に混乱を与えないでください。整数除算 'self .__ chunksize = fsize/self .__ numchunks'を使用してください。 – DyZ

答えて

0

問題のコードは、サイズが50MBのファイルではなく、設定された数のチャンクを生成することに焦点を当てているようです。

このコードは50MBのファイルを生成します。

import os 


try: 
    f = open('big.txt', 'rb') 
except (OSError, IOError), e: 
    raise FileSplitterException, str(e) 

bname = (os.path.split('big.txt'))[1] 

chunksz = 50 * 1000 * 1000 # metric MB - use 1024 * 1024 for binary MB (MiB) 

counter = 0 

while True: 
    chunkfilename = bname + '-' + str(counter+1) + '.foo' 

    try: 
     print 'Writing file',chunkfilename 
     data = f.read(chunksz) 
     if not data: 
      # We have reached the end of the file, end the script. 
      break 
     chunkf = file(chunkfilename, 'wb') 
     chunkf.write(data) 
     chunkf.close() 
    except (OSError, IOError), e: 
     print e 
     continue 
    except EOFError, e: 
     print e 
     break 
    counter += 1 

コードのいくつかの側面は、現代のpythonで貧しいスタイルと考えられている - たとえば、ファイルを開くには、コンテキストマネージャを使用していない - しかし、OPは、2.5のような古いのpythonである場合には、私はこれらを変更していません。

0

Minimal, Complete, and Verifiable exampleが含まれていないため、質問が不明です。正確にあなたのコードに間違いがあります。しかし、欠けている部分についての私の推測を作成/シミュレートした後、私はあなたが望むものをまったく引き出すことができました。

import os 

class FileSplitterException(Exception): pass 

class FileSplitter(object): 
    def __init__(self, filename, chunksize): 
     if not os.path.isfile(filename): 
      raise FileSplitterException(
       "File: {!r} does not exist".format(filename)) 
     self._filename = filename 
     self._postfix = 'chunk' 
     self._chunksize = chunksize 

    def split(self): 
     bname = os.path.splitext(self._filename)[0] 
     fsize = os.path.getsize(self._filename) 
     chunks, partial = divmod(fsize, self._chunksize) 
     if partial: 
      chunks += 1 

     with open(self._filename, 'rb') as infile: 
      for i in range(chunks): 
       chunk_filename = os.path.join('{}-{}.{}'.format(
               bname, i, self._postfix)) 
       with open(chunk_filename, 'wb') as outfile: 
        data = infile.read(self._chunksize) 
        if data: 
         outfile.write(data) 
        else: 
         FileSplitterException('unexpected EOF encountered') 

if __name__ == '__main__': 
    import glob 

    filename = 'big_file.txt' 
    chunksize = 1 * 1024 * 1024 # 1 Mb 

    print('splitting {} into {:,} sized chunks'.format(filename, chunksize)) 

    fs = FileSplitter(filename, chunksize) 
    fs.split() 

    print('chunk files written:') 
    bname = os.path.splitext(filename)[0] 
    for chunkname in sorted(glob.glob(bname + '-*.' + fs._postfix)): 
     fsize = os.path.getsize(chunkname) 
     print(' {}: size: {:,}'.format(chunkname, fsize)) 
関連する問題