This question already has answers here:
Java 'file.delete()' Is not Deleting Specified File
(8 answers)
Can't delete files in java?
(7 answers)
Closed 5 years ago.
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?
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.
/**
* 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
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
Related
I am trying to make a base file plugin which other threads will inherit. But I am stuck at a point where the file exists and can be read from a normal thread but when I try to read that file from an abstract Base file, it says File not found. Here's my base class :-
package com.evol.fp;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public abstract class BaseFilePlugin extends Thread implements BaseFileReader{
String filename = "";
File file = null;
boolean fileStarted = false;
boolean fileEnded = false;
public BaseFilePlugin() {
file = new File(filename);
}
public void readFile() {
BufferedReader br = null;
System.out.println("Base call: " + filename);
try {
System.out.println("inbside ");
br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
if(br.readLine().trim().isEmpty()) {
endFile();
return;
} else {
startFile(filename);
String record;
while((record = br.readLine().trim()) != null) {
parseRecord(record);
}
endFile();
}
} catch(Exception ioe) {
ioe.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public abstract void parseRecord(String record);
public void startFile(String filename) {
this.fileStarted = true;
this.fileEnded = false;
}
public void endFile() {
file.delete();
this.fileEnded = true;
this.fileStarted = false;
}
public void run() {
while(true) {
System.out.println("Inside run, fileName: " + filename);
System.out.println("Filestarted: " + fileStarted + ", file exists: " + file.exists());
if(!fileStarted) {
readFile();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* #return the filename
*/
public String getFilename() {
return filename;
}
/**
* #param filename the filename to set
*/
public void setFilename(String filename) {
this.filename = filename;
}
}
I am aware of multithreading but never implemented with base class to parse records from a file, if someone tells me what's the problem that will be great. I know that the file exists for sure. Here's my child class: -
package com.evol.fp;
public class FileReaderThread extends BaseFilePlugin {
public FileReaderThread() {
super.setFilename("E:\\soham\\soham.txt");
}
#Override
public void parseRecord(String record) {
System.out.println(record);
}
}
But its not calling the child's parseRecord method, using a simple main method:-
package com.evol.fp;
public class StartProcess {
public static void main(String[] args) {
FileReaderThread thd = new FileReaderThread();
thd.start();
}
}
I think it's because the parent constructor (BaseFilePlugin.class) is called first before you set your filename in super.setFile("E:\\soham\\soham.txt");
If you can remove the parent constructor instead and replace your setFileName into setFile where file is iniatilize .e.g
// public BaseFilePlugin() {
// file = new File(filename);
// }
....
....
/**
* #return the file
*/
public String getFile() {
return file
}
/**
* #param file the file to set
*/
public void setFile(String file) {
file = new File(file);
}
and in your subclass
public FileReaderThread() {
super.setFile("E:\\soham\\soham.txt");
}
BaseFilePlugin's constructor creates its file with an empty string since initially String filename = "";.
The client calls setFilename(...) which updates filename. However, file is still the same instance when the object was first created (which is using an empty string as the file name).
I would suggest to pass the file name as part of the constructor so file is properly initialized:
public BaseFilePlugin(String filename) {
this.filename = filename;
file = new File(filename);
}
Optionally, if it makes sense that an instance can read only 1 file, then make those class attributes final, and remove the setFilename() method.
I have a Jar in java which is containing 2 classes and 1 Interface. How can i get the interface and class names from the jar. Currently I am able to get the class names, but not the interface name.
List jClasses = getClasseNames("D://Test.jar");
System.out.println(jClasses.size());
for (int i = 0; i < jClasses.size(); i++) {
System.out.println("Print Classes ::" + jClasses.get(i));
if(( null != jClasses.getClass().getInterfaces()[i])) {
System.out.println(jClasses.getClass().getInterfaces()[i]);
} else {
System.out.println("No connection");
}
}
public static List getClasseNames(String jarName) {
ArrayList classes = new ArrayList();
try {
JarInputStream jarFile = new JarInputStream(new FileInputStream(
jarName));
JarEntry jarEntry;
while (true) {
jarEntry = jarFile.getNextJarEntry();
if (jarEntry == null) {
break;
}
if (jarEntry.getName().endsWith(".class")) {
classes.add(jarEntry.getName().replaceAll("/", "\\."));
}
}
} catch (Exception e) {
e.printStackTrace();
}
return classes;
}
output :
Print Classes ::com.java.testclient.PTest1.class
interface java.util.List
======
Print Classes ::com.java.testclient.ClassSpy.class
interface java.util.RandomAccess
======
Print Classes ::com.java.testclient.myInt.class
interface java.lang.Cloneable
======
Print Classes ::com.java.testclient.PTest.class
interface java.io.Serializable
Please suggest.
You can use this class:
package io.github.gabrielbb.java.utilities;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
/**
* #author Gabriel Basilio Brito
* #since 12/26/2016
* #version 1.1
*/
public class ClassesAndInterfacesFromJar {
public static List<Class> getJarClasses(String jarPath) throws IOException, ClassNotFoundException {
File jarFile = new File(jarPath);
return getJarClasses(jarFile);
}
public static List<Class> getJarClasses(File jar) throws IOException, ClassNotFoundException {
ArrayList<Class> classes = new ArrayList();
JarInputStream jarInputStream = null;
URLClassLoader cl;
try {
cl = URLClassLoader.newInstance(new URL[]{new URL("jar:file:" + jar + "!/")}); // To load classes inside the jar, after getting their names
jarInputStream = new JarInputStream(new FileInputStream(
jar)); // Getting a JarInputStream to iterate through the Jar files
JarEntry jarEntry = jarInputStream.getNextJarEntry();
while (jarEntry != null) {
if (jarEntry.getName().endsWith(".class")) { // Avoiding non ".class" files
String className = jarEntry.getName().replaceAll("/", "\\."); // The ClassLoader works with "." instead of "/"
className = className.substring(0, jarEntry.getName().length() - 6); // Removing ".class" from the string
Class clazz = cl.loadClass(className); // Loading the class by its name
classes.add(clazz);
}
jarEntry = jarInputStream.getNextJarEntry(); // Next File
}
} finally {
if (jarInputStream != null) {
jarInputStream.close(); // Closes the FileInputStream
}
}
return classes;
}
// Main Method for testing purposes
public static void main(String[] args) {
try {
String jarPath = "C://Test.jar";
List<Class> classes = getJarClasses(jarPath);
for (Class c : classes) {
// Here we can use the "isInterface" method to differentiate an Interface from a Class
System.out.println(c.isInterface() ? "Interface: " + c.getName() : "Class: " + c.getName());
}
} catch (Exception ex) {
System.err.println(ex);
}
}
It can be found at:
https://github.com/GabrielBB/Java-Utilities/blob/master/ClassesAndInterfacesFromJar.java
I'm trying to find the .class creation time for a file inside a jar.
But When I try to use this piece of code, I'm getting the Jar creation time instead of the .class file creation time.
URL url = TestMain.class.getResource("/com/oracle/determinations/types/CommonBuildTime.class");
url.getPath();
try {
System.out.println(" Time modified :: "+ new Date(url.openConnection().getLastModified()));
} catch (IOException e) {
e.printStackTrace();
}
But when I open the jar I can see the .class creation time is different from that of the jar creation time.
Could you please try following solution:
import java.io.IOException;
import java.util.Date;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class Test {
public static void main(String[] args) throws IOException {
String classFilePath = "/com/mysql/jdbc/AuthenticationPlugin.class";
String jarFilePath = "D:/jars/mysql-connector-java-5.1.34.jar";
Test test=new Test();
Date date = test.getLastUpdatedTime(jarFilePath, classFilePath);
System.out.println("getLastModificationDate returned: " + date);
}
/**
* Returns last update time of a class file inside a jar file
* #param jarFilePath - path of jar file
* #param classFilePath - path of class file inside the jar file with leading slash
* #return
*/
public Date getLastUpdatedTime(String jarFilePath, String classFilePath) {
JarFile jar = null;
try {
jar = new JarFile(jarFilePath);
Enumeration<JarEntry> enumEntries = jar.entries();
while (enumEntries.hasMoreElements()) {
JarEntry file = (JarEntry) enumEntries.nextElement();
if (file.getName().equals(classFilePath.substring(1))) {
long time=file.getTime();
return time==-1?null: new Date(time);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (jar != null) {
try {
jar.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
}
Was trying to get a JFrame added to see if it would help with using launch4j to convert a small jar file to an .exe. I wrote a short program to help sort HPLC data at work and want to make it just a simple point and click.
It works when I run it from the command line java KFile and the JFileChooser lets me choose directories for the script to work on. When I converted it to the .exe, the JFileChooser never rendered and the .exe closes.
I read that I might need a JFrame parent and so I created a JFrame, but now the script hangs before completion as if waiting for the frame to close. I'm pretty new to java, so I'm not sure how I to resolve this issue.
import java.io.*;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.Files;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.FileVisitResult;
import java.nio.MappedByteBuffer;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import java.util.Collection;
import java.util.ArrayList;
import java.nio.file.SimpleFileVisitor;
public class KFile extends SimpleFileVisitor<Path> {
public static void main(String[] args) {
Path currPath = Paths.get("");
String currDir = currPath.toAbsolutePath().toString();
System.out.println(currDir);
File dataDir = chooseDir("open");
File destDir = chooseDir("save");
if(!destDir.exists()) {
try {
destDir.mkdir();
}
catch (SecurityException se) {
System.out.println("Couldn't make directory!");
}
}
int n = 0;
if(dataDir.exists()) {
Collection<Path> allDir = new ArrayList<Path>();
try {
addTree(dataDir.toPath(),allDir);
}
catch (IOException e) {
System.out.println("Error with scanning");
}
for( Path thisPath : allDir ) {
if(thisPath.toString().contains("Report.pdf")) {
Path thisDir = thisPath.getParent();
File f = new File(thisDir.toString(), "\\Report.txt");
n = n + 1;
String fileName = "Report " + n + ".pdf";
try {
fileName = parseName(f);
System.out.println(fileName);
} catch (IOException e) {
e.printStackTrace();
}
File thisFile = new File(destDir + "\\" + fileName);
try {
copyFile(thisPath.toFile(),thisFile);
} catch ( IOException e) {
e.printStackTrace();
}
}
}
}
}
public static boolean copyFile(File sourceFile, File destFile) throws IOException {
//create file if it doesn't exist.
if(!destFile.exists()) {
destFile.createNewFile();
}
FileChannel source = null;
FileChannel destination = null;
try {
source = new FileInputStream(sourceFile).getChannel();
destination = new FileOutputStream(destFile).getChannel();
destination.transferFrom(source, 0, source.size());
}
finally {
if(source != null) {
source.close();
}
if(destination != null) {
destination.close();
return true;
}
return false;
}
}
public static File chooseDir(String s) {
JFrame myFrame = new JFrame("HPLC Data Transfer");
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.pack();
myFrame.setVisible(true);
JFileChooser chooser = new JFileChooser();
File currDir = new File(System.getProperty("user.home") + "\\Documents");
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.setCurrentDirectory(currDir);
int choice = 0;
if (s.equals("save")) {
choice = chooser.showSaveDialog(myFrame);
} else {
choice = chooser.showOpenDialog(myFrame);
}
myFrame.setVisible(false);
myFrame.removeAll();
if(choice == JFileChooser.APPROVE_OPTION) {
System.out.println("You chose to open: " + chooser.getSelectedFile().getName());
return chooser.getSelectedFile();
}
return new File("");
}
static String parseName(File f) throws IOException {
BufferedReader textReader = new BufferedReader(new InputStreamReader(new FileInputStream(f), "UTF-16"));
int lnCnt = 32;
String[] fileData = new String[lnCnt];
for (int i = 0; i < lnCnt; i++) {
fileData[i] = textReader.readLine();
}
fileData[1] = fileData[1].replace("\uFEFF","");
String name = fileData[1].substring(13) + ".pdf";
textReader.close();
return name;
}
static void addTree(Path directory, final Collection<Path> all)
throws IOException {
Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
#Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
all.add(file);
return FileVisitResult.CONTINUE;
}
});
}
}
You could try changing
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
to
myFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
and then call
myFrame.dispose();
to terminate the JFrame.
Since javadocs says EXIT_ON_CLOSE terminates the whole program using System.exit(); I'm not sure if that's the problem that is stopping your application but I hope it helps :)
It looks like you just called setVisible(false) when dealing with your JFrame. That just hides your JFrame, it doesn't get rid of it. If you want to get rid of your frame entirely (and all of its resources), call myFrame.dispose();
So I have to make a program in java that automatically runs in the background and looks for a new .dat file and when it sees the new .dat file it then runs a .bat file to load data into a database. So far I have a program that watches for new file creation, modification, and deletion. I also have a script that runs the .bat file and loads the data into the database now i just need to connect the two but I am not sure how to go about this, If someone could point me in the right direction I would greatly appreciate it.
Below is the code I have so far.
import static java.nio.file.LinkOption.NOFOLLOW_LINKS;
import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
import static java.nio.file.StandardWatchEventKinds.OVERFLOW;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
import java.io.*;
import java.util.*;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.WatchEvent;
import java.nio.file.WatchEvent.Kind;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
public class Order_Processing {
public static void watchDirectoryPath(Path path)
{
try {
Boolean isFolder = (Boolean) Files.getAttribute(path,
"basic:isDirectory", NOFOLLOW_LINKS);
if (!isFolder)
{
throw new IllegalArgumentException("Path: " + path
+ " is not a folder");
}
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
System.out.println("Watching path: "+ path);
FileSystem fs = path.getFileSystem();
try (WatchService service = fs.newWatchService())
{
path.register(service, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE);
WatchKey key = null;
while (true)
{
key = service.take();
Kind<?> kind = null;
for (WatchEvent<?> watchEvent : key.pollEvents())
{
kind = watchEvent.kind();
if (OVERFLOW == kind)
{
continue;
}
else if (ENTRY_CREATE == kind)
{
Path newPath = ((WatchEvent<Path>) watchEvent)
.context();
System.out.println("New Path Created: " + newPath);
}
else if (ENTRY_MODIFY == kind)
{
Path newPath = ((WatchEvent<Path>) watchEvent)
.context();
System.out.println("New path modified: "+ newPath);
}
else if (ENTRY_DELETE == kind)
{
Path newPath = ((WatchEvent<Path>) watchEvent)
.context();
System.out.println("New path deleted: "+ newPath);
}
}
if (!key.reset())
{
break;
}
}
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
catch (InterruptedException ie)
{
ie.printStackTrace();
}
}
public static void main(String[] args)
throws FileNotFoundException
{
File dir = new File("C:\\Paradigm");
watchDirectoryPath(dir.toPath());
//below is the script that runs the .bat file and it works if by itself
//with out all the other watch code.
try {
String[] command = {"cmd.exe", "/C", "Start", "C:\\Try.bat"};
Process p = Runtime.getRuntime().exec(command);
}
catch (IOException ex) {
}
}
}
This doesn't work because you have a while (true). This makes sense because you are listening and want the to happen continuously; however, the bat call will never be executed because watchDirectory(...) will never terminate. To solve this, pull the rest of the main out into its own function like so
public static void executeBat() {
try {
String[] command = {"cmd.exe", "/C", "Start", "C:\\Try.bat"};
Process p = Runtime.getRuntime().exec(command);
}
catch (IOException ex) {
// You should do something with this.
// DON'T JUST IGNORE FAILURES
}
so that upon file creation, you can call that bat script
...
else if (ENTRY_CREATE == kind)
{
Path newPath = ((WatchEvent<Path>) watchEvent).context();
executeBat();
}
...