Creating file and intermediate directories if does not exist - java

I want to create a file if and only if that file does not exist.
As an example file location is referring to "C:\user\Desktop\dir1\dir2\filename.txt"
if (!file.exists()) {
try {
file.createNewFile();
} catch(IOException ioe) {
ioe.printStackTrace();
return;
}
}
Unfortunately the above code is failing, as the dir1 and dir2 does not exist.
For my case
Sometime the dir1 and dir2 may exist and sometime they may not exist.
I do not want to overwrite the contents of these intermediate directories if they already exists,
How to check this cleanly?
I was thinking to add the following check to handle this condition:
if (!file.getParentFile().getParentFile().exists()) {
file.getParentFile().getParentFile().mkdirs();
}
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
if (!file.exists()) {
try {
file.createNewFile();
} catch(IOException ioe) {
ioe.printStackTrace();
return;
}
}
Or there is a clearer solution than this?

you can do something of this sort:
file.getParentFile().mkdirs();
Creates the directory named by this abstract pathname, including any necessary but nonexistent parent directories. Note that if this operation fails it may have succeeded in creating some of the necessary parent directories.
Update
if (file.getParentFile().exists || file.getParentFile().mkdirs()){
try
{
file.createNewFile();
}
catch(IOException ioe)
{
ioe.printStackTrace();
return;
}
} else {
/** could not create directory and|or all|some nonexistent parent directories **/
}

Beware that File.exists() checks for the existence of a file or directory.
Instead of:
if(!file.exists()) {
try {
file.createNewFile();
} catch(IOException ioe) {
ioe.printStackTrace();
return;
}
}
You should explicitly check if the file is a file as there may be a directory of the same name:
if(!file.isFile()) {
try {
file.createNewFile();
} catch(IOException ioe) {
ioe.printStackTrace();
return;
}
}
Similarly, you should check that the parent file is a directory:
if (!file.getParentFile().getParentFile().isDirectory()) { ... }

Related

How to place a file for jar and read it with FileInputStream

This is the code
public static void readCharacters() {
try (FileInputStream fi = new FileInputStream("main/characters.dat"); ObjectInputStream os = new ObjectInputStream(fi)) {
characterList = (LinkedList<Character>) os.readObject();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
This is the structure:
And this is the Error
java.io.FileNotFoundException: main\characters.dat (The system cannot find the path specified)
What I want is to include the characters.dat file in my jar, and be able to read and write it while the program runs. Is there a different way to write the path? or to put the .dat file in a different position.
Also the writing method:
public static void writeCharacters() {
try (FileOutputStream fs = new FileOutputStream("main/characters.dat"); ObjectOutputStream os = new ObjectOutputStream(fs)) {
System.out.println("Writing Characters...");
os.writeObject(characterList);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
You can't. You can do one or the other. JAR files are not file systems, and their entries are not files. You can read it with an input stream:
InputStream in = this.getClass().getResourceAsStream("/main/characters.dat");
Check it for null before proceeding.
The jar is for read-only resources. You can use it for the initial file, as a kind of template.
Path path = Paths.get(System.getProperty("user.home") + "/myapp/chars.dat");
Files.mkdirs(path.getParentPath());
if (!Files.exists()) {
try (InputStream in =
Controller.class.getResourceAsStream("/main/characters.dat")) {
Files.copy(in, path);
}
}
The above copies the initial.dat resource from the jar to the user's home "myapp" directory, which is a common solution.
System.getProperty("user.dir") would the running directory. One can also take the jar's path:
URL url = Controller.class.getResource("/main/characters.dat");
String s = url.toExternalForm(); // "jar:file:/.... /xxx.jar!/main/characters.dat"
From that you can also construct the jar's directory. Mind to check Windows, Linux, spaces and such.
URL url = Controller.class.getProtectionDomain().getCodeSource().getLocation();
The solution above risks a NullPointerException, and works a bit differenly running inside the IDE or stand-alone.
Important note:
When using getResourceAsStream, you must start your path by slash /, this specifies the root of your jar, .getResourceAsStream("/file.txt");
In my case my file was a function argument, String filename, I had to do it like this:
InputStream in = this.getClass().getResourceAsStream("/" + filename);

OutputStreamWriter contains a path separator

Today i tested "files" instead of a normal path.
Here is my code:
File path=new File(getFilesDir(),"uf");
File test = new File(path.getAbsolutePath(),"test.txt");
if(!path.exists()){
path.mkdir();
}
if(!test.isFile()){
try {
test.createNewFile();
} catch (IOException e) {
//TODO in errorlog -> filecreation
e.printStackTrace();
}
}else{
try {
OutputStreamWriter mywriter = new OutputStreamWriter(openFileOutput(test.getAbsolutePath().toString(),Context.M ODE_PRIVATE));
mywriter.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
In the error code comes everytime: illegal Arguments: contains a path seperator!
Thank you for your help in advance
Maybe add more info about your error. But...
This error is about that you are trying to full path (include you subdirectories) to access to private data area.
Solution is use FileOutputStream, more here. And use
new File(YOUR_FILE)
to create your file.
Keep on mind that you should call method mkDirs() to create all necessary directories and subdirectories. More about mkDirs() here
Note: There is also method mkDir(), here is doc. This one will create a single directory.

How to check a file is shortcut file?

Following code fails to check the shortcut file. code source
Suppose there is file sdcard/1234567.mp3 which is not shortcut file even the absolute and canonical paths are different.
public static boolean isShortcutFile(File file) {
try {
if (!file.exists()) {
return true;
} else {
return !file.getAbsolutePath().equals(file.getCanonicalPath());
}
} catch (IOException ex) {
System.err.println(ex);
return true;
}
}
Alternate way what i tried is checking the extension of a file is .lnk will it work for all case?

Text document is becoming file folder

Here is my class, what I am doing wrong. Why is my text document becoming a file folder. Please explain what is going on and how I can correct it. Thank you
public class InputOutput {
public static void main(String[] args) {
File file = new File("C:/Users/CrypticDev/Desktop/File/Text.txt");
Scanner input = null;
if (file.exists()) {
try {
PrintWriter pw = new PrintWriter(file);
pw.println("Some data that we have stored");
pw.println("Another data that we stored");
pw.close();
} catch(FileNotFoundException e) {
System.out.println("Error " + e.toString());
}
} else {
file.mkdirs();
}
try {
input = new Scanner(file);
while(input.hasNext()) {
System.out.println(input.nextLine());
}
} catch(FileNotFoundException e) {
System.out.println("Error " + e.toString());
} finally {
if (input != null) {
input.close();
}
}
System.out.println(file.exists());
System.out.println(file.length());
System.out.println(file.canRead());
System.out.println(file.canWrite());
System.out.println(file.isFile());
System.out.println(file.isDirectory());
}
}
Thanks. The above is my Java class.
You mistakingly assume Text.txt is not a directory name.
mkdirs() creates a directory (and all directories needed to create it). In your case 'Text.txt'
See here: https://docs.oracle.com/javase/7/docs/api/java/io/File.html#mkdirs().
It is perfectly fine for a directory to have a . in it.
You could use getParentFile() to get the directory you want to create and use mkdirs() on that.
For additional informations. Here is the différence between the two representaions of files and directories:
final File file1 = new File("H:/Test/Text.txt"); // Creates NO File/Directory
file1.mkdirs(); // Creates directory named "Text.txt" and its parent directory "H:/Test" if it doesn't exist (may fail regarding to permissions on folders).
final File file = new File("H:/Test2/Text.txt"); // Creates NO File/Directory
try {
file.createNewFile(); // Creates file named "Text.txt" (if doesn't exist) in the folder "H:/Test2". If parents don't exist, no file is created.
} catch (IOException e) {
e.printStackTrace();
}
Replace your code:
else {
file.mkdirs();
}
with:
else {
if (!file.isFile()&&file.getParentFile().mkdirs()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Awkward result while reading file containing spaces in pathname using getResource() in java

I have a project named Downloader containing files like this:
Downloader
-->src
-->Downloader
-->DownLoader.java
-->AudioLinks
I have tried to access AudioLinks from Downloader.java by the following function.
public void readFile()
{
{
File file=new File(this.getClass().getResource("AudioLinks").getFile());
if(file.exists())
{
System.out.println(file+" Exists");
}
else
{
System.out.println(file+" Doesn't exist");
}
}
}
It returned the following:
E:\Project%20Eclipse\Workspace\Downloader\bin\Downloader\AudioLinks Doesn't exist
But if I edit the function like this(replace "%20" by a " "):
public void readFile()
{
{
File file=new File(this.getClass().getResource("AudioLinks").getFile().replaceAll("%20", " "));
if(file.exists())
{
System.out.println(file+" Exists");
}
else
{
System.out.println(file+" Doesn't exist");
}
}
}
It returns:
E:\Project Eclipse\Workspace\Downloader\bin\Downloader\AudioLinks Exists
The problem is that if I export my program to runnable jar it gives "Doesn't exist" in both cases. Could anyone please explain these occurances?
peeskillet wrote in his comment:
Don't read it as a File. Read it as a URL through just the getResource(). Get rid of the File wrapper (or an an InputStream through getResourceAsStream, depending on the type required)
So, I've edited the function like this and found no error:
public void readFile()
{
{
BufferedReader reader=new BufferedReader(new InputStreamReader(this.getClass().getResourceAsStream("AudioLinks")));
String text;
try {
while((text=reader.readLine())!=null)
{
System.out.println(text);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Categories