¿Cómo obtengo la extensión de archivo de un archivo en Java?


484

Para ser claros, no estoy buscando el tipo MIME.

Digamos que tengo la siguiente entrada: /path/to/file/foo.txt

Me gustaría una forma de dividir esta entrada, específicamente .txtpara la extensión. ¿Hay alguna forma integrada de hacer esto en Java? Me gustaría evitar escribir mi propio analizador.


12
Nunca se sabe cuándo aparecerá una nueva plataforma que defina las extensiones como separadas por una coma. Ahora necesita escribir código dependiente de la plataforma. Los frameworks de Java deben ser más progresistas y tener API para obtener extensiones donde escriben el código dependiente de la plataforma y usted, como usuario de la API, simplemente dice obtener la extensión.
ArtOfWarfare

@ArtOfWarfare: OMG. Vamos a crear un 100MB JRE con las clases de muchos miles, pero por favor asegúrese de no aplicar cualquier método que retorna "txt"desde "filename.txt"ya que algunos plataforma de algún lugar que desee utilizar "filename,txt".
Eric Duminil

@EricDuminil "Asegúrese de no implementar ningún método que devuelva" txt "de" filename.txt "" ??? Intenta path.substring(path.lastIndexOf("."));..... y sí ... seguramente no duplicarán algo por nada ...
VelocityPulse

@VelocityPulse Eso es exactamente lo que me molesta. Como no hay una forma estándar de obtener la extensión del archivo, obtienes docenas de respuestas medio equivocadas e implementaciones ligeramente diferentes. El código utiliza 2 métodos (Me hubiera gustado tener un método único y explícito), vuelve ".txt"a partir "filename.txt", que podría no ser el resultado deseado, y lo peor de todo, se produce un error con StringIndexOutOfBoundsExceptionen lugar de devolver una cadena vacía si no hay extensión.
Eric Duminil

Respuestas:


649

En este caso, use FilenameUtils.getExtension de Apache Commons IO

Aquí hay un ejemplo de cómo usarlo (puede especificar la ruta completa o solo el nombre del archivo):

String ext1 = FilenameUtils.getExtension("/path/to/file/foo.txt"); // returns "txt"
String ext2 = FilenameUtils.getExtension("bar.exe"); // returns "exe"

Dependencia de Maven:

<dependency>
  <groupId>commons-io</groupId>
  <artifactId>commons-io</artifactId>
  <version>2.6</version>
</dependency>

Gradle Groovy DSL

implementation 'commons-io:commons-io:2.6'

Gradle Kotlin DSL

implementation("commons-io:commons-io:2.6")

Otros https://search.maven.org/artifact/commons-io/commons-io/2.6/jar


70
Debe tenerse en cuenta que solo devuelve "gz" para un archivo llamado archive.tar.gz.
Zitrax

106
@Zitrax es porque "gz" es la extensión del archivo.
BrainSlugs83

66
@ BrainSlugs83 Entonces, ¿qué significa "alquitrán"?
TuGordoBello

31
@zhelon .gz representa el archivo comprimido gnu y .tar representa (t) ape (ar) cebolleta. Entonces .tar.gz es un archivo tar dentro de un archivo comprimido gnu, que tiene la extensión .gz.
cirovladimir

55
No hay razón para traer otra biblioteca para esta tarea simple.
masterwok

311

¿Realmente necesitas un "analizador" para esto?

String extension = "";

int i = fileName.lastIndexOf('.');
if (i > 0) {
    extension = fileName.substring(i+1);
}

Suponiendo que se trata de nombres de archivo simples similares a Windows, no algo así archive.tar.gz.

Por cierto, para el caso de que un directorio pueda tener un '.', Pero el nombre de archivo en sí no (me gusta /path/to.a/file), puede hacer

String extension = "";

int i = fileName.lastIndexOf('.');
int p = Math.max(fileName.lastIndexOf('/'), fileName.lastIndexOf('\\'));

if (i > p) {
    extension = fileName.substring(i+1);
}

44
¡Gracias! Claro que es posible que necesite un analizador / objeto para esto, si desea hacer más manipulaciones que solo la extensión ... diga si desea solo la ruta, el directorio principal, el nombre del archivo (menos la extensión), etc. I ' m proveniente de C # y .Net donde tenemos esto: msdn.microsoft.com/en-us/library/…
longda

10
Como usted dice, hay varias cosas en las que pensar, más allá de usar el ingenuo lastIndexOf ("."). Supongo que Apache Commons tiene un método para esto, que tiene en cuenta todos los pequeños problemas potenciales.
MatrixFrog

12
Creo que i > 0debería cambiarse a i >= 0o i != -1. Esto se encarga de los nombres de archivo como .htaccess.
Pijusn

8
independientemente de lo simple que sea cualquier fragmento de código ... aún necesita actualizarlo / mantenerlo / probarlo / ponerlo a disposición como una dependencia conveniente ... mucho más fácil si ya había una biblioteca haciendo todo eso
Don Cheadle

2
En más gotcha es si el archivo termina con un punto. Mejor en una lib. if (i> p && i <(fileName.length () - 1)) {extension = fileName.substring (i + 1);
tgkprog

97
private String getFileExtension(File file) {
    String name = file.getName();
    int lastIndexOf = name.lastIndexOf(".");
    if (lastIndexOf == -1) {
        return ""; // empty extension
    }
    return name.substring(lastIndexOf);
}

13
Cabe señalar que esto devuelve el '.' también, por lo que su extensión de archivo será '.txt' en lugar de 'txt' en algunas de las otras respuestas
NickEntin

2
Mejor respuesta y @NickEntin Mejor comentario. Para eliminar el punto "." desde la extensión del archivo, se puede codificar como int lastIndexOf = name.lastIndexOf (".") + 1;
Hanzallah Afgan

11
ese enfoque puede no funcionar en algunos casos, por ejemplo /usr/bin/foo.bar/httpconf
Iman Akbari

8
@ lukasz1985 1. cientos de paquetes de Linux crean directorios con nombres como "init.d", además, no es seguro confiar en que la ruta no tenga directorios con puntos, ya que no es ilegal 2. Estaba codificando para Android, así que usé algunos SDK método que no recuerdo, pero supongo que stackoverflow.com/a/3571239/2546146 no tiene este defecto
Iman Akbari

66
@Iman Akbari: getName () solo devuelve el nombre del archivo, que sería "httpconf" en su ejemplo.
Dreamspace President

85

Si usa la biblioteca Guava , puede recurrir a Filesla clase de utilidad. Tiene un método específico, getFileExtension(). Por ejemplo:

String path = "c:/path/to/file/foo.txt";
String ext = Files.getFileExtension(path);
System.out.println(ext); //prints txt

Además, también puede obtener el nombre de archivo con una función similar, getNameWithoutExtension () :

String filename = Files.getNameWithoutExtension(path);
System.out.println(filename); //prints foo

44
De Verdad? Es una gran biblioteca, llena de utilidades. La mayoría de ellos formarán parte de Java8, como la gran Función Guava .
JeanValjean

Desafortunadamente, no todas las personas pueden decidir qué bibliotecas usar. Al menos tenemos Apache Commons, aunque sea viejo.
Lluis Martinez

1
si ve el código fuente de getFileExtensionhecho, no es int dotIndex = fileName.lastIndexOf('.'); return (dotIndex == -1) ? "" : fileName.substring(dotIndex + 1)gran cosa. Además, tenga en cuenta que Filesmarcado como "inestable" por alguna razón.
Al-Mothafar

@ Al-Mothafar muchas clases están marcadas como inestables (ver constructores de mapas múltiples), tampoco entiendo por qué: se han lanzado varias, pero nada ha cambiado allí.
JeanValjean

27

Si está en Android, puede usar esto:

String ext = android.webkit.MimeTypeMap.getFileExtensionFromUrl(file.getName());

Tenga en cuenta que esto no funcionará si la cadena no está codificada (por ejemplo, contiene un espacio o un carácter chino), consulte: stackoverflow.com/a/14321470/1074998
Fruta

14

Para tener en cuenta los nombres de archivo sin caracteres antes del punto, debe usar esa ligera variación de la respuesta aceptada:

String extension = "";

int i = fileName.lastIndexOf('.');
if (i >= 0) {
    extension = fileName.substring(i+1);
}

"file.doc" => "doc"
"file.doc.gz" => "gz"
".doc" => "doc"

probablemente debería defenderse de "foo". entrada.
chrisinmtown

14

Este es un método probado

public static String getExtension(String fileName) {
    char ch;
    int len;
    if(fileName==null || 
            (len = fileName.length())==0 || 
            (ch = fileName.charAt(len-1))=='/' || ch=='\\' || //in the case of a directory
             ch=='.' ) //in the case of . or ..
        return "";
    int dotInd = fileName.lastIndexOf('.'),
        sepInd = Math.max(fileName.lastIndexOf('/'), fileName.lastIndexOf('\\'));
    if( dotInd<=sepInd )
        return "";
    else
        return fileName.substring(dotInd+1).toLowerCase();
}

Y caso de prueba:

@Test
public void testGetExtension() {
    assertEquals("", getExtension("C"));
    assertEquals("ext", getExtension("C.ext"));
    assertEquals("ext", getExtension("A/B/C.ext"));
    assertEquals("", getExtension("A/B/C.ext/"));
    assertEquals("", getExtension("A/B/C.ext/.."));
    assertEquals("bin", getExtension("A/B/C.bin"));
    assertEquals("hidden", getExtension(".hidden"));
    assertEquals("dsstore", getExtension("/user/home/.dsstore"));
    assertEquals("", getExtension(".strange."));
    assertEquals("3", getExtension("1.2.3"));
    assertEquals("exe", getExtension("C:\\Program Files (x86)\\java\\bin\\javaw.exe"));
}

10

Mi sucio y más pequeño usando String.replaceAll :

.replaceAll("^.*\\.(.*)$", "$1")

Tenga en cuenta que primero *es codicioso, por lo que capturará la mayor cantidad de caracteres posibles y luego solo quedará el último punto y la extensión del archivo.


Esto falla si el archivo no tiene extensión.
Zack

Sí, desafortunadamente, todavía se puede usar para escenarios simples como la detección rápida de tipo de archivo y, por ejemplo, tener una extensión incorrecta no es muy diferente de no tener ninguno, o se puede poner una condición if cuando el resultado de reemplazar es igual a input.
Ebrahim Byagowi

1
O incluso más corto.replaceAll(".*\\.", "")
Ebrahim Byagowi

10
String path = "/Users/test/test.txt";
String extension = "";

if (path.contains("."))
     extension = path.substring(path.lastIndexOf("."));

devolver ".txt"

si solo quieres "txt", haz path.lastIndexOf(".") + 1


9

Como es obvio por todas las otras respuestas, no existe una función "incorporada" adecuada. Este es un método seguro y simple.

String getFileExtension(File file) {
    if (file == null) {
        return "";
    }
    String name = file.getName();
    int i = name.lastIndexOf('.');
    String ext = i > 0 ? name.substring(i + 1) : "";
    return ext;
}

7

¿Qué tal (usando Java 1.5 RegEx):

    String[] split = fullFileName.split("\\.");
    String ext = split[split.length - 1];

6

Si planea usar Apache commons-io, y solo desea verificar la extensión del archivo y luego hacer alguna operación, puede usar esto , aquí hay un fragmento:

if(FilenameUtils.isExtension(file.getName(),"java")) {
    someoperation();
}

Tenga en cuenta que esta comprobación distingue entre mayúsculas y minúsculas según los documentos.
Babken Vardanyan

6

Aquí hay otro one-liner para Java 8.

String ext = Arrays.stream(fileName.split("\\.")).reduce((a,b) -> b).orElse(null)

Funciona de la siguiente manera:

  1. Divida la cadena en una matriz de cadenas usando "."
  2. Convierta la matriz en una secuencia
  3. Use reduce para obtener el último elemento de la transmisión, es decir, la extensión del archivo

4

¿Qué tal JFileChooser? No es sencillo, ya que tendrá que analizar su salida final ...

JFileChooser filechooser = new JFileChooser();
File file = new File("your.txt");
System.out.println("the extension type:"+filechooser.getTypeDescription(file));

que es un tipo MIME ...

OK ... Olvidé que no quieres saber su tipo MIME.

Código interesante en el siguiente enlace: http://download.oracle.com/javase/tutorial/uiswing/components/filechooser.html

/*
 * Get the extension of a file.
 */  
public static String getExtension(File f) {
    String ext = null;
    String s = f.getName();
    int i = s.lastIndexOf('.');

    if (i > 0 &&  i < s.length() - 1) {
        ext = s.substring(i+1).toLowerCase();
    }
    return ext;
}

Pregunta relacionada: ¿Cómo recorto una extensión de archivo de una cadena en Java?


4

Aquí hay un método que se maneja .tar.gzcorrectamente, incluso en una ruta con puntos en los nombres de directorio:

private static final String getExtension(final String filename) {
  if (filename == null) return null;
  final String afterLastSlash = filename.substring(filename.lastIndexOf('/') + 1);
  final int afterLastBackslash = afterLastSlash.lastIndexOf('\\') + 1;
  final int dotIndex = afterLastSlash.indexOf('.', afterLastBackslash);
  return (dotIndex == -1) ? "" : afterLastSlash.substring(dotIndex + 1);
}

afterLastSlashestá creado para que la búsqueda sea afterLastBackslashmás rápida ya que no tendrá que buscar en toda la cadena si hay algunas barras.

El char[]interior del original Stringse reutiliza, no agrega basura allí, y la JVM probablemente notará que afterLastSlashes basura inmediatamente para colocarlo en la pila en lugar del montón .


este método se copia del código fuente de Guava, debe mencionarlo.
sorprendido

1
No copié esto. Si está en el código fuente de Guava, lo copiaron desde aquí. Quizás avisarles.
Olathe

perdón por eso no es idéntico por cierto, así que tú y el desarrollador de Guava solo tienen la misma idea.
humillado

2
Realmente "gz" es la extensión correcta para volver. Si el código de llamada también puede manejar "tar", entonces también debería verificar, externo a una getExtensionfunción. Si el nombre del archivo del usuario es "my zip. don't touch.tar.gz", este método devolverá la extensión incorrecta.
intrepidis

2
// Modified from EboMike's answer

String extension = "/path/to/file/foo.txt".substring("/path/to/file/foo.txt".lastIndexOf('.'));

la extensión debería tener ".txt" cuando se ejecute.


13
Se bloqueará si el nombre no tiene una extensión.
EboMike

2

Aquí está la versión con Opcional como valor de retorno (porque no puede estar seguro de que el archivo tenga una extensión) ... también verificaciones de cordura ...

import java.io.File;
import java.util.Optional;

public class GetFileExtensionTool {

    public static Optional<String> getFileExtension(File file) {
        if (file == null) {
            throw new NullPointerException("file argument was null");
        }
        if (!file.isFile()) {
            throw new IllegalArgumentException("getFileExtension(File file)"
                    + " called on File object that wasn't an actual file"
                    + " (perhaps a directory or device?). file had path: "
                    + file.getAbsolutePath());
        }
        String fileName = file.getName();
        int i = fileName.lastIndexOf('.');
        if (i > 0) {
            return Optional.of(fileName.substring(i + 1));
        } else {
            return Optional.empty();
        }
    }
}

2

¿Qué tal la versión REGEX :

static final Pattern PATTERN = Pattern.compile("(.*)\\.(.*)");

Matcher m = PATTERN.matcher(path);
if (m.find()) {
    System.out.println("File path/name: " + m.group(1));
    System.out.println("Extention: " + m.group(2));
}

o con extensión nula compatible:

static final Pattern PATTERN =
    Pattern.compile("((.*\\" + File.separator + ")?(.*)(\\.(.*)))|(.*\\" + File.separator + ")?(.*)");

class Separated {
    String path, name, ext;
}

Separated parsePath(String path) {
    Separated res = new Separated();
    Matcher m = PATTERN.matcher(path);
    if (m.find()) {
        if (m.group(1) != null) {
            res.path = m.group(2);
            res.name = m.group(3);
            res.ext = m.group(5);
        } else {
            res.path = m.group(6);
            res.name = m.group(7);
        }
    }
    return res;
}


Separated sp = parsePath("/root/docs/readme.txt");
System.out.println("path: " + sp.path);
System.out.println("name: " + sp.name);
System.out.println("Extention: " + sp.ext);

resultado para * nix:
ruta: / root / docs /
name: readme
Extensión: txt

para Windows, parsePath ("c: \ windows \ readme.txt"):
ruta: c: \ windows \
name: readme
Extensión: txt


1
String extension = com.google.common.io.Files.getFileExtension("fileName.jpg");

1

Aquí hice un método pequeño (sin embargo, no es tan seguro y no comprueba muchos errores), pero si solo usted está programando un programa general de Java, esto es más que suficiente para encontrar el tipo de archivo. Esto no funciona para tipos de archivo complejos, pero normalmente no se usan tanto.

    public static String getFileType(String path){
       String fileType = null;
       fileType = path.substring(path.indexOf('.',path.lastIndexOf('/'))+1).toUpperCase();
       return fileType;
}

OP está buscando un método incorporado
Panther

(1) Debe usar lastIndexOfpara que los nombres de archivo como john.smith.report.docse traten correctamente. (2) Debe manejar adecuadamente los casos cuando no hay extensión. Este método devuelve ABC/XYZuna ruta como abc/xyz, que no tiene ningún sentido. Tendría más sentido volver ""o null. (3) El separador de archivos no siempre es así /.
Radiodef

1

Obtener extensión de archivo del nombre de archivo

/**
 * The extension separator character.
 */
private static final char EXTENSION_SEPARATOR = '.';

/**
 * The Unix separator character.
 */
private static final char UNIX_SEPARATOR = '/';

/**
 * The Windows separator character.
 */
private static final char WINDOWS_SEPARATOR = '\\';

/**
 * The system separator character.
 */
private static final char SYSTEM_SEPARATOR = File.separatorChar;

/**
 * Gets the extension of a filename.
 * <p>
 * This method returns the textual part of the filename after the last dot.
 * There must be no directory separator after the dot.
 * <pre>
 * foo.txt      --> "txt"
 * a/b/c.jpg    --> "jpg"
 * a/b.txt/c    --> ""
 * a/b/c        --> ""
 * </pre>
 * <p>
 * The output will be the same irrespective of the machine that the code is running on.
 *
 * @param filename the filename to retrieve the extension of.
 * @return the extension of the file or an empty string if none exists.
 */
public static String getExtension(String filename) {
    if (filename == null) {
        return null;
    }
    int index = indexOfExtension(filename);
    if (index == -1) {
        return "";
    } else {
        return filename.substring(index + 1);
    }
}

/**
 * Returns the index of the last extension separator character, which is a dot.
 * <p>
 * This method also checks that there is no directory separator after the last dot.
 * To do this it uses {@link #indexOfLastSeparator(String)} which will
 * handle a file in either Unix or Windows format.
 * <p>
 * The output will be the same irrespective of the machine that the code is running on.
 *
 * @param filename  the filename to find the last path separator in, null returns -1
 * @return the index of the last separator character, or -1 if there
 * is no such character
 */
public static int indexOfExtension(String filename) {
    if (filename == null) {
        return -1;
    }
    int extensionPos = filename.lastIndexOf(EXTENSION_SEPARATOR);
    int lastSeparator = indexOfLastSeparator(filename);
    return (lastSeparator > extensionPos ? -1 : extensionPos);
}

/**
 * Returns the index of the last directory separator character.
 * <p>
 * This method will handle a file in either Unix or Windows format.
 * The position of the last forward or backslash is returned.
 * <p>
 * The output will be the same irrespective of the machine that the code is running on.
 *
 * @param filename  the filename to find the last path separator in, null returns -1
 * @return the index of the last separator character, or -1 if there
 * is no such character
 */
public static int indexOfLastSeparator(String filename) {
    if (filename == null) {
        return -1;
    }
    int lastUnixPos = filename.lastIndexOf(UNIX_SEPARATOR);
    int lastWindowsPos = filename.lastIndexOf(WINDOWS_SEPARATOR);
    return Math.max(lastUnixPos, lastWindowsPos);
}

Créditos

  1. Copiado de la clase Apache FileNameUtils - http://grepcode.com/file/repo1.maven.org/maven2/commons-io/commons-io/1.3.2/org/apache/commons/io/FilenameUtils.java#FilenameUtils. getExtension% 28java.lang.String% 29

1

Sin el uso de ninguna biblioteca, puede usar el método String dividido de la siguiente manera:

        String[] splits = fileNames.get(i).split("\\.");

        String extension = "";

        if(splits.length >= 2)
        {
            extension = splits[splits.length-1];
        }

0

Solo una alternativa basada en expresiones regulares. No tan rápido, no tan bueno.

Pattern pattern = Pattern.compile("\\.([^.]*)$");
Matcher matcher = pattern.matcher(fileName);

if (matcher.find()) {
    String ext = matcher.group(1);
}

0

Encontré una mejor manera de encontrar extensiones combinando todas las respuestas anteriores

public static String getFileExtension(String fileLink) {

        String extension;
        Uri uri = Uri.parse(fileLink);
        String scheme = uri.getScheme();
        if (scheme != null && scheme.equals(ContentResolver.SCHEME_CONTENT)) {
            MimeTypeMap mime = MimeTypeMap.getSingleton();
            extension = mime.getExtensionFromMimeType(CoreApp.getInstance().getContentResolver().getType(uri));
        } else {
            extension = MimeTypeMap.getFileExtensionFromUrl(fileLink);
        }

        return extension;
    }

public static String getMimeType(String fileLink) {
        String type = CoreApp.getInstance().getContentResolver().getType(Uri.parse(fileLink));
        if (!TextUtils.isEmpty(type)) return type;
        MimeTypeMap mime = MimeTypeMap.getSingleton();
        return mime.getMimeTypeFromExtension(FileChooserUtil.getFileExtension(fileLink));
    }

0

Me gusta la simplicidad de la respuesta de Spectre , y en uno de sus comentarios hay un enlace a otra respuesta que corrige los puntos en las rutas de los archivos, en otra pregunta, realizada por EboMike .

Sin implementar algún tipo de API de terceros, sugiero:

private String getFileExtension(File file) {

    String name = file.getName().substring(Math.max(file.getName().lastIndexOf('/'),
            file.getName().lastIndexOf('\\')) < 0 ? 0 : Math.max(file.getName().lastIndexOf('/'),
            file.getName().lastIndexOf('\\')));
    int lastIndexOf = name.lastIndexOf(".");
    if (lastIndexOf == -1) {
        return ""; // empty extension
    }
    return name.substring(lastIndexOf + 1); // doesn't return "." with extension
}

Algo como esto puede ser útil, por ejemplo, en cualquiera de los writemétodos de ImageIO , donde se debe pasar el formato de archivo.

¿Por qué utilizar una API de terceros completa cuando puedes hacer bricolaje?


0

Esta pregunta en particular me dio muchos problemas, entonces encontré una solución muy simple para este problema que estoy publicando aquí.

file.getName().toLowerCase().endsWith(".txt");

Eso es.


3
OP Necesita una forma de extraer la extensión, no probarla.
Predrag Manojlovic

en realidad, sea lo que sea que esté desarrollando en la mayoría de los casos, debe tratar solo con un tipo particular de archivos ... así que si su problema se presenta en esta área, esto lo ayudará.
Vikram Bhardwaj

44
Lo que no responde a sus requisitos
Predrag Manojlovic

2
Esta no es una respuesta a la pregunta, pero de hecho era lo que estaba buscando.
Ediolot

-1

prueba esto.

String[] extension = "adadad.adad.adnandad.jpg".split("\\.(?=[^\\.]+$)"); // ['adadad.adad.adnandad','jpg']
extension[1] // jpg

-1
  @Test
    public void getFileExtension(String fileName){
      String extension = null;
      List<String> list = new ArrayList<>();
      do{
          extension =  FilenameUtils.getExtension(fileName);
          if(extension==null){
              break;
          }
          if(!extension.isEmpty()){
              list.add("."+extension);
          }
          fileName = FilenameUtils.getBaseName(fileName);
      }while (!extension.isEmpty());
      Collections.reverse(list);
      System.out.println(list.toString());
    }

-4

Java tiene una forma integrada de lidiar con esto, en la clase java.nio.file.Files , que puede funcionar para sus necesidades:

File f = new File("/path/to/file/foo.txt");
String ext = Files.probeContentType(f.toPath());
if(ext.equalsIgnoreCase("txt")) do whatever;

Tenga en cuenta que este método estático utiliza las especificaciones que se encuentran aquí para recuperar el "tipo de contenido", que puede variar.


28
Esto es incorrecto. El tipo de retorno para probeContentType es el tipo de contenido Mime, no la extensión del archivo. Por lo general, no coincidirá con la extensión. Esto también sería bastante lento en un navegador de archivos, ya que en realidad abre el archivo para determinar el tipo.
Charles
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.