Add a file name to a Path object - java

I have a Path object leading to a folder.
Path pathToFolder = Paths.get( "/Users/someuser/" );
…or the recommended way using Path.of:
Path pathToFolder = Path.of( "/Users/someuser/" );
I want to create a file named "whatever.text" in that folder using Files.newBufferedWriter where I pass a Path object.
BufferedWriter writer = Files.newBufferedWriter( pathToFile ) ;
How do I transform my pathToFolder to get a Path object pathToFile?
I need more than mere string manipulation, as these are soft-coded values determined at runtime. And I am trying to be cross-platform as well.
This seems like an obvious question, but I could not find any existing post (the terminology does make searching tricky).

You are looking for Path.resolve():
Converts a given path string to a Path and resolves it against this Path in exactly the manner specified by the resolve method. For example, suppose that the name separator is "/" and a path represents "foo/bar", then invoking this method with the path string "gus" will result in the Path "foo/bar/gus".
So you should use this:
Path pathToFolder = Path.of("/Users/someuser/");
Path pathToFile = pathToFolder.resolve("your-file-name");
BufferedWriter writer = Files.newBufferedWriter(pathToFile);

Related

`java.nio.file.Path`- necessary to `path = Files.createDirectories(path)`?

Talking about the Java java.nio.file.Path and associated utilities.
As the title suggests, is it really necessary for one to set the path they just created?
I.E,
Path path = Path.of("some", "dir");
path = Files.createDirectories(path);
//continue to use path variable
vs
Path path = Path.of("some", "dir");
Files.createDirectories(path);
//continue to use path variable
Is the second example adequate, or are there actually changes made that are relevant/ required that are returned in the Path object in createDirectories?

Getting an element inside a directory using java.nio.file.Path's

I am currently getting to grips with file management in Java. As far as i've read, java.nio.file.Path is the preferred way of doing so.
Say I want to copy the contents of oldDir to the, currently empty, newDir. Every time I copy a file, I need this loong line just to get the Path of newFile:
Path newDir = FileSystems.getDefault().getPath("new");
Path oldDir = FileSystems.getDefault().getPath("old");
for (Path oldFile : oldDir) {
Path newFile = FileSystems.getDefault().getPath("new", oldFile.getFileName().toString()); // Why so complicated? :(
Files.copy(oldFile, newFile);
}
Is there something like newDir.getChild(oldFile.getFileName()) to do what I want, or is there really no shorter way of doing it?
There are a couple things you can do to make the code simpler:
Use Path#of(String,String...) or Paths#get(String,String...) to create your Path instances. Both methods delegate to the default FileSystem. The former was added in Java 11 and is now the preferred approach.
Use Path#resolve(Path) to append a relative path to some absolute path.
But there's also an error in your code. You are iterating over oldDir which works because Path implements Iterable<Path>. However, that iterates over the names of the path, not the children of the path. In other words, this:
Path path = Path.of("foo", "bar", "file.txt");
for (Path name : path) {
System.out.println(name);
}
Will output:
foo
bar
file.txt
If you want to iterate over the children of a directory you need to use something like Files#list(Path) or Files#newDirectoryStream(Path) (the latter has two overloads). Both those methods only return the immediate children of the directory. There are other methods available to recursively iterate a directory and its sub-directories; browse the Files documentation to see what's provided.
So your code should instead look something like:
Path oldDir = Path.of(...);
Path newDir = Path.of(...);
try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(oldDir)) {
for (Path oldFile : dirStream) {
Path newFile = newDir.resolve(oldFile.getFileName());
Files.copy(oldFile, newFile);
}
}

Java: Including folder path in the file name for a File object

I am trying to output an object to a file, and the code below works fine.
val myFile = new File(myPath + "_" + myFileName)
val myData = new ObjectOutputStream(new FileOutputStream(myFile))
However, if I want to make myFileName under myPath like:
val myFile = new File(myPath + "/" + myFileName)
val myData = new ObjectOutputStream(new FileOutputStream(myFile))
I got java.io.FileNotFoundException.
Any idea what I might have missed? Thank you!
If folder myPath does not exists the FileNotFoundException will be thrown. You have to create that folder first. You may do it manually or by mkdir() method from File class.
This error is definitely due to missing folder referenced by "mypath" or myFileName.
JDK7 has nice abstraction for path in which you don't have to worry about path separator character (i.e /)
Use Paths
for eg
Path p = Paths.get("c:", myPath ,myFileName)
You can extract file object from path and do whether path exists before starting any processing.

How to name File objects and their corresponding path strings in Java

Often times, I find myself creating two objects like these:
String pathString = "/foo/bar";
File path = new File(pathString);
Though variable naming is a fairly subjective issue, what's the most common naming convention for File objects and their corresponding absolute file path stored in a String?
I guess there is no naming convention. I would either take a look at the constructor argument of File and name it after that, e.g.
String pathname = "/foo/bar";
File file = new File(pathname);
Normally the file has a meaning in your application. So I would choose a name that describes it. E.g.
String errorLogFilepath = "/var/log/error.log";
File errorLogFile = new File(errorLogFilepath);
Do you need to idependently identify the path?
If not, Id suggest just using:
File path = new File("/foo/bar");
Similarly, pass around File objects, not string paths.
If you are not reusing this path for further reference in the code , suggest you to initialize the file by passing an arguement. eg
File file = new File("/foo/bar");
This will prevent the creation of an extra string variable.
I always use double backslash and I've never have problem with that:
File outputfile = new File("c:\\Selenium\\workspace\\....\\input.txt");

File.mkdir is not working and I can't understand why

I've this brief snippet:
String target = baseFolder.toString() + entryName;
target = target.substring(0, target.length() - 1);
File targetdir = new File(target);
if (!targetdir.mkdirs()) {
throw new Exception("Errore nell'estrazione del file zip");
}
doesn't mattere if I leave the last char (that is usually a slash). It's done this way to work on both unix and windows. The path is actually obtained from the URI of the base folder. As you can see from baseFolder.toString() (baseFolder is of type URI and is correct). The base folder actually exists. I can't debug this because all I get is true or false from mkdir, no other explanations.The weird thing is that baseFolder is created as well with mkdir and in that case it works.
Now I'm under windows.
the value of target just before the creation of targetdir is "file:/C:/Users/dario/jCommesse/jCommesseDB"
if I cut and paste it (without the last entry) in windows explore it works...
The path you provide is not a file path, but a URI.
I suggest you try the following :
URI uri = new URI("file://c:/foo/bar");
File f = new File(uri).
It looks, to me, as if the "file:/" at the beginning is the problem... Try getAbsolutePath() instead of toString().
The File constructor taking a String expects a path name. A path name is not an URI.
Remove the file:/ from the front of the String (or better yet, use getPath() instead of toString()) to get to the path you need.

Categories

Resources