2013-07-01 1 views
0

KML 파일을 만드는 모델이 있습니다. 내가 메일러에 다음을 제공하는 것이 앞으로 다음 문자열로 그 KML을 취급 :너무 많은 메모리를 사용하지 않고 큰 텍스트 파일 저장

def write_kml(coords3d, time) 
    kml = String.new 
    kml << header 
    coords3d.each do |coords| 
     coordinates = String.new 
     coords.each do |coord| 
     lat = coord[0].to_f 
     lng = coord[1].to_f 
     coordinates << "#{lng}" + "," "#{lat}" + ",0 " 
     kml << polygon(coordinates) 
     end 
     end 

    kml << footer 
    kml 

end 

이 여기에 사용됩니다 :

CsvMailer.kml_send(kml,time, mode, email).deliver 

메일러 :

def kml_send(kml, time, mode, email) 
    @time = (time/60).to_i 
    @mode = mode 
    gen_time = Time.now 
    file_name = gen_time.strftime('%Y-%m-%d %H:%M:%S') + " #{@mode.to_s}" + " #{@time.to_s}(mins)" 
    attachments[file_name + '(KML).kml'] = { mime_type: 'text/kml', content: kml} 
    mail to: email, subject: ' KML Filem' 
    end 

그것은 차지하는 엄청난 양의 메모리. 이 파일들 중 일부는 꽤 큽니다 (200MB). 예를 들어 Heroku에서는 너무 많은 공간을 차지합니다.

나는 S3를 사용하여 몇 가지 아이디어를 가지고 있었지만,이 파일을 만들어서 메모리를 계속 사용해야했습니다. 메모리를 사용하지 않고 S3에 곧바로 쓸 수 있습니까?

답변

1

s3 멀티 파트 업로드를 통해 파일 크기를 미리 알 필요가 없으므로이를 수행 할 수 있습니다.

부품의 크기는 최소 5MB 여야하므로 가장 쉽게 사용할 수있는 방법은 메모리 버퍼에 데이터를 쓰고 5MB를 초과 할 때마다 부품을 s3에 업로드하는 것입니다. 업로드에는 10000 개의 부분이 있습니다. 따라서 파일 크기가 50GB를 넘으면 부품을 더 크게 만들 수 있도록 사전에 알아야합니다. 안개 라이브러리를 사용

, 즉 당신이 버퍼를 포장 업 로더 클래스를 생성하고 거기에 모든 S3 논리를 붙어 있다면 당신은 아마 깔끔한 뭔가 가지고 올 수

def upload_chunk connection, upload_id, chunk, index 
    md5 = Base64.encode64(Digest::MD5.digest(chunk)).strip 
    connection.upload_part('bucket', 'a_key', upload_id, chunk_index, chunk, 'Content-MD5' => md5) 
end 


connection = Fog::Storage::AWS.new(:aws_access_key_id => '...', :region => '...', :aws_secret_access_key => '...' 
upload_id = connection.initiate_multipart_upload('bucket', 'a_key').body['UploadId'] 
chunk_index = 1 

kml = String.new 
kml << header 
coords3d.each do |coords| 
    #append to kml 
    if kml.bytesize > 5 * 1024 * 1024 
    upload_chunk connection, upload_id, kml, chunk_index 
    chunk_index += 1 
    kml = '' 
    end 
end 
upload_chunk connection, upload_id, kml, chunk_index 
#when you've uploaded all the chunks 
connection.complete_multipart_upload('bucket', 'a_key', upload_id) 

처럼 조금 보일 것이다. 그렇다면 kml 코드에는 실제 문자열이 있는지 또는 s3에 주기적으로 플러시되는 문자열인지 알 필요가 없습니다.

+0

감사합니다. 어떤 부품이 5 메가 바이트에 도달했는지 어떻게 알 수 있습니까? 그리고 그것들을 모두 다른 끝과 함께 결합합니까? –

+0

문자열에 추가 할 때마다 5MB가 넘는지를 자주 확인해야합니다. 그렇다면 청크를 업로드하십시오 (정확하게 5MB 일 필요는 없습니다). S3는 모든 합류를 처리합니다 –

+0

예를 들어 주시겠습니까? 나는 5 메가마다 믿을 수있게 그것을 분쇄하기 위해 고심하고있다. –

관련 문제