Удалить расширение имени файла в Java
(Без включения каких-либо внешних библиотек.)
Какой самый эффективный способ удалить расширение имени файла в Java, не принимая ничего из имени файла?
Некоторые примеры и ожидаемые результаты:
- папкa >
- hello.txt > hello
- read.me > читать
- hello.bkp.txt > hello.bkp
- weird..name > странный.
- .hidden > .hidden
(или должен быть скрыт последний)?
Изменить. В исходном вопросе предполагается, что вход является именем файла (а не файловым путем). Поскольку некоторые ответы касаются путей к файлам, такие функции также должны работать в таких случаях, как:
- редкий. папка/привет > редкий. папка/привет.
Этот частный случай очень хорошо обрабатывается ответом Сильвана М.
Ответы
Ответ 1
У меня будет удар, который использует версию с двумя аргументами lastIndexOf
, чтобы удалить код проверки специального кода и, надеюсь, сделает его более читаемым. Кредит отправляется Justin 'jinguy' Nelson за основу этого метода:
public static String removeExtention(String filePath) {
// These first few lines the same as Justin's
File f = new File(filePath);
// if it a directory, don't remove the extention
if (f.isDirectory()) return filePath;
String name = f.getName();
// Now we know it 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
, было бы немного более четким, если бы это были входы и выходы.
Ответ 2
Использование общего io из apache http://commons.apache.org/io/
public static String removeExtension (String filename)
FYI, исходный код здесь:
http://commons.apache.org/proper/commons-io/javadocs/api-release/src-html/org/apache/commons/io/FilenameUtils.html#line.1025
Арг, я просто что-то пробовал...
System.out.println(FilenameUtils.getExtension(".polop")); // polop
System.out.println(FilenameUtils.removeExtension(".polop")); // empty string
Итак, это решение кажется не очень хорошим...
Даже с обычным io, вам придется играть с removeExtension() getExtension() indexOfExtension()...
Ответ 3
Это займет путь к файлу и затем вернет новое имя файла без расширения.
public static String removeExtention(String filePath) {
File f = new File(filePath);
// if it 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-редактора. Этот код не предназначен для производства. Он предназначен только для сервера как хороший пример первой попытки, как я хотел бы удалить расширение из имени файла.
Ответ 4
На самом деле это очень просто, если у вас есть допустимое имя файла.
В именах файлов Windows символ точки используется только для обозначения расширения. Так разделите точку и что-нибудь после нее.
В unix-подобных именах файлов точка указывает расширение, если оно после последнего разделителя ('/') и имеет по крайней мере один символ между ним и последним разделителем (и не является первым символом, если нет разделителей), Найдите последнюю точку, посмотрите, удовлетворяет ли она условиям, и разделите ее и любые конечные символы, если это произойдет.
Важно, чтобы вы подтвердили имя файла перед тем, как это сделать, поскольку этот алгоритм на invlaid filename может сделать что-то неожиданное и создать допустимое имя файла. Поэтому в Windows вам может потребоваться проверить, нет ли обратной косой черты или двоеточия после точки.
Если вы не знаете, с каким именем вы сталкиваетесь, обработка их всех, как Unix, доставит вам большую часть пути.
Ответ 5
int p=name.lastIndexOf('.');
if (p>0)
name=name.substring(0,p);
Я сказал "p > 0" вместо "p >= 0", потому что, если первый символ является периодом, мы предположительно не хотим уничтожить все имя, как в вашем примере ".hidden".
Вы действительно хотите обновить имя файла на диске, или вы говорите о том, чтобы просто манипулировать им внутри?
Ответ 6
Regex для этих вещей "быстро" достаточно, но не эффективен, если сравнивать с простейшим методом, который можно подумать: сканировать строку с конца и усекать ее в первой точке (не включительно). В Java вы можете использовать lastIndexOf и подстроку, чтобы взять только интересующую вас часть. Исходную точку следует рассматривать как частный случай, и если последнее вхождение "." находится в начале, вся строка должна быть возвращена.
Ответ 7
Я знаю regex, чтобы сделать это, но в Java мне нужно написать, как 10 строк кода, чтобы сделать простое замещение регулярного выражения?
С и без убийства скрытых файлов:
^(.*)\..*$
^(..*)\..*$
Ответ 8
Используйте новый Remover(). remove (String),
[email protected]:/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);
}
}
Ответ 9
filename.replace("$(.+)\.\\w+", "\1");
Ответ 10
Функция remove()
выше должна быть переписана для поддержки тестовых примеров, таких как LOST.DIR/myfile.txt
public static String removeExtension( String in )
{
int p = in.lastIndexOf(".");
if ( p < 0 )
return in;
int d = in.lastIndexOf( File.separator );
if ( d < 0 && p == 0 )
return in;
if ( d >= 0 && d > p )
return in;
return in.substring( 0, p );
}