明確にするために、私はMIMEタイプを探していません。
次のような入力があるとしましょう。/path/to/file/foo.txt
この入力を、特に拡張子の.txt
に分解する方法が欲しいのですが。 Javaでこれを行うための方法は組み込まれていますか?私は自分のパーサーを書かないようにしたいと思います。
この場合は、 FilenameUtils.getExtension from Apache Commons IO を使用します。
これを使用する方法の例を次に示します(フルパスまたはファイル名のみを指定できます)。
String ext1 = FilenameUtils.getExtension("/path/to/file/foo.txt"); // returns "txt"
String ext2 = FilenameUtils.getExtension("bar.exe"); // returns "exe"
これには本当に「パーサー」が必要ですか。
String extension = "";
int i = fileName.lastIndexOf('.');
if (i > 0) {
extension = fileName.substring(i+1);
}
archive.tar.gz
のようなものではなく、単純なWindowsのようなファイル名を扱っていると仮定します。
ところで、ディレクトリに '。'があるかもしれませんが、ファイル名自体にはない(/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);
}
private String getFileExtension(File file) {
String name = file.getName();
int lastIndexOf = name.lastIndexOf(".");
if (lastIndexOf == -1) {
return ""; // empty extension
}
return name.substring(lastIndexOf);
}
Guava libraryを使用する場合は、 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
Androidの場合、これを使用できます。
String ext = Android.webkit.MimeTypeMap.getFileExtensionFromUrl(file.getName());
文字のないファイル名 前 ドットを考慮に入れるために、あなたは受け入れられた答えのそのわずかな変化を使用しなければなりません:
String extension = "";
int i = fileName.lastIndexOf('.');
if (i >= 0) {
extension = fileName.substring(i+1);
}
"file.doc" => "doc"
"file.doc.gz" => "gz"
".doc" => "doc"
私の汚いと String.replaceAll :
.replaceAll("^.*\\.(.*)$", "$1")
最初の*
は欲張りなので、可能な限り多くの可能な文字を取得し、最後のドットとファイル拡張子だけが残ります。
これはテスト済みの方法です
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"));
}
他のすべての答えから明らかなように、適切な「組み込み」機能はありません。これは安全で簡単な方法です。
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;
}
(Java 1.5 RegExを使用して)どうですか。
String[] split = fullFileName.split("\\.");
String ext = split[split.length - 1];
Apache commons-ioを使用し、ファイルの拡張子を確認してから何らかの操作を実行する場合は、 this を使用できます。これは、以下のスニペットです。
if(FilenameUtils.isExtension(file.getName(),"Java")) {
someoperation();
}
これは、ディレクトリ名にドットが含まれているパスでも、.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
を素早く見つけるために作成されています。
元のString
内のchar[]
は再利用され、そこにガベージは追加されず、 JVMはおそらくafterLastSlash
がヒープの代わりにスタックに置かれるためにすぐにガベージであることに気付くでしょう 。
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;
}
関連する質問: Javaで文字列からファイル拡張子を削除する方法
String path = "/Users/test/test.txt"
String extension = path.substring(path.lastIndexOf("."), path.length());
「.text」を返します
「テキスト」のみが必要な場合は、path.lastIndexOf(".") + 1
を作成します
これはJava 8のためのもう一つのワンライナーです。
String ext = Arrays.stream(fileName.split("\\.")).reduce((a,b) -> b).orElse(null)
次のように動作します。
// Modified from EboMike's answer
String extension = "/path/to/file/foo.txt".substring("/path/to/file/foo.txt".lastIndexOf('.'));
実行時には、拡張子に「.txt」が必要です。
これは戻り値としてOptionalを使ったバージョンです(ファイルに拡張子があるかどうかわからないからです)...また健全性チェック...
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();
}
}
}
_ regex _ versionはどうでしょうか。
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));
}
またはnull拡張子がサポートされている場合:
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の結果:
パス:/ root/docs /
名前:readme
拡張子:txt
windowsの場合、parsePath( "c:\ windows\readme.txt"):
パス:c:\ windows \
名前:readme
拡張子:txt
ファイル名からファイル拡張子を取得する
/**
* 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);
}
クレジット
ライブラリを使用しなくても、Stringメソッドsplitを次のように使用できます。
String[] splits = fileNames.get(i).split("\\.");
String extension = "";
if(splits.length >= 2)
{
extension = splits[splits.length-1];
}
String extension = com.google.common.io.Files.getFileExtension("fileName.jpg");
ここで私は小さな方法を作りました(しかしそれほど安全ではなく、多くのエラーをチェックしません)が、一般的なJavaプログラムをプログラミングしているのがあなただけであれば、これはファイルタイプを見つけるのに十分すぎるほどです。これは複雑なファイルタイプに対しては機能しませんが、通常はそれほど使用されません。
public static String getFileType(String path){
String fileType = null;
fileType = path.substring(path.indexOf('.',path.lastIndexOf('/'))+1).toUpperCase();
return fileType;
}
この特定の質問は私に多くの悩みを与え、それから私は私がここに投稿しているこの問題に対する非常に簡単な解決策を見つけました。
file.getName().toLowerCase().endsWith(".txt");
それでおしまい。
単なる正規表現ベースの選択肢です。それほど速くはない、それほど良くない。
Pattern pattern = Pattern.compile("\\.([^.]*)$");
Matcher matcher = pattern.matcher(fileName);
if (matcher.find()) {
String ext = matcher.group(1);
}
spectre's answer の単純さが好きで、彼のコメントの1つにリンクされているのは、ファイルパス内のドットを修正する別の回答へのリンク、 EboMikeによって作成された です。
ある種のサードパーティAPIを実装せずに、私はお勧めします:
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
}
ImageIOのwrite
メソッドのいずれか でファイル形式を渡す必要がある場合などに、このようなことが役に立ちます。
あなたがDIYすることができるのになぜ全体の第三者APIを使うのですか?
上記のすべての答えを組み合わせて拡張機能を見つけるためのより良い方法を見つけました
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));
}