जावा: फ़ाइल नाम को एक आधार और विस्तार में विभाजित करना


83

फ़ाइल बेसनेम और एक्सटेंशन प्राप्त करने का एक बेहतर तरीका है जैसे कुछ

File f = ...
String name = f.getName();
int dot = name.lastIndexOf('.');
String base = (dot == -1) ? name : name.substring(0, dot);
String extension = (dot == -1) ? "" : name.substring(dot+1);

7
कॉमन्स- io पर एक नज़र डालें FilenameUtils। इसके getBaseName(..)और getExtension(..)तरीके हैं।
बूझो

के लिए केवल विस्तार, देख stackoverflow.com/questions/3571223/...
एंडी थॉमस

जवाबों:


168

मुझे पता है कि अन्य लोगों ने उल्लेख किया है String.split, लेकिन यहां एक संस्करण है जो केवल दो टोकन (आधार और विस्तार) देता है:

String[] tokens = fileName.split("\\.(?=[^\\.]+$)");

उदाहरण के लिए:

"test.cool.awesome.txt".split("\\.(?=[^\\.]+$)");

पैदावार:

["test.cool.awesome", "txt"]

नियमित अभिव्यक्ति जावा को किसी भी अवधि पर विभाजित करने के लिए कहती है, जिसके बाद किसी भी गैर-अवधि के बाद इनपुट की समाप्ति होती है। केवल एक अवधि है जो इस परिभाषा से मेल खाती है (अर्थात्, अंतिम अवधि)।

तकनीकी रूप से रेगेक्सिक रूप से, इस तकनीक को शून्य-चौड़ाई सकारात्मक लुकहेड कहा जाता है


BTW, यदि आप एक पथ को विभाजित करना चाहते हैं और पूर्ण फ़ाइल नाम प्राप्त करना चाहते हैं, लेकिन डॉट एक्सटेंशन तक सीमित नहीं है, तो स्लैश के साथ पथ का उपयोग करते हुए,

    String[] tokens = dir.split(".+?/(?=[^/]+$)");

उदाहरण के लिए:

    String dir = "/foo/bar/bam/boozled"; 
    String[] tokens = dir.split(".+?/(?=[^/]+$)");
    // [ "/foo/bar/bam/" "boozled" ] 

2
मुझे पता नहीं है कि लोग निर्भरता से क्यों डरते हैं ;-)
Bozho

3
@Bozho: मैं मानता हूं कि इस प्रकार की समस्या के लिए पुस्तकालय बेहतर समाधान हैं। यह अन्य लोगों को आपके लिए बनाए रखने और सोचने देता है (यही कारण है कि मैंने आपके जवाब को वोट दिया है!)। यह तुच्छ लग सकता है, लेकिन मेरा एक हिस्सा है जो हमेशा अपाचे पुस्तकालय सहित विचार करने पर हिचकिचाता है क्योंकि मुझे अतीत में उनके कुछ सामान के साथ "जार नरक" का सामना करना पड़ा है (मुझे पता है, यह तुच्छ है)।
एडम पेन्न्टर

4
@ बोजो: एडम का 100% सही है। यह मुद्दा मुझे अभी तक किसी अन्य पुस्तकालय में ले जाने के लिए पर्याप्त नहीं होगा - लेकिन अगर मैं पहले से ही अन्य कारणों के लिए कॉमन्स-आईओआई का उपयोग कर रहा था, तो मैं फाइलनेमुटिल्स का उपयोग करूंगा।
जेसन एस

1
@ जेसन: नियमित अभिव्यक्ति: उपहार जो देता रहता है। :)
एडम पेन्न्टर

3
@Bozho - सरकस्म? असली सवाल यह है कि जावा निरर्थक वर्गों के अंतहीन ढेरों के साथ आता है जो इतने करीब आते हैं कि यह करना आसान है कि आप वास्तव में क्या करना चाहते हैं, लेकिन तब निराशा वास्तव में कभी नहीं करती है। पाइथन में अपाचे-कॉमन्स के बराबर नहीं है क्योंकि पायथन में आपके द्वारा निर्मित सभी उपयोगी सामान हैं। सी # एक ऐसी भाषा का एक और उदाहरण प्रतीत होता है, जहाँ आप अपनी अनूठी समस्या पर ध्यान केंद्रित करने के बजाय यह जान सकते हैं कि पहिया को कैसे सुदृढ़ करना है या उस पहिये को प्राप्त करना है जिसका आविष्कार किसी और ने किया है।
आर्टऑफवर्फ

84

पुराना प्रश्न लेकिन मैं आमतौर पर इस समाधान का उपयोग करता हूं:

import org.apache.commons.io.FilenameUtils;

String fileName = "/abc/defg/file.txt";

String basename = FilenameUtils.getBaseName(fileName);
String extension = FilenameUtils.getExtension(fileName);
System.out.println(basename); // file
System.out.println(extension); // txt (NOT ".txt" !)

अगर विंडोज़ में काम नहीं करता है और स्ट्रिंग "फाइलनेम" "D: \ resource \ ftp_upload.csv" है, तो क्या आप मदद कर सकते हैं?
NIKHIL CHAURASIA

3
@NIKHILCHAURASIA आपको बैकस्लैश से बचकर, उन्हें दोगुना करने की आवश्यकता है। जैसे: "D: \\ resource \\ ftp_upload.csv"।
Ricket

8

स्रोत: http://www.java2s.com/Code/Java/File-Input-Output/Getextensionpathandfilename.htm

ऐसी उपयोगिता वर्ग:

class Filename {
  private String fullPath;
  private char pathSeparator, extensionSeparator;

  public Filename(String str, char sep, char ext) {
    fullPath = str;
    pathSeparator = sep;
    extensionSeparator = ext;
  }

  public String extension() {
    int dot = fullPath.lastIndexOf(extensionSeparator);
    return fullPath.substring(dot + 1);
  }

  public String filename() { // gets filename without extension
    int dot = fullPath.lastIndexOf(extensionSeparator);
    int sep = fullPath.lastIndexOf(pathSeparator);
    return fullPath.substring(sep + 1, dot);
  }

  public String path() {
    int sep = fullPath.lastIndexOf(pathSeparator);
    return fullPath.substring(0, sep);
  }
}

उपयोग:

public class FilenameDemo {
  public static void main(String[] args) {
    final String FPATH = "/home/mem/index.html";
    Filename myHomePage = new Filename(FPATH, '/', '.');
    System.out.println("Extension = " + myHomePage.extension());
    System.out.println("Filename = " + myHomePage.filename());
    System.out.println("Path = " + myHomePage.path());
  }
}

4
basename()इसके बजाय एक बेहतर नाम होगाfilename()
nimcap

यदि कोई एक्सटेंशन नहीं है (उदाहरण के लिए "/ etc / मेजबान" जैसे फ़ाइल नाम) तो यह "मेजबानों" को एक्सटेंशन ("") के बजाय वापस लौटा देगा। लाइब्रेरी-ग्रेड उपयोगिता कक्षाओं को कोने के मामलों का ध्यान रखना चाहिए।
जैच-एम

6

http://docs.oracle.com/javase/6/docs/api/java/io/File.html#getName ()

से http://www.xinotes.org/notes/note/774/ :

जावा में दिए गए फ़ाइल पथ के लिए बेसनेम और डीरनेम प्राप्त करने के लिए अंतर्निहित फ़ंक्शन हैं, लेकिन फ़ंक्शन नाम इतने स्व-स्पष्ट नहीं हैं।

import java.io.File;

public class JavaFileDirNameBaseName {
    public static void main(String[] args) {
    File theFile = new File("../foo/bar/baz.txt");
    System.out.println("Dirname: " + theFile.getParent());
    System.out.println("Basename: " + theFile.getName());
    }
}

5
java.io.File.getName () एक्सटेंशन के साथ नाम लौटाता है।
ब्रैम

2
मैं यह सोचना पसंद करता हूं कि "एक्सटेंशन" जैसी कोई चीज नहीं है :-)

4

फ़ाइल एक्सटेंशन एक टूटी हुई अवधारणा है

और इसके लिए कोई विश्वसनीय कार्य मौजूद नहीं है। उदाहरण के लिए इस फ़ाइलनाम पर विचार करें:

archive.tar.gz

विस्तार क्या है ? DOS उपयोगकर्ता नाम पसंद करते होंगे archive.tgz। कभी-कभी आप बेवकूफ विंडोज एप्लिकेशन देखते हैं जो पहले फाइल को डिकम्प्रेस करते हैं (फाइल की उपज .tar), फिर आपको संग्रह सामग्री को देखने के लिए इसे फिर से खोलना होगा।

इस मामले में, फ़ाइल एक्सटेंशन की एक अधिक उचित धारणा होगी .tar.gz। भी कर रहे हैं .tar.bz2, .tar.xz, .tar.lzऔर .tar.lzmaउपयोग में फ़ाइल "एक्सटेंशन"। लेकिन आप यह कैसे तय करेंगे, कि अंतिम बिंदु पर विभाजन करना है या दूसरे-से-अंतिम बिंदु पर?

इसके बजाय माइम-प्रकार का उपयोग करें।

जावा 7 फ़ंक्शन Files.probeContentType फ़ाइल एक्सटेंशन पर भरोसा करने की तुलना में फ़ाइल प्रकारों का पता लगाने के लिए बहुत अधिक विश्वसनीय होगा। बहुत अधिक सभी यूनिक्स / लिनक्स दुनिया के साथ-साथ आपके वेबब्रोसर और स्मार्टफोन पहले से ही इस तरह से करते हैं।


6
यह प्रश्न का उत्तर कैसे देता है? न तो Fileहै और न ही Pathमुझे विस्तार अलग हो गई हैं।
एंड्रियास एबेल

@ andreas.abel मुझे यह दोहराने देता है: फ़ाइल एक्सटेंशन एक टूटी हुई अवधारणा हैं। वे विश्वसनीय नहीं, और न ही डॉस 8 + 3 फ़ाइल नाम को छोड़कर अच्छी तरह से परिभाषित कर रहे हैं (पर विचार .tar.gzबनाम .tgzयूनिक्स पर सब भी आम)। इसके बजाय माइम प्रकार का उपयोग करें।
QUIT है - Anony-Mousse

1
@ Anony-Mousse खैर, मैं सिद्धांत रूप में सहमत हूं, लेकिन सभी प्रणालियों के 99,999% मैं एक फ़ाइल नाम के उपयोग के साथ बातचीत करता हूं, न कि एक माइम प्रकार
क्रिश्चियन सॉयर

Files.probeContentTypeसही एक्सटेंशन होने के लिए फ़ाइल नाम पर निर्भर होने के बजाय उपयोग करने में समस्या कहां है ?
QUIT - एनी-मूस

3
इस सवाल का जवाब नहीं है। मेरे पास एक उपयोग-मामला है जहां फ़ाइल-नाम, एक फिल्म, एक नाम + एक्सटेंशन है। मैं माइम-प्रकारों का उपयोग करके नाम कैसे निकालूंगा?
नीक

1

आपके कोड में क्या गलत है? एक साफ उपयोगिता विधि में लिपटे यह ठीक है।

विभाजक के रूप में उपयोग करने के लिए क्या अधिक महत्वपूर्ण है - पहला या अंतिम बिंदु। पहला फ़ाइल नाम जैसे "सेटअप-2.5.1.exe" के लिए बुरा है, अंतिम "mybundle.tar.gz" जैसे कई एक्सटेंशन वाले फ़ाइल नामों के लिए बुरा है।



-3

शायद आप स्ट्रिंग # विभाजन का उपयोग कर सकते हैं

आपकी टिप्पणी का जवाब देने के लिए:

मुझे यकीन नहीं है कि एक से अधिक हो सकते हैं। एक फ़ाइल नाम में, लेकिन जो भी हो, भले ही अधिक डॉट्स हों आप विभाजन का उपयोग कर सकते हैं। उदाहरण पर विचार करें:

String input = "boo.and.foo";

String[] result = input.split(".");

इससे युक्त एक सरणी वापस आ जाएगी:

{ "boo", "and", "foo" }

तो आपको पता चल जाएगा कि सरणी में अंतिम सूचकांक विस्तार है और अन्य सभी आधार हैं।


ठीक है, हाँ, लेकिन मुझे .एक स्ट्रिंग में आखिरी के लिए एक रेगेक्स का पता लगाना होगा
जेसन एस

1
हम्म मुझे यकीन नहीं है, लेकिन क्या आप सिर्फ "" का उपयोग नहीं कर सकते? या फ़ाइल नाम में 1 से अधिक बिंदु हैं?

2
मुझे लगता है कि यह काम करेगा:fileName.split("\\.(?=[^\\.]+$)")
एडम पेन्न्टर

1
आप यह नहीं मान सकते कि केवल एक बिंदु है। एडम: धन्यवाद, मैं यह कोशिश करूँगा।
जेसन एस

4
यह उत्तर गलत है। क्योंकि डॉट को नहीं छोड़ा गया है, यह एक खाली सरणी लौटाएगा।
Aled
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.