2013-05-28 10 views
5

Questa è la mia prima domanda qui perché sono abbastanza nuovo in questo mondo! Ho trascorso alcuni giorni cercando di capirlo da solo, ma finora non sono riuscito a trovare nessuna informazione utile.Boto "get byte range" restituisce più del previsto

Sto cercando di recuperare un intervallo di byte da un file memorizzato in S3, con qualcosa di simile:

S3Key.get_contents_to_file(tempfile, headers={'Range': 'bytes=0-100000'} 

Il file che sto cercando di ripristinare da è un file video, in particolare un MXF. Quando richiedo un intervallo di byte, recupero più informazioni nel tempfile di quanto richiesto. Ad esempio, utilizzando un file, richiedo 100.000 byte e restituisco 100.451.

Una cosa da notare sui file MXF è che essi contengono legittimamente 0x0A (feed riga ASCII) e 0x0D (ritorno a capo ASCII).

Ho fatto uno scavo in giro e sembra che ogni volta che un byte 0D è presente nel file, le informazioni recuperate aggiungono 0A 0D invece di solo 0D, apparendo quindi per recuperare più informazioni del necessario.

A titolo di esempio, il file originale contiene la stringa esadecimale di:

02 03 00 00 00 00 3B 0A 06 0E 2B 34 01 01 01 05

Ma la forma file scaricato S3 dispone:

02 03 00 00 00 00 3B 0D 0A 06 0E 2B 34 01 01 01 05

ho cercato di eseguire il debug del codice e lavorare la mia strada attraverso la logica Boto, ma io sono relativamente nuovo a questo, in modo da perdersi molto facilmente.

Ho creato questo per i test, che mostra il problema

from boto.s3.connection import S3Connection 
from boto.s3.connection import Location 
from boto.s3.key import Key 
import boto 
import os 


## AWS credentials 
AWS_ACCESS_KEY_ID = 'secret key' 
AWS_SECRET_ACCESS_KEY = 'access key' 

## Bucket name and path to file 
bucketName = 'bucket name' 
filePath = 'path/to/file.mxf' 

#Local temp file to download to 
tempFilePath = 'c:/tmp/tempfile' 


## Setup the S3 connection and create a Key to access the file specified 
## in filePath 
conn = S3Connection(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) 
bucket = conn.get_bucket(bucketName) 
S3Key = Key(bucket) 
S3Key.key = filePath 

def testRangeGet(bytesToRead=100000): # default read of 100K 
    tempfile = open(tempFilePath, 'w') 
    rangeString = 'bytes=0-' + str(bytesToRead -1) #create byte range as string 
    rangeDict = {'Range': rangeString} # add this to the dictionary 
    S3Key.get_contents_to_file(tempfile, headers=rangeDict) # using Boto 
    tempfile.close() 
    bytesRead = os.path.getsize(tempFilePath) 
    print 'Bytes requested = ' + str(bytesToRead) 
    print 'Bytes recieved = ' + str(bytesRead) 
    print 'Additional bytes = ' + str(bytesRead - bytesToRead) 

Credo che ci sia qualcosa nel codice Boto che è alla ricerca fuori per alcuni caratteri di escape ASCII e li modifica, e non riesco a trovare alcuna modo per specificare di trattarlo come un file binario.

Qualcuno ha avuto un problema simile e può condividere un modo per aggirarlo?

Grazie

Tim

+0

Quale versione di boto stai usando? 'boto .__ version__' – Alfe

+0

Utilizzo di boto versione 2.6.0 –

+0

Ho provato qualcos'altro, giusto per assicurarmi che non sia direttamente correlato ai bit {'Range': 'byte = 0-100000'}, così ho scaricato l'intero file usando get_contents_as_file e: Byte richiesti = 234630656 Byte ricevuti = 235363424 byte aggiuntivi = 732768 –

risposta

2

Aprire il file di output come un file binario. In caso contrario, la scrittura in quel file convertirà automaticamente LF in CR/LF.

tempfile = open(tempFilePath, 'wb') 

Ovviamente è necessario solo su sistemi Windows. Gli Unix non convertono nulla, indipendentemente dal fatto che un file sia stato aperto come testo o come file binario.

È necessario fare attenzione durante il caricamento anche se non si ottengono dati corrotti di questo tipo in S3.

+0

Grazie Alfe, è semplice e ovvio quando qualcuno lo indica . Davvero apprezzato! –

Problemi correlati