2010-08-26 12 views
331

Чтобы быть ясным, я не ищу тип MIME.Как получить расширение файла файла на Java?

Допустим, у меня есть следующий входной сигнал: /path/to/file/foo.txt

я хотел способ разорвать этот вход вверх, в частности, в .txt для расширения. Есть ли встроенный способ сделать это в Java? Я бы хотел, чтобы не писать собственный парсер.

+7

Вы никогда не знаете, когда придет новая платформа, которая определяет расширения как разделенные запятой. Теперь вам нужно написать код, зависящий от платформы. Структуры Java должны быть более перспективными и иметь API-интерфейсы для получения расширений, где они пишут код, зависящий от платформы, и вы, как пользователь API, просто скажете, что получите расширение. – ArtOfWarfare

ответ

473

В этом случае используйте FilenameUtils.getExtension из Apache Commons IO

Вот пример того, как использовать его (вы можете указать либо полный путь или только имя файла):

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

Следует отметить, что он возвращает только «gz» для файла с именем archive.tar.gz. – Zitrax

+71

@ Zitrax это потому, что «gz» является расширением файла. – BrainSlugs83

+5

@ BrainSlugs83 Так что же означает «смола»? – cheloncio

227

Вам действительно нужен «парсер» для этого?

String extension = ""; 

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

Предполагая, что вы имеете дело с простыми Windows, как имена файлов, а не что-то вроде archive.tar.gz.

Btw, за исключением случая, что каталог может иметь «», но само имя файла не (как /path/to.a/file), вы можете сделать

String extension = ""; 

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

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

Спасибо! Конечно, для этого вам понадобится парсер/объект, если вы хотите сделать больше манипуляций, чем просто расширение ... скажите, хотите ли вы только путь, родительский каталог, имя файла (минус расширение) и т. Д. m из C# и .Net, где у нас есть это: http://msdn.microsoft.com/en-us/library/system.io.fileinfo_members.aspx – longda

+8

Как вы говорите, есть много вещей, о которых стоит подумать, за исключением использования наивного lastIndexOf ("."). Я бы предположил, что Apache Commons имеет метод для этого, который учитывает все небольшие сложные проблемы. – MatrixFrog

+9

Я думаю, что 'i> 0' следует изменить на' i> = 0' или 'i! = -1'. Это касается имен файлов, таких как '.htaccess'. – Pijusn

2
// Modified from EboMike's answer 

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

расширение должно быть».txt "в нем, когда бежать.

+9

Сбой, если имя не имеет расширения. – EboMike

+0

А, хорошо поймать! – longda

4

Как насчет JFileChooser? Это не так просто, как вам нужно будет разобрать его конечный результат ...

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

который является типом MIME ...

OK ... Я забыл, что вы не хотите, чтобы узнать MIME-тип.

Интересный код в следующей ссылке: 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; 
} 

Связанные вопрос: How do I trim a file extension from a String in Java?

6

Как насчет (с помощью Java 1.5 RegEx):

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

Будет неправильным, если нет расширения – BullyWiiPlaza

69

Если вы используете Гуава библиотека, вы можете прибегнуть к Files служебный класс. Он имеет конкретный метод, getFileExtension(). Например:

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

Кроме того, вы можете также получить имя файла с аналогичной функцией, getNameWithoutExtension():

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

Действительно? Это отличная библиотека, полная утилит. Большинство из них будут частью Java8, например, большой Guava [Function] (http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Function.html). – JeanValjean

+0

Не все люди могут решить, какие библиотеки использовать, к сожалению. По крайней мере, у нас есть Apache Commons, хотя и старый. –

4

Вот метод, который обрабатывает .tar.gz должным образом, даже в пути с точками в именах каталогов:

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); 
} 

afterLastSlash создан, чтобы находить afterLastBackslash быстрее, так как он не будет искать вся строка, если в ней есть косые черты.

char[] внутри оригинала String повторно используется, добавив там мусора и the JVM will probably notice that afterLastSlash is immediately garbage in order to put it on the stack instead of the heap.

+0

этот метод копируется из исходного кода Guava, вы должны это указать. – humazed

+1

Я не копировал это. Если он находится в исходном коде Guava, они скопировали его здесь. Возможно, уведомите их. – Olathe

+0

жаль, что это не идентично кстати, так и вы, и у Guava dev есть такая же идея. – humazed

0

Только регулярное выражение . Не так быстро, не так хорошо.

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

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

Для того, чтобы принять в имена файлов учетных записей без символов до того точку, вы должны использовать, что небольшое изменение принятого ответа:

String extension = ""; 

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

"file.doc" => "doc" 
"file.doc.gz" => "gz" 
".doc" => "doc" 
-3

Java имеет встроенный способ борьбы с этим, в java.nio.file.Files class, который может работать для ваших нужд:

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

Обратите внимание, что этот статический метод использует спецификации found here для извлечения «типа контента», который может меняться.

+27

Это неверно. Тип возврата для probeContentType - это тип содержимого Mime, а не расширение файла. Обычно это не соответствует расширению. Это также будет довольно медленным в файловом браузере, так как он фактически открывает файл для определения типа. – Charles

69
private String getFileExtension(File file) { 
    String name = file.getName(); 
    try { 
     return name.substring(name.lastIndexOf(".") + 1); 
    } catch (Exception e) { 
     return ""; 
    } 
} 
+8

Следует отметить, что это возвращает '.' также, поэтому ваше расширение файла будет «.txt» в отличие от «txt» в некоторых других ответах. – NickEntin

+1

«Лучший ответ» и «@NickEntin». Чтобы удалить период "." из расширения файла, может быть закодирован как int lastIndexOf = name.lastIndexOf (".") + 1; –

+8

этот подход может не работать в некоторых случаях, например. /usr/bin/foo.bar/httpconf –

9

Моего загрязнен и мельчайший с помощью String.replaceAll:

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

Обратите внимание, что первый * жаден, так что будет захватывать наиболее возможные символы, насколько это возможно, а затем просто последняя точка и расширение файла будет оставил.

+0

Это не удается, если файл не имеет расширения. – Zack

+0

Да, к сожалению, все же, однако, можно использовать для простых сценариев, таких как быстрое обнаружение типа файла и, например, наличие неправильного расширения, не очень отличается от отсутствия, или можно поставить условие if, когда результат замены равен входному. –

+0

Или даже более короткое '.replaceAll (". * \\. "," ")' –

6

Если вы планируете использовать Apache Commons-IO, и просто хочу, чтобы проверить расширение файла, а затем сделать некоторые операции, вы можете использовать this, вот фрагмент:

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

Обратите внимание, что эта проверка чувствительна к регистру в соответствии с документами. –

-5

пусть «имя» быть имя файла с файлом расширения.

int len=name.length(); 
    int i=0; 
    String eXt; 
    while(i<len){ 
     if(name.charAt(i)=='.'){    
      eXt=(String) name.subSequence(i, len); 
      break; 
     } 
     i++; 
    } 
+1

В String нет метода 'subSequence'. Если бы был такой метод, он возвращал бы 'String', поэтому нет необходимости бросать. И вашему коду было бы трудно найти расширение, если имя файла содержит точки, такие как 'this.is.my.file.txt'. – Tom

25

Если на Android, вы можете использовать это:

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

Понравилось - Просто и просто – Ash

+0

Обратите внимание, что это не будет работать, если строка не закодирована (например, содержит пробел или китайский символ), см. Https://stackoverflow.com/a/14321470/1074998 –

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

Здесь я сделал небольшой метод (однако это не безопасно и оленья кожа проверки для многих ошибок), но если это только вы программируете общую java-программу, этого более чем достаточно, чтобы найти файл. Это не работает для сложных типов файлов, но обычно они не используются.

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

OP выглядит для встроенного метода – Panther

-1

Вы можете использовать Java7-функцию из java.И.О. пакет

Files.probeContentType(path); 

см ниже фрагмент кода

public static String returnContentType(String pathText) throws Exception { 

    // obtain Path object that represents the file 
    Path path = Paths.get(pathText); 

    // probe the content 
    String contentType = Files.probeContentType(path); 

    // return content type 
    return contentType; 

} 
+3

probeContentType возвращает тип Mime – XGouchet

6

Это проверенный метод

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(); 
} 

И тест:

@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")); 
} 
0

Данный вопрос дает мне много неприятностей, после чего я нашел очень простое решение для этой проблемы, которое я размещаю здесь.

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

Всё.

+2

OP Требуется способ извлечь расширение - не тестировать его. –

+0

На самом деле, что бы вы ни разрабатывали в большинстве случаев, вам нужно иметь дело только с конкретным типом файлов. Если ваша проблема возникает в этой области, это вам поможет. –

+3

Что не отвечает его требованиям –

1

Попадая расширение файла из имени файла

/** 
* 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); 
} 

Кредиты

  1. скопированные из 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

Как насчет 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)); 
} 

или с нулевым расширением поддерживается:

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); 

результат для * NIX:
путь:/корень/Docs/
Имя: риде
Удлинитель: текстового

для windows, parsePath ("c: \ windows \ readme.txt"):
путь: c: \ windows \
Имя: риде
Удлинителя: TXT

1

Вот версия с дополнительным в качестве возвращаемого значения (потому что вы не можете быть уверены, что файл имеет расширение) ... и здравомыслие проверки ...

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

без использования какой-либо библиотеки, вы можете использовать метод Разбивает строку следующим образом:

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

     String extension = ""; 

     if(splits.length >= 2) 
     { 
      extension = splits[splits.length-1]; 
     } 
2
path = "/Users/test/test.txt" 

extension = path.substring(path.lastIndexOf("."), path.length()); 

возвращение ".txt"

, если вы хотите только ".txt", сделать path.lastIndexOf(".") + 1

0

попробовать это.

String[] extension = "adadad.adad.adnandad.jpg".split("\\.(?=[^\\.]+$)"); // ['adadad.adad.adnandad','jpg'] 
extension[1] // jpg 
0
@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()); 
    } 
0

Я нашел лучший способ найти расширение путем смешивания всех выше ответы

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

Как видно из всех других ответов, нет адекватной «встроенной» функции. Это безопасный и простой метод.

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; 
} 
Смежные вопросы