Trabajando en un cargador simple que me pide que cargue en carpetas 'específicas del usuario', que deberían crearse la primera vez que un usuario carga algo. Todo el almacenamiento se realiza en S3. El código de prueba que tengo en este momento es este (mybucket.domain.name no es el depósito real, obviamente, cambié ese bit para esta publicación);
<cfif DirectoryExists("s3://mybucket.domain.name/test123/")> <!--- The directory exists ---> <cfelse> <!--- Directory doesn't exist, so create it ---> <cfdirectory action="CREATE" directory="s3://mybucket.domain.name/test123/" storelocation="US"> </cfif>Cuando ejecuto esto, no se devuelven errores, pero siempre informa que el directorio no existe y nunca lo crea. Revisé los documentos y las publicaciones anteriores aquí, y por lo que puedo decir, la sintaxis es correcta.
El problema principal aquí es que S3 no considera nada como una "carpeta". No hay un árbol de directorios en S3: son solo objetos, y algunos de esos objetos tienen caracteres / en sus nombres.
Hay un par de formas de evitar esto, pero ninguna le permite usar directoryExists().
La primera forma es evaluar si la matriz devuelta por directoryList('s3://mybucket/foldername') contiene algún miembro.
Otra forma es hacer todas sus operaciones S3 a través de un CFC. Aquí hay uno: https://github.com/joedanz/cf-amazon-s3
Si crea su propio componente que amplía ese, puede agregarle esta función que escribí para lograr lo mismo:
<cffunction name="folderExists" access="public" returntype="boolean" hint="folderPath = path/to/folder/ (with trailing slash and no leading slash)"> <cfargument name="folderPath" type="string" /> <cfset var objArr = getBucket(bucketName=variables.bucket,prefix='#arguments.folderPath#',delimiter='/') /> <cfloop array="#objArr#" index="local.o"> <cfif o.key EQ arguments.folderPath AND o.size EQ 0> <cfreturn true /> </cfif> </cfloop> <cfreturn false /> </cffunction>("folderPath" sería "/" si está buscando una "carpeta" en la raíz del depósito).
* otra edición: es posible que también desee esta función:
<cffunction name="folderCreate" access="public" returntype="void"> <cfargument name="folderPath" type="string" default="" /> <cfargument name="bucket" type="string" default="#variables.bucket#" /> <cfif len(folderPath)> <cfif right(folderPath,1) NEQ "/"> <cfset folderPath &= "/" /> </cfif> <cfset putObject(bucketName=bucket,uri=variables.finderPath&URLEncodedFormat(folderPath),contentType='binary/octet-stream') /> </cfif> </cffunction>Explicación: la mayoría de los clientes de S3 que he visto evitan la inexistencia de carpetas creando objetos de longitud cero e interpretándolos como carpetas.
Si desea crear una "carpeta" en AWS S3 desde ColdFusion, debe crear un archivo de longitud 0 que tenga un "/" final al final de su nombre.
La forma en que lo hago es simple usando el soporte integrado:
<cffile action = "write" file = "s3://yourS3bucket/folder_1/" output="">Después de que esto se escriba en su depósito, AWS lo informará como un directorio y DirectoryExists funcionará con él (devolverá verdadero) o si coloca en DirectoryList su depósito como una consulta, este objeto será del tipo DIR. También puede usar DirectoryCopy (aunque "recurse" no funciona realmente como se espera con ningún subdirectorio en el directorio de origen). Nota: ahora tendrá un objeto en su depósito cuya clave es "folder_1/"