Удалить расширение имени файла в Java

(Без включения каких-либо внешних библиотек.)

Какой наиболее эффективный способ удалить расширение имени файла в Java, не предполагая ничего из имени файла?

Некоторые примеры и ожидаемые результаты:

  • папка> папка
  • hello.txt> hello
  • read.me> read
  • hello.bkp.txt> hello.bkp
  • weird..name> weird.
  • .hidden> .hidden

(или последний должен быть просто hidden ?)

Редактировать : исходный вопрос предполагал, что ввод - это имя файла (а не файл дорожка). Поскольку в некоторых ответах говорится о путях к файлам, такие функции также должны работать в таких случаях, как:

  • Red.folder / hello> Red.folder / hello

Этот конкретный случай очень хорошо обрабатывается ответом Sylvain M.

23
задан Joshua Pinter 5 December 2013 в 05:22
поделиться

9 ответов

Я собираюсь нанести удар, который использует версию lastIndexOf с двумя аргументами, чтобы удалить некоторый код проверки особого случая и, надеюсь, сделать намерение более читабельно. Благодарим Джастина 'jinguy' Нельсона за основу для этого метода:

public static String removeExtention(String filePath) {
    // These first few lines the same as Justin's
    File f = new File(filePath);

    // if it's a directory, don't remove the extention
    if (f.isDirectory()) return filePath;

    String name = f.getName();

    // Now we know it's a file - don't need to do any special hidden
    // checking or contains() checking because of:
    final int lastPeriodPos = name.lastIndexOf('.');
    if (lastPeriodPos <= 0)
    {
        // No period after first character - return name as it was passed in
        return filePath;
    }
    else
    {
        // Remove the last period and everything after it
        File renamed = new File(f.getParent(), name.substring(0, lastPeriodPos));
        return renamed.getPath();
    }
}

Для меня это яснее, чем скрытые файлы в специальном регистре и файлы, не содержащие точки. Кроме того, он понятнее того, что я понимаю в вашей спецификации; что-то вроде «удалите последнюю точку и все, что следует за ней, при условии, что она существует и не является первым символом имени файла».

Обратите внимание, что в этом примере также подразумеваются строки как входы и выходы. Поскольку большая часть абстракции требует объектов File , было бы немного яснее, если бы они также были входами и выходами.

12
ответ дан 29 November 2019 в 01:20
поделиться

Это займет путь к файлу, а затем вернет новое имя файла без расширения.

public static String removeExtention(String filePath) {
    File f = new File(filePath);
    // if it's a directory, don't remove the extention
    if (fisDirectory()) return f.getName();
    String name = f.getName();
    // if it is a hidden file
    if (name.startsWith(".")) {
        // if there is no extn, do not rmove one...
        if (name.lastIndexOf('.') == name.indexOf('.')) return name;
    }
    // if there is no extention, don't do anything
    if (!name.contains(".") return name;
    // Otherwise, remove the last 'extension type thing'
    return name.substring(0, name.lastIndexOf('.'))
}

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

11
ответ дан 29 November 2019 в 01:20
поделиться

Использование common io из apache http://commons.apache.org/io/

public static String removeExtension(String filename)

К вашему сведению, исходный код здесь:

http://commons.apache.org/proper/commons-io/javadocs/api-release/src-html/org/apache/commons/io/FilenameUtils.html#line.1025

Arg, я только что попробовал кое-что...

System.out.println(FilenameUtils.getExtension(".polop")); // polop
System.out.println(FilenameUtils.removeExtension(".polop")); // empty string

Итак, это решение кажется не очень хорошим... Даже с common io придется поиграться с removeExtension() getExtension() indexOfExtension()...

26
ответ дан 29 November 2019 в 01:20
поделиться

На самом деле это очень просто, если предположить, что у вас есть допустимое имя файла.

В именах файлов Windows точка используется только для обозначения расширения. Так что снимите точку и все, что после нее.

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

Важно, чтобы вы проверили имя файла перед тем, как сделать это, так как этот алгоритм для инкрустированного имени файла может сделать что-то неожиданное и сгенерировать допустимое имя файла. Таким образом, в Windows вам может потребоваться проверить, что после точки нет обратной косой черты или двоеточия.

Если вы не знаете, с какими именами файлов вы имеете дело, относитесь ко всем как к Unix.

2
ответ дан 29 November 2019 в 01:20
поделиться
int p=name.lastIndexOf('.');
if (p>0)
  name=name.substring(0,p);

Я сказал «p> 0» вместо «p> = 0», потому что, если первый символ - точка, мы предположительно не хотим стирать все имя, как в вашем «. скрытый "пример.

Вы действительно хотите обновить имя файла на диске или имеете в виду внутреннее изменение имени файла?

2
ответ дан 29 November 2019 в 01:20
поделиться

Regex для таких вещей достаточно "быстрый", но не эффективный, если сравнивать с самым простым методом, который можно придумать: сканируйте строку с конца и усекайте ее на первой точке (не включительно). В Java вы можете использовать lastIndexOf и substring, чтобы взять только интересующую вас часть. Начальная точка должна рассматриваться как особый случай, и если последнее вхождение "." находится в начале, то должна быть возвращена вся строка.

1
ответ дан 29 November 2019 в 01:20
поделиться

Я знаю регулярное выражение для этого, но в Java у меня есть написать 10 строк кода, чтобы выполнить простую замену регулярного выражения?

С уничтожением скрытых файлов и без него:

^(.*)\..*$
^(..*)\..*$
1
ответ дан 29 November 2019 в 01:20
поделиться

Use new Remover().remove(String),

jdb@Vigor14:/tmp/stackoverflow> javac Remover.java && java Remover
folder > folder
hello.txt > hello
read.me > read
hello.bkp.txt > hello.bkp
weird..name > weird.
.hidden > .hidden

Remover.java,

import java.util.*;

public class Remover {

    public static void main(String [] args){
        Map<String, String> tests = new LinkedHashMap<String, String>();
        tests.put("folder", "folder");
        tests.put("hello.txt", "hello");
        tests.put("read.me", "read");
        tests.put("hello.bkp.txt", "hello.bkp");
        tests.put("weird..name", "weird.");
        tests.put(".hidden", ".hidden");

        Remover r = new Remover();
        for(String in: tests.keySet()){
            String actual = r.remove(in);
            log(in+" > " +actual);
            String expected = tests.get(in);
            if(!expected.equals(actual)){
                throw new RuntimeException();
            }
        }
    }

    private static void log(String s){
        System.out.println(s);
    }

    public String remove(String in){
        if(in == null) {
            return null;
        }
        int p = in.lastIndexOf(".");
        if(p <= 0){
            return in;
        }
        return in.substring(0, p);
    }
}
1
ответ дан 29 November 2019 в 01:20
поделиться
filename.replace("$(.+)\.\\w+", "\1");
0
ответ дан 29 November 2019 в 01:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: