24

How do I remove the file name from a URL or String?

String os = System.getProperty("os.name").toLowerCase();
        String nativeDir = Game.class.getProtectionDomain().getCodeSource().getLocation().getFile().toString();

        //Remove the <name>.jar from the string
        if(nativeDir.endsWith(".jar"))
            nativeDir = nativeDir.substring(0, nativeDir.lastIndexOf("/"));

        //Load the right native files
        for(File f : (new File(nativeDir + File.separator + "lib" + File.separator + "native")).listFiles()){
            if(f.isDirectory() && os.contains(f.getName().toLowerCase())){
                System.setProperty("org.lwjgl.librarypath", f.getAbsolutePath()); break;
            }
        }

That's what I have right now, and it work. From what I know, because I use "/" it will only work for windows. I want to make it platform independent

Not a bug
  • 4,109
  • 1
  • 35
  • 68
Yemto
  • 443
  • 1
  • 4
  • 17

9 Answers9

25

Consider using org.apache.commons.io.FilenameUtils

You can extract the base path, file name, extensions etc with any flavor of file separator:

String url = "C:\\windows\\system32\\cmd.exe";

String baseUrl = FilenameUtils.getPath(url);
String myFile = FilenameUtils.getBaseName(url)
                + "." + FilenameUtils.getExtension(url);

System.out.println(baseUrl);
System.out.println(myFile);

Gives,

windows\system32\
cmd.exe

With url; String url = "C:/windows/system32/cmd.exe";

It would give;

windows/system32/
cmd.exe
PopoFibo
  • 8,281
  • 2
  • 29
  • 47
14

You are using File.separator in another line. Why not using it also for your lastIndexOf()?

nativeDir = nativeDir.substring(0, nativeDir.lastIndexOf(File.separator));
Dirk Fauth
  • 3,538
  • 2
  • 10
  • 22
  • Because It returns the wrong thing for my system. But it don't seam to care if it becomes C:\something\something\something/something – Yemto Feb 17 '14 at 12:46
  • The File.separator is returning the file separator dependent to your system. So on Windows you will get "\" while on Unix you get "/". That's why you should use the File.separator. – Dirk Fauth Feb 17 '14 at 12:50
  • `Game.class.getProtectionDomain().getCodeSource().getLocation().getFile().toString()` returns **D:/Dropbox/NetBeansProjects/** while `System.out.println(File.separator)` returns \ so that's wrong. I have windows 7 64bit – Yemto Feb 17 '14 at 13:40
  • Well if that method always returns "/" you might want to perform a replacement first to ensure the same state in any case. String.replace() might help – Dirk Fauth Feb 18 '14 at 13:24
  • Notice that in order to get the **filename**, expression should be something like `nativeDir.substring(nativeDir.lastIndexOf(File.separator) + 1)` (so the substring *from* the separator, *to* the end). – rsenna Nov 25 '19 at 14:38
14

By utilizing java.nio.file; (afaik introduced after J2SE 1.7) this simply solved my problem:

Path path = Paths.get(fileNameWithFullPath);
String directory = path.getParent().toString();
saygley
  • 301
  • 5
  • 11
  • 2
    Doesn't work well for HTTP URLs, which wasn't specifically mentioned in the question, but might be of interest to some browsing these answers. – Nate Jan 04 '19 at 04:40
3

The standard library can handle this as of Java 7

Path pathOnly;

if (file.getNameCount() > 0) {
  pathOnly = file.subpath(0, file.getNameCount() - 1);
} else {
  pathOnly = file;
}

fileFunction.accept(pathOnly, file.getFileName());
Andrew
  • 3,330
  • 1
  • 33
  • 53
Jeremy Sigrist
  • 321
  • 2
  • 11
  • 1
    path.getNameCount() documentation says: "the number of elements in the path, or 0 if this path only represents a root component" This could cause issues... – Andrew Jul 13 '17 at 19:53
2
File file = new File(path);
String pathWithoutFileName = file.getParent();

where path could be "C:\Users\userName\Desktop\file.txt"

0

Instead of "/", use File.separator. It is either / or \, depending on the platform. If this is not solving your issue, then use FileSystem.getSeparator(): you can pass different filesystems, instead of the default.

Chthonic Project
  • 7,687
  • 1
  • 39
  • 85
  • 1
    I would. But File.separator return a "\" while nativeDir uses "/" – Yemto Feb 17 '14 at 12:38
  • Then shouldn't something like this work? `if(nativeDir.endsWith(".jar")){ int index = Math.max(nativeDir.lastIndexOf("/"), nativeDir.lastIndexOf("\\")); nativeDir = nativeDir.substring(0, index); }` – Yemto Feb 17 '14 at 12:43
  • Added more info. That should resolve the difference with native dir. – Chthonic Project Feb 17 '14 at 12:49
0

I solve this problem using regex.

For windows:

String path = "";
String filename = "d:\\folder1\\subfolder11\\file.ext";
String regEx4Win = "\\\\(?=[^\\\\]+$)";
String[] tokens = filename.split(regEx4Win);
if (tokens.length > 0)
   path = tokens[0]; // path -> d:\folder1\subfolder11
0

Please try below code:

file.getPath().replace(file.getName(), "");
Shalu T D
  • 3,373
  • 2
  • 21
  • 32
Amin Arab
  • 502
  • 4
  • 16
0

Kotlin solution:

val file = File( "/folder1/folder2/folder3/readme.txt")
val pathOnly = file.absolutePath.substringBeforeLast( File.separator )
println( pathOnly )

produces this result:

/folder1/folder2/folder3

Interkot
  • 477
  • 7
  • 9