loop to check if a file exists - java

I have a folder that must contain always one file config8, and if a new file is created in this folder the old file is deleted and replaced by the new file with the same name config8.
I write this code
File file1 = new File("/home/olfa/Bureau/config/config8");
File file2 = new File("/home/olfa/Bureau/config/config9");
while (file2.exists())
{
file1.delete();
file2.renameTo(file1); }
}
serverConnection = new ServerConnection("/home/olfa/Bureau/config/config8");
I need to add a loop to check everytime if config9 is created.

Instead of a loop try a WatchService.
Basically you would be watching a particular directory for change and then you can react on this change.
https://docs.oracle.com/javase/tutorial/essential/io/notification.html
For example :
import static java.nio.file.StandardWatchEventKinds.*;
WatchService watcher = FileSystems.getDefault().newWatchService();
Path dir = ...;
try {
WatchKey key = dir.register(watcher,
ENTRY_CREATE,
ENTRY_DELETE,
ENTRY_MODIFY);
} catch (IOException x) {
System.err.println(x);
}
Then you can process your key events.

If you have to solve this task with Java 1.6, you can use https://commons.apache.org/proper/commons-vfs/, version 2.1.
Here is an example for moving all incoming config files to "config8":
import org.apache.commons.vfs2.*;
import org.apache.commons.vfs2.impl.DefaultFileMonitor;
import java.io.File;
public class ConfigWatcher {
private static final String configDirName = "target/config";
private static final String configName = "config8";
private static final String absoluteConfigName = new File(configDirName + File.separator + configName).getAbsolutePath();
private FileSystemManager manager = null;
FileObject configDir = null;
private FileObject configFile = null;
private FileChangeEvent lastEvent = null;
public void watchConfig() throws Exception {
manager = VFS.getManager();
DefaultFileMonitor fm = new DefaultFileMonitor(new ConfigFileListener());
configFile = manager.resolveFile(absoluteConfigName);
configDir = manager.resolveFile(new File(configDirName).getAbsolutePath());
fm.setDelay(1000);
fm.addFile(configDir);
fm.start();
}
class ConfigFileListener implements FileListener {
public void fileCreated(FileChangeEvent fileChangeEvent) throws Exception {
FileObject latestConfigFile = fileChangeEvent.getFile();
String fileBaseName = fileChangeEvent.getFile().getName().getBaseName();
if (!configName.endsWith(fileBaseName) && !fileChangeEvent.equals(lastEvent)) {
System.out.println("new config detected - move config");
latestConfigFile.moveTo(configFile);
}
lastEvent = fileChangeEvent;
}
public void fileChanged(FileChangeEvent fileChangeEvent) {
}
public void fileDeleted(FileChangeEvent fileChangeEvent) {
}
}
public static void main(String[] args) throws Exception {
final ConfigWatcher configWatcher = new ConfigWatcher();
configWatcher.watchConfig();
while (true) {
Thread.sleep(1000);
}
}
}

Related

Listing files of a directory in spring-boot

Is there an easy way to show the directory listing of my SPRING BOOT (v 2.1) resources/static folder?
The files are located under resources/static and I can access them separately, but I want to have a listing of all files and open them by clicking on the title like shown in the picture.
I want to "expose" the Log Files under resources/static/logs. If possible answer the question in Kotlin.
I found a similar question on SO but it didn't help:
Spring boot Tomcat – Enable/disable directory listing
Try this. It detects new files and folders (register new folder watcher) and performs some logic.
Somewhere in config class...
#Bean(name = "storageWatchService")
public WatchService createWatchService() throws IOException {
return FileSystems.getDefault().newWatchService();
}
#Component
public class StorageWatcher implements ApplicationRunner {
private static final Logger LOG = LoggerFactory.getLogger(StorageWatcher.class);
private static final WatchEvent.Kind<Path>[] WATCH_EVENTS_KINDS = new WatchEvent.Kind[] {StandardWatchEventKinds.ENTRY_CREATE};
private static final Map<WatchKey, Path> KEY_PATH_MAP = new HashMap<>();
#Resource
private PPAFacade ppaFacade;
#Resource
private WatchService storageWatchService;
#Resource
private Environment environment;
#Override
public void run(ApplicationArguments args) {
try {
registerDir(Paths.get(environment.getProperty(RINEX_FOLDER)), storageWatchService);
while (true) {
final WatchKey key = storageWatchService.take();
for (WatchEvent<?> event : key.pollEvents()) {
if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE && event.context() instanceof Path) {
final String fullPath = KEY_PATH_MAP.get(key) + "\\" + event.context().toString();
final File file = new File(fullPath);
if (file.isDirectory()) {
registerDir(file.toPath(), storageWatchService);
} else {
ppaFacade.process(file);
}
}
}
if (!key.reset()) {
KEY_PATH_MAP.remove(key);
}
if (KEY_PATH_MAP.isEmpty()) {
break;
}
}
} catch (InterruptedException e) {
LOG.error("StorageWatcher has been interrupted. No new files will be detected and processed.");
}
}
private static void registerDir(Path path, WatchService watchService) {
if (!Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS)) {
return;
}
try {
LOG.info("registering: " + path);
final WatchKey key = path.register(watchService, WATCH_EVENTS_KINDS);
KEY_PATH_MAP.putIfAbsent(key, path);
Arrays.stream(path.toFile().listFiles()).forEach(f -> registerDir(f.toPath(), watchService));
} catch (IOException e) {
LOG.error(MessageFormat.format("Can not register file watcher for {0}", path), e);
}
}
}

LOG4J2 Use multiple config files using java

can log4j2 use multiple config files. I wanna run my project and load one default config file - logger.xml and after that to check if there is a second configuration from another file logger_1.xml and to add it and not to override the first one.
Here is some dummy code. In short I wanna fill up the arrayList with file paths and then to load all of them.
public class LoggerConfiguratorManager
{
public static final String LOG4J_PATH = "etc/confs/logger.xml";
private static LoggerContext context = null;
private static final ConfigurationFactory factory = XmlConfigurationFactory.getInstance();
private static ConfigurationSource configurationSource = null;
private static Configuration configuration = null;
private static final ArrayList<String> registred_logger = new ArrayList<>();
private static void loadLoggerConfig(String logger_path)
{
InputStream is = null;
try
{
if(logger_path.endsWith(".xml"))
is = new FileInputStream(logger_path);
else
{
final ZipFile archive = new ZipFile(logger_path);
final ZipEntry logger_entry = archive.getEntry(LOG4J_PATH);
if(logger_entry == null) throw new IOException("Cannot find 'logger.xml' in " + logger_path);
is = archive.getInputStream(logger_entry);
}
configurationSource = new ConfigurationSource(is);
configuration = factory.getConfiguration(configurationSource);
}
catch(IOException ex)
{
System.err.println("=============================================================================");
System.err.println("=============================== LOGGER CONFIG ===============================");
System.err.println("=============================================================================");
System.err.println("=== [ERROR] " + ex);
}
finally
{
if (configurationSource != null)
{
context = Configurator.initialize(null, configurationSource);
context.start(configuration);
try { is.close(); } catch(IOException ex) { }
}
}
}
public static void load()
{
registred_logger.add(Globals.getClassLocation(LoggerConfiguratorManager.class));
for(final String conf : registred_logger)
loadLoggerConfig(conf);
}
public static void regLoggerConf(String conf_path) { registred_logger.add(conf_path); }
I would suggest doing instead:
public class LoggerConfiguratorManager {
private static final String LOG4J_PATH = "etc/confs/log4j2.xml";
private static final StringBuffer paths = new StringBuffer(LOG4J_PATH);
public static void registerConfiguration(String confPath) {
paths.append(",").append(confPath);
}
public static void initLog4j() {
Configurator.initializer("My Config", null, paths.toString(), null);
}
}
For a full working example please see https://github.com/rgoers/CompositeConfigurationExample.

Error when load JAR file classes at run time

I am trying to add JAR file to class path and load all classes from JAR file at run time. here is the code I wrote for this task (This class extends URLClassLoader)
public void loadJar(final String fName) throws IOException, IllegalAccessException, ClassNotFoundException {
final File file = new File(fName);
if (file.exists() && getFileExtension(file.getName()).equalsIgnoreCase("jar")) {
addURL(file.toURI().toURL());
for(final URL url : getURLs()){
System.out.println(url.toString());
}
final ZipFile jarFile = new ZipFile(file, ZipFile.OPEN_READ);
final Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) jarFile.entries();
while (entries.hasMoreElements()) {
final String className = getClassCanonicalName(entries.nextElement());
if (className != null) {
loadClass(getClassCanonicalName(entries.nextElement()));
}
}
}
}
private String getFileExtension(final String fileName) {
return fileName.substring(fileName.lastIndexOf(".") + 1);
}
private String getClassCanonicalName(final ZipEntry entry) {
final String entryName = entry.getName();
if (getFileExtension(entryName).toLowerCase().endsWith("class")) {
return entryName.replaceAll(File.separator, ".");
} else {
return null;
}
}
But I keep getting ClassNotFoundException for class entities even through getURLs does indicate jar files has been added to this loader.
What is the cause of this problem? Thanks
return entryName.replaceAll(File.separator, ".");
On Windows this will fail. It should be / for the separator of a ZipEntry for a Zip made on any platform.
So replace that with:
return entryName.replaceAll("/", ".");
Also strip the class name. SSCCE E.G.:
import java.io.*;
import java.net.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class URLClassLoaderTest extends URLClassLoader {
public URLClassLoaderTest(URL[] arg0) {
super(arg0);
}
public void loadJar(URL urlOfJar) throws IOException, IllegalAccessException, ClassNotFoundException {
if (getFileExtension(urlOfJar.getFile()).equalsIgnoreCase("jar")) {
addURL(urlOfJar);
for(final URL url : getURLs()){
System.out.println(url.toString());
}
final ZipInputStream zis = new ZipInputStream(urlOfJar.openStream());
ZipEntry ze = zis.getNextEntry();
while (ze!=null) {
final String className = getClassCanonicalName(ze);
if (className != null) {
loadClass(getClassCanonicalName(ze));
}
ze = zis.getNextEntry();
}
}
}
private String getFileExtension(final String fileName) {
return fileName.substring(fileName.lastIndexOf(".") + 1);
}
private String getClassCanonicalName(final ZipEntry entry) {
final String entryName = entry.getName();
if (getFileExtension(entryName).toLowerCase().endsWith("class")) {
String s = entryName.substring(0,entryName.length()-6);
s = s.replaceAll("/", ".");
System.out.println(s);
return s;
} else {
return null;
}
}
public static void main(String[] args) throws Exception {
URL[] url = {new URL("http://pscode.org/lib/mime.jar")};
URLClassLoaderTest uclt = new URLClassLoaderTest(url);
uclt.loadJar(url[0]);
}
}
Output
http://pscode.org/lib/mime.jar
org.pscode.mime.MimeType$1
org.pscode.mime.MimeType$1
org.pscode.mime.MimeType$2
org.pscode.mime.MimeType$2
org.pscode.mime.MimeType
org.pscode.mime.MimeType

How to access files within folders within jar files?

I have looked at How to access resources in JAR file? and How do I copy a text file from a jar into a file outside of the jar? and many other questiions but couldnt actually get an answer. What I'm trying to do is copy contents of a file in res/CDC.txt that is in jar, to somewhere out of a jar. Now, on my computer it works but when I try it on different computer I get FileNotFoundException. So, I figured out why it works on mine. I have a CLASSPATH set to .;D:\myname\Java\JavaFiles where all my java files are located in packages. In "JavaFiles" directory there is also "res/CDC.txt". So, when I start my application, it first checks the current directory myapp.jar is located in for "res/CDC.txt", and then it checks "JavaFiles" and finds it. Other computers do not have it. So, this was my initial code:
public final class CT
{
//Other fields
private static CT ct;
private NTSystem nts;
private File f1;
private File f6;
private PrintWriter pw1;
private BufferedReader br1;
//Other fields
public static void main(String[] args)
{
try
{
showMessage("Executing program...");
ct = new CT();
ct.init();
ct.create();
ct.insertData();
//Other code
showMessage("Program executed!");
}
catch(Exception e)
{
showMessage("An exception occured! Program closed.");
e.printStackTrace();
System.exit(0);
}
}
private void init()
throws IOException
{
//Other initialization
nts = new NTSystem();
f1 = new File("C:\\Users\\" + nts.getName() + "\\blahblah");
f6 = new File("res\\CDC.txt");
br1 = new BufferedReader(new FileReader(f6));
//Other initialization
showMessage("Initialized");
}
private void create()
throws IOException
{
//Makes sure file/dir exists, etc
pw1 = new PrintWriter(new BufferedWriter(new FileWriter(f1)), true);
//Other Stuff
showMessage("Created");
}
private void insertData()
throws IOException
{
String line = br1.readLine();
while(line != null)
{
pw1.println(line);
line = br1.readLine();
}
//Other stuff
showMessage("Data inserted");
}
private static void showMessage(String msg)
{
System.out.println(msg);
}
}
which I changed to
public final class CT
{
//Other fields
private static CT ct;
private NTSystem nts;
private byte[] buffer;
private File f1;
private URL url1;
private FileOutputStream fos1;
private InputStream is1;
//Other fields
public static void main(String[] args)
{
try
{
showMessage("Executing program...");
ct = new CT();
ct.init();
ct.create();
ct.insertData();
//Other code
showMessage("Program executed!");
}
catch(Exception e)
{
showMessage("An exception occured! Program closed.");
e.printStackTrace();
System.exit(0);
}
}
private void init()
throws IOException
{
//Other initialization
nts = new NTSystem();
buffer = new byte[4096];
f1 = new File("C:\\Users\\" + nts.getName() + "\\blahblah");
url1 = getClass().getClassLoader.getResource("res\\CDC.txt"); //Also tried url1 = ct.getClass().getClassLoader.getResource("res\\CDC.txt"); or url1 = this.getClass().getClassLoader.getResource("res\\CDC.txt"); or url1 = CT.getClass().getClassLoader.getResource("res\\CDC.txt");
is1 = url1.openStream();
//Other initialization
showMessage("Initialized");
}
private void create()
throws IOException
{
//Makes sure file/dir exists, etc
pw1 = new PrintWriter(new BufferedWriter(new FileWriter(f1)), true);
//Other Stuff
showMessage("Created");
}
private void insertData()
throws IOException
{
int read = is1.read(buffer);
while(line != null)
{
fos1.write(buffer, 0, read);
read = is1.read(buffer);
}
//Other stuff
showMessage("Data inserted");
}
private static void showMessage(String msg)
{
System.out.println(msg);
}
}
And this time I always get NullPointerException. So, how to read folders and files that are within jar?
Thanks
You will want to use getSystemResourceAsStream() to read the contents from files in a jar.
This of course is assuming the file is actually on the classpath of the other users computers.

delele all files with an extension in java

So I found some code earlier that looks like it would work but it doesn't call to delete the files just to list them. What do I need to add so that it deletes the files?
import java.io.File;
import java.util.regex.Pattern;
public class cleardir {
static String userprofile = System.getenv("USERPROFILE");
private static void walkDir(final File dir, final Pattern pattern) {
final File[] files = dir.listFiles();
if (files != null) {
for (final File file : files) {
if (file.isDirectory()) {
walkDir(file, pattern);
} else if (pattern.matcher(file.getName()).matches()) {
System.out.println("file to delete: " + file.getAbsolutePath());
} } } }
public static void main(String[] args) {
walkDir(new File(userprofile+"/Downloads/Software_Tokens"),
Pattern.compile(".*\\.sdtid"));
}
}
Once you have the path to the file, delete him:
File physicalFile = new File(path); // This is one of your file objects inside your for loop, since you already have them just delete them.
try {
physicalFile.delete(); //Returns true if the file was deleted or false otherwise.
//You might want to know this just in case you need to do some additional operations based on the outcome of the deletion.
} catch(SecurityException securityException) {
//TODO Handle.
//If you haven't got enough rights to access the file, this exception is thrown.
}
To delete a file you can call the delete function
file.delete();
You can invoke the delete() method on an instance of File. Be sure to check the returncode to make sure your file was actually deleted.
Use file.delete(); to delete a file.
You need to learn Java basics properly before attempting to write programs. Good resource: http://docs.oracle.com/javase/tutorial/index.html
Call File.delete() for each file you want to delete. So your code would be:
import java.io.File;
import java.util.regex.Pattern;
public class cleardir {
static String userprofile = System.getenv("USERPROFILE");
private static void walkDir(final File dir, final Pattern pattern) {
final File[] files = dir.listFiles();
if (files != null) {
for (final File file : files) {
if (file.isDirectory()) {
walkDir(file, pattern);
} else if (pattern.matcher(file.getName()).matches()) {
System.out.println("file to delete: " + file.getAbsolutePath());
boolean deleteSuccess=file.delete();
if(!deleteSuccess)System.err.println("[warning]: "+file.getAbsolutePath()+" was not deleted...");
}
}
}
}
public static void main(String[] args) {
walkDir(new File(userprofile+"/Downloads/Software_Tokens"),
Pattern.compile(".*\\.sdtid"));
}
}
final File folder = new File("C:/Temp");
FileFilter ff = new FileFilter() {
#Override
public boolean accept(File pathname) {
String ext = FilenameUtils.getExtension(pathname.getName());
return ext.equalsIgnoreCase("EXT"); //Your extension
}
};
final File[] files = folder.listFiles(ff);
for (final File file : files) {
file.delete();
}
public class cleardir {
static String userprofile = System.getenv("USERPROFILE");
private static final String FILE_DIR = userprofile+"\\Downloads\\Software_Tokens";
private static final String FILE_TEXT_EXT = ".sdtid";
public static void run(String args[]) {
new cleardir().deleteFile(FILE_DIR,FILE_TEXT_EXT);
}
public void deleteFile(String folder, String ext){
GenericExtFilter filter = new GenericExtFilter(ext);
File dir = new File(folder);
if (dir.exists()) {
//list out all the file name with .txt extension
String[] list = dir.list(filter);
if (list.length == 0) return;
File fileDelete;
for (String file : list){
String temp = new StringBuffer(FILE_DIR)
.append(File.separator)
.append(file).toString();
fileDelete = new File(temp);
boolean isdeleted = fileDelete.delete();
System.out.println("file : " + temp + " is deleted : " + isdeleted);
}
}
}
//inner class, generic extension filter
public class GenericExtFilter implements FilenameFilter {
private String ext;
public GenericExtFilter(String ext) {
this.ext = ext;
}
public boolean accept(File dir, String name) {
return (name.endsWith(ext));
}
}
}

Categories

Resources