3

I'm struggling with very basic problem, please take a look:

Some other process creates a file(only one) with unknown name but with .txt extension. This creation may take a while so I have written a loop which waits for this file and it breakes when the file is found. The problem is- how can I pass the unknown value to the String? I suppose that it is possible to do it with a regular expression.

What is more I have tried with this: Java: Find .txt files in specified folder but in my opion there is a better way to apply different solution to my case.

Code:

import java.io.File;

public class Test {

public static void waitForFile() throws InterruptedException{
    while(true){
        File f = new File("C:\\Test\\strangeName.txt");
        if(f.exists()){
            System.out.println("File is available now! End of the program");
            break;
        }
        System.out.println("File still does not exist.");
        Thread.sleep(5000);
    }
}   
public static void main(String[]args) throws InterruptedException{
    waitForFile();  
}
}

I would like to have a code which runs like this:

File f = new File("C:\\Test\\*.txt");    

Thanks a lot in advance for any hints!

SOLUTION OF THIS PROBLEM

Thanks to @JordiCastilla I have created a code below. Once again thanks a lot :)

import java.io.File;
import java.io.FileFilter;

class TextFileFilter implements FileFilter{

private String fileExtension = "txt";

@Override
public boolean accept(File file) {
    if(file.getName().toLowerCase().endsWith(fileExtension)){
        return true;
    }
    return false;
}
}

public class Test {

public static String waitForFileAndGetName() throws InterruptedException{

    TextFileFilter tff = new TextFileFilter();
    File f = new File("C:\\Users\\502532974\\Desktop\\Tescior");
    int i = 1;
    while(true){

        File[] files = f.listFiles(tff);
        if(files.length > 0){
            System.out.println("File is available now! End of the program.");
            return f.listFiles(tff)[0].getName();
        }
        System.out.println("File still does not exist. Iteration number "+i);
        Thread.sleep(5000);
        i++;
    }
}


public static void main(String[]args) throws InterruptedException{
    System.out.println("File name is="+waitForFileAndGetName());    
}
}
Community
  • 1
  • 1
JMK
  • 199
  • 1
  • 2
  • 18
  • This is what WatchService is for. But whatever method you choose, you need to be a lot smarter about it, because the file's existence doesn't mean it has its content fully written yet. – biziclop Jan 29 '16 at 12:07
  • @biziclop so how to deal with this problem? – JMK Jan 29 '16 at 12:29
  • It's difficult. If you have control over the system that writes the files, the solution is to write them as a temporary file (to the same location), and as the last step, rename it to `something.txt`. But if you don't have control over the writers, you need to keep track of the last modification dates of files and only pick ones up that have stopped being modifying let's say 5 seconds ago. – biziclop Jan 29 '16 at 13:49
  • 1
    @biziclop I don't have any control over the writer. As I was writting previously an extern process is creating this file and when it is finished it copies it to the my directory. Your suggestion with checking modification seems the best solution to prevent the problem. Thanks! – JMK Jan 29 '16 at 14:09

5 Answers5

3

I would recommend to use WatchService from java.nio.file: https://docs.oracle.com/javase/tutorial/essential/io/notification.html

You can filter the result for the txt extension then.

simdevmon
  • 673
  • 7
  • 14
2

Create your own FileFilter:

If you ONLY need *.txt files:

public class TextFileFilter implements FileFilter
{
  private final String TXT = "txt";

  public boolean accept(File file)
  {
    if (file.getName().toLowerCase().endsWith(TXT))
      return true;
    else
      return false;
  }
}

Now you just need to check the folder for changes:

File folder = new File("yourFolder");

while (true) {
    File[] files = folder.listFiles(new TextFileFilter());
    if (files.length > 0) // found;
}

ADD ON:

If you want to check more thank *.txt file extension. Will be something like this:

public class TextFileFilter implements FileFilter
{
  private final String[] okFileExtensions = new String[] {"txt", "doc"};

  public boolean accept(File file)
  {
    for (String extension : okFileExtensions)
    {
      if (file.getName().toLowerCase().endsWith(extension))
      {
        return true;
      }
    }
    return false;
  }
}

SOURCE

Jordi Castilla
  • 26,609
  • 8
  • 70
  • 109
  • 1
    Your answer looks really good and it is working fine! I have added a line which gets this particular file name. Thanks a lot :) – JMK Jan 29 '16 at 11:48
0
File f = new File("C:\\Test\\strangeName.txt");
  1. Get a filename:

    String fileName = f.getName();
    
  2. Then get extension:

    String exte = fileName.substring(fileName.lastIndexOf(".") + 1);
    
Tom
  • 16,842
  • 17
  • 45
  • 54
Sonal
  • 262
  • 5
  • 22
0

An alternative solution:

public static void waitForFile(String fileLocation, String extension) throws InterruptedException {

    List<File> files = Arrays.asList(new File(fileLocation).listFiles());

    int i = 0;
    try {
        while (!files.get(i).getCanonicalPath().endsWith(extension)) {

            i = i == files.size() ? 0 : i + 1;

            Thread.sleep(5000);

        }

        System.out.println(files.get(i).getName());

    } catch (Exception e) {

        Thread.sleep(5000);
        waitForFile(fileLocation, extension);

    }

}

call this method giving the file location and desired extension as arguments.

 new bbb().waitForFile("C:\\Test\\", ".txt");
Chathura Wijeweera
  • 289
  • 1
  • 2
  • 9
0

Simplest solution:

public static String waitForFileAndGetName() throws InterruptedException{
    FilenameFilter tff = new WildcardFileFilter("*.txt");
    File f = new File("C:\\Users\\502532974\\Desktop\\Tescior");
    File[] files;
    int i = 0;
    while((files = f.listFiles(tff)).length == 0){
        System.out.println("File still does not exist. Iteration number " + ++i);
        Thread.sleep(500);
    }
    System.out.println("File is available now! End of the program.");
    return f.listFiles(tff)[0].getName();
}
Adam Silenko
  • 3,025
  • 1
  • 14
  • 30