0

I have this Java class

    package com.cf.utils;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.UUID;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;

import com.cf.CoreFaction;
import com.cf.faction.Faction;

import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.relauncher.Side;

public class FactionUtils {

    public static boolean saveFaction(Faction f) {
        if (Utils.isServer()) {
            JSONObject obj = new JSONObject();
            obj.put("Name", f.getName());
            obj.put("Owner", f.getOwner().toString());

            JSONArray members = new JSONArray();
            for (UUID u : f.getMembers()) {
                members.add(u.toString());
            }

            obj.put("Members", members);

            File dir = new File(DimensionManager.getCurrentSaveRootDirectory() + "/factions");
            if (!dir.exists())
                dir.mkdirs();

            try (FileWriter file = new FileWriter(
                    DimensionManager.getCurrentSaveRootDirectory() + "/factions/" + f.getName() + ".json")) {
                file.write(obj.toJSONString());
                file.close();
                return true;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    public static void deleteFaction(Faction f) {
        if (Utils.isServer()) {
            File file = new File(DimensionManager.getCurrentSaveRootDirectory() + "/factions/" + f.getName() + ".json");
            if (file.exists()) {
                if(file.delete()) { //THIS RETURNS FALSE
                    for (UUID p : f.getMembers()) {
                        Utils.sendMessage(p, Utils.getTranslation("faction.disbanded", TextFormatting.RED));
                    }
                } else
                    Utils.sendMessage(f.getOwner(), Utils.getTranslation("faction.disband.error", TextFormatting.RED));

            } else
                System.out.println("Can't find the file");
        }
    }

    public static Faction getFaction(UUID player) {
        for (Faction f : getAllFactions()) {
            if (f.getMembers().contains(player))
                return f;
        }
        return null;
    }

    public static Faction getFaction(String name) {
        for (Faction f : getAllFactions()) {
            if (f.getName().equalsIgnoreCase(name))
                return f;
        }
        return null;
    }

    public static ArrayList<Faction> getAllFactions() {
        ArrayList<Faction> list = new ArrayList<Faction>();
        if (Utils.isServer()) {
            File dir = new File(DimensionManager.getCurrentSaveRootDirectory() + "/factions");
            if (!dir.exists())
                return list;
            File[] factions = dir.listFiles();
            for (File f : factions) {
                JSONParser parser = new JSONParser();

                try {
                    Object obj = parser.parse(new FileReader(f));
                    JSONObject jsonObject = (JSONObject) obj;

                    JSONArray members = (JSONArray) jsonObject.get("Members");
                    Faction faction = new Faction((String) jsonObject.get("Name"),
                            UUID.fromString((String) jsonObject.get("Owner")));
                    ArrayList<UUID> ids = new ArrayList<UUID>();
                    for (int i = 0; i < members.size(); i++) {
                        ids.add(UUID.fromString(members.get(i).toString()));
                    }
                    faction.setMembers(ids);
                    list.add(faction);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return list;
    }
}

When i call the method deleteFaction i want to delete a specific file, but despite the file.exists() returns true, the file.delete() returns false and i can't figure out why. So why the file i'm pointing cannot be deleted?

Jimi
  • 1,285
  • 1
  • 12
  • 27
  • 1
    Have you checked whether you have permission to delete the file, according to the operating system? – Andy Thomas Jun 01 '17 at 18:57
  • 1
    The file might be in use by another process. If that's the case then you can't delete it until the process 'dies'. – cdaiga Jun 01 '17 at 18:58
  • 1
    Returning `false` instead of throwing proper exception is one of reasons why we should use file system API added in Java 7 (Path, Paths, Files, etc) instead of `File` class. Take a look at https://docs.oracle.com/javase/tutorial/essential/io/delete.html and maybe at [Why File sucks](http://java7fs.wikia.com/wiki/Why_File_sucks) – Pshemo Jun 01 '17 at 18:59

3 Answers3

0

It's always a good design practice to handle possible errors around any kind of i/o be local or over the network
Try to catch the following exceptions in delete():-

try {
    Files.delete(file.toPath());
} catch (NoSuchFileException x) {
    System.err.format("%s: no such" + " file or directory%n", file.getAbsolutePath());
} catch (DirectoryNotEmptyException x) {
    System.err.format("%s not empty%n", file.getAbsolutePath());
} catch (IOException x) {
    // File permission problems are caught here.
    System.err.println(x);
}

This is from Java documentation

Pshemo
  • 118,400
  • 24
  • 176
  • 257
Zakir
  • 2,142
  • 19
  • 30
  • It raises a FileSystemException, so is something related to permissions. The problem is that this file is used by a costantly running server who acces it, but i also need to delete this file when i need (wich again it won't allow me to do it because is used by the server wich cannot be stopped) – Jimi Jun 01 '17 at 19:13
  • 1
    Why did you change `Files.delete` to `file.delete`? `file` suggests that you want to invoke `delete` method on `File` instance, but `File` class doesn't have `delete(anotherLocation)` method. In documentation there is `Files` class which is different than `File`. `Files` provides utility methods such as `delete(location)`. – Pshemo Jun 01 '17 at 19:27
  • @Pshemo Opps I did not realize that, was trying to use OP's variable `file` - Thanks for pointing it out !! – Zakir Jun 01 '17 at 19:33
0

Be sure you have right permissions for that directory and everything beneath it. Here it depends in your OS, if it is Linux you can run chmod.

Also please make sure to see this it once helped me.

Oussama Ben Ghorbel
  • 2,071
  • 4
  • 15
  • 29
0
/**
     * Deletes the file or directory denoted by this abstract pathname.  If
     * this pathname denotes a directory, then the directory must be empty in
     * order to be deleted.
     *
     * @return  <code>true</code> if and only if the file or directory is
     *          successfully deleted; <code>false</code> otherwise
     *
     * @throws  SecurityException
     *          If a security manager exists and its <code>{@link
     *          java.lang.SecurityManager#checkDelete}</code> method denies
     *          delete access to the file
     */

are you sure that your process has access rights for removing? Try to catch SecurityException

Vitaliy Moskalyuk
  • 2,253
  • 11
  • 15