2016-06-27 45 views
11

Ho bisogno di elencare tutti i file contenuti in una determinata cartella contenuta nel mio bucket S3.Elenco dei file in una "cartella" specifica di un bucket AWS S3

struttura La cartella è la seguente

/my-bucket/users/<user-id>/contacts/<contact-id> 

devo file relativi a utenti e file relativi a contatto di un certo utente. Ho bisogno di elencarli entrambi.

per elencare i file che sto usando questo codice:

ListObjectsRequest listObjectsRequest = new ListObjectsRequest().withBucketName("my-bucket") 
       .withPrefix("some-prefix").withDelimiter("/"); 
ObjectListing objects = transferManager.getAmazonS3Client().listObjects(listObjectsRequest); 

per elencare i file di un certo utente Sto usando questo prefisso:

users/<user-id>/

e sto correttamente ottenere tutto file nella directory esclusa la sottodirectory contacts, ad esempio:

users/<user-id>/file1.txt 
users/<user-id>/file2.txt 
users/<user-id>/file3.txt 

per elencare i file di un certo contatto utente invece sto usando questo prefisso:

users/<user-id>/contacts/<contact-id>/

ma in questo caso mi sto anche la directory stesso come un oggetto restituito:

users/<user-id>/contacts/<contact-id>/file1.txt 
users/<user-id>/contacts/<contact-id>/file2.txt 
users/<user-id>/contacts/<contact-id>/ 

Perché sto ottenendo questo comportamento? Qual è la differenza tra le due richieste di quotazione? Ho bisogno di elencare solo i file nella directory, escluse le sottodirectory.

+0

Questo comportamento è previsto se in realtà è stata creata la "cartella vuota" nella console, poiché tale azione crea effettivamente un oggetto vuoto con la chiave 'percorso/alla/mia/cartella /' così la console ha un segnaposto. Lo hai fatto mentre testavi? –

+0

@ Michael-sqlbot Non ho creato nessuna cartella vuota. Infatti tutti i file vengono caricati dall'applicazione utilizzando la struttura delle cartelle che ho segnalato come prefisso per la chiave del file. – davioooh

+0

Si potrebbe voler provare un 'GET' sull'oggetto apparente con barra finale, quindi, perché se non si crea una cartella e si utilizzava il'/'delimitatore' withDelimiter ("/") 'quando si elencano gli oggetti , questo dovrebbe significare che in effetti hai un oggetto chiamato con una barra finale, probabilmente a causa di un bug nel tuo codice che ne ha creato uno in quel modo. Un tale oggetto sarebbe probabilmente invisibile nella console. –

risposta

12

Tutto in S3 è un oggetto. Per te, potrebbero essere file e cartelle. Ma per S3, sono solo oggetti.

Gli oggetti che terminano con il delimitatore (/ nella maggior parte dei casi) sono solitamente percepiti come una cartella, ma non è sempre il caso. Dipende dall'applicazione. Di nuovo, nel tuo caso, lo stai interpretando come una cartella. S3 no. È solo un altro oggetto.

Nel tuo caso sopra, l'oggetto users/<user-id>/contacts/<contact-id>/ esiste in S3 come oggetto distinto, ma l'oggetto users/<user-id>/ no. Questa è la differenza nelle tue risposte. Perché sono così, non possiamo dirlo, ma qualcuno ha creato l'oggetto in un caso e non nell'altro. Non lo vedi nella Console di gestione AWS perché la console lo sta interpretando come una cartella e te lo nasconde.

Poiché S3 vede solo queste cose come oggetti, non "esclude" determinate cose per te. Spetta al cliente occuparsi degli oggetti come dovrebbero essere affrontati.

vostra soluzione

Dal momento che tu sei quello che non vuole gli oggetti di cartelle, è possibile escludere da soli controllando l'ultimo carattere per un /. Se lo è, quindi ignora l'oggetto dalla risposta.

0

S3 non ha directory, mentre è possibile elencare i file in una directory pseudo come si è dimostrato, non esiste alcuna directory "file" per sé.
È possibile che sia stato inavvertitamente creato un file di dati denominato users/<user-id>/contacts/<contact-id>/.

+0

Non riesco a visualizzare nessun file 'users//contacts/ /' nella console di gestione. ma, se esiste, come posso escluderlo? – davioooh

8

Mentre tutti dicono che non ci sono directory e file in s3, ma solo oggetti (e bucket), che è assolutamente vero, suggerirei di sfruttare i CommonPrefixes, descritti nella risposta this. Così, si può fare seguendo ottenere l'elenco delle "cartelle" (commonPrefixes) e "file" (objectSummaries):

ListObjectsV2Request req = new ListObjectsV2Request().withBucketName(bucket.getName()).withPrefix(prefix).withDelimiter(DELIMITER); 
ListObjectsV2Result listing = s3Client.listObjectsV2(req); 
for (String commonPrefix : listing.getCommonPrefixes()) { 
     System.out.println(commonPrefix); 
} 
for (S3ObjectSummary summary: listing.getObjectSummaries()) { 
    System.out.println(summary.getKey()); 
} 

Nel tuo caso, per objectSummaries (file) deve restituire (in caso di corretto prefisso):
utenti/user-id/contatti/contact-id/file1.txt
utenti/user-id/contatti/contact-id/file2.txt

per commonPrefixes:
utenti/user-id/contacts/contact-id/

+0

ListObjectsV2 non è ancora utilizzato in modo prominente. .getCommonPrefixes() è davvero il modo di andare qui .. – Omkar

+0

Controlla questo articolo qui, sembra che sia esattamente quello che stai cercando: http://codeflex.co/get-list-of-objects-from-s3-directory/ – user5495300

Problemi correlati