Java Regex Expression isn't working for File Validation - java

I'm trying to validate a filepath a user has entered through a swing box. They click on the location where they want the file and then they add the name of the file by themselves. So they need to make sure it is in the format such as "C:/files/documents/hello.txt and they need to specify the file type at the end so i can create a new file to write to. The isFile method doesn't seem to satisfy this as the file has to exist, so i'm trying to use regex now with an if statement to validate the file path .
public class Main {
public static void main (String [] args) throws FileNotFoundException {
String fileName = "C:/users/furquan/hello.txt";
File zerina = new File (fileName);
//FileInputStream fis = new FileInputStream (zerina);
String regex = "\\^(?:[\w]\:|\\\)(\\\[a-z_\-\s0-9\.]+)+\\\.(txt|gif|pdf|doc|docx|xls|xlsx)$";
System.out.println (fileName.matches(regex));
}
}
I know you need to add more slashes in java regex because of the escape sequence but i can't get it to work

Use java.nio.file.Path. (you don't need Regexs)
for example :
// imports
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
Path path = Paths.get("C:/users/furquan/hello.txt");
Path parent = path.getParent();
if (Files.exists(parent) && path.getFileName().endsWith(".txt")) {
// your code goes here
}
EDIT :
Also, if you want to validate file names :
static final Pattern FILE_NAME_PATTERN = Pattern.compile("([\\w\\d\\s\\-\\.])+\\.(txt|gif|pdf|doc|docx|xls|xlsx)");
public static void main(String[] args) throws Exception {
String s = "C:/users/furquan/hello.txt";
System.out.println(createFile(s));
}
static boolean createFile(String fileName) throws IOException {
Path path = Paths.get(fileName);
if (Files.exists(path)) {
return true;
}
if (FILE_NAME_PATTERN.matcher(path.getFileName().toString()).matches()) {
Path parent = path.getParent();
if (!Files.exists(parent)) {
Files.createDirectories(parent);
}
Files.createFile(path);
return true;
}
return false;
}

You have way too much escaping and unnecessary stuff in your regex. None of the characters you're dealing with need escaping, and in fact escaping them breaks your regex.
Try this:
String regex = "(?i)[A-Z]:[\\\\\\w\\s.-]+)\\.(txt|gif|pdf|docx|doc|xlsx|xls)";
Since matches() must match the whole string, ^ and $ are implied, so leave them out.

Related

Copying the content of a list into a folder

I have an arrayList "rules" containing Rules. Each Rule is an XML file and have some properties such as filename...
I want to copy the Rules from the arraylist to a folder named AllMRG. I tried the code between comments but I get the message "Source 'RG6.31.xml' does not exist".
I changed the code by the following, but there is still a problem with 'RG6.31.xml' and the folder AllMRG is empty even though the arrayList contains many Rules!
First attemption:
File AllMRGFolder = new File("AllMRG");
for(int p = 0; p < rules.size(); p++) {
/* File MRGFile = new File(rules.get(p).fileName);
FileUtils.copyFileToDirectory(MRGFile, AllMRGFolder); */
File MRGFile = new File("AllMRG/" + rules.get(p).fileName);
if (!MRGFile.exists()) {
FileUtils.copyFileToDirectory(MRGFile, AllMRGFolder);
}
}
Second attemption:
String path = "AllMRG";
for(Rule rule : rules) {
File MRGFile = new File(rule.fileName);
Files.copy(MRGFile.toPath(), (new File(path + MRGFile.getName())).toPath(), StandardCopyOption.REPLACE_EXISTING);
}
PS: Rule is a class
public class Rule implements Comparable{
public String fileName;
public String matches;
public String TPinstances;
public int nbrOfMatches;
public double T;
#Override
public int compareTo(Object o) {
if(o instanceof Rule){
//processing to compare one Rule with another
}
return 0;
}
}
Here is the entire code after having considered Shyam's answer. The same problem persists!
Path directoryPath = Files.createDirectory(Paths.get("AllMGR"));
for(Rule rule : rules) {
Path filePath = directoryPath.resolve(rule.fileName);
Files.createFile(filePath);
File MRGFile = new File(rule.fileName);
String ruleContent = new String(Files.readAllBytes(Paths.get(MRGFile.getPath())));
String fileContent = new String(Files.readAllBytes(filePath));
fileContent=ruleContent;
PrintWriter out13= new PrintWriter("AllMGR/"+rule.fileName+".xml");
out13.print(fileContent);
out13.close();
}
Firstly, you are creating a new File with rule.filename without giving any predefined path. Then, you are building a path like: path + MRGFile.getName() without any path delimiters and trying to copy the file to this location. I don't think this will work.
What can actually help you is, creating a base directory first and then creating individual files in it.
Create base directory:
Path directoryPath = Files.createDirectory(Paths.get("AllMGRDir"));
Then for each of your Rule object you can crate file using:
for(Rule rule : rules) {
Path filePath = directoryPath.resolve(rule.fileName());
Files.createFile(filePath);
// your remaining code
}
The resolve(String other) method resolves the given path. Java doc says that:
Converts a given path string to a Path and resolves it against this
Path in exactly the manner specified by the resolve(Path) method.
For example, suppose that the name separator is "/" and a path
represents "foo/bar", then invoking this method with the path string
"gus" will result in the Path "foo/bar/gus"
Hope this helps.

File Not Found Exception?

I'm trying to read in a file, and throw each word into an arraylist, but it keeps saying it can't find the file. I've double checked (and triple, and quadruple, lol) that the file names match with correct extension and in the same directory. I feel like I'm missing something obvious. Also, I know there are other ways to read a file, but we haven't learned those yet in my class so I want to get this to work using the Scanner class.
public class FrequencyAnalysis {
private static ArrayList<String> words = new ArrayList<>();
public static void read() throws IOException {
String token;
Scanner inFile = new Scanner(new File("plaintext.txt"));
while (inFile.hasNext()){
token = inFile.next();
words.add(token);
}
}
}
public class FrequencyAnalysisTester {
public static void main(String[] Args) throws IOException {
FrequencyAnalysis.read();
}
}
The current directory may differ from the directory of .class file.
If your file is in the class path ,this code solve your problem
URL path = ClassLoader.getSystemResource("myFile.txt");
File f = new File(path.toURI());
Refer this answer for more details
Java, reading a file from current directory?

Inputting a text file into a program?

I had a lecture today on inputting and outputting but it didn't really seem to explain where the text file is etc..
here is my code:
package inputoutput;
import java.util.*;
import java.io.*;
public class input {
public static void main(String[] args) throws FileNotFoundException {
String name;
int lineCount = 0;
File input = new File("lab1task3.txt");
Scanner in = new Scanner(input);
while(in.hasNextLine()){
lineCount++;
}
System.out.println(lineCount);
}
}
I get a file not found exception but the text file is in the same folder as the program?
Please first read up on the difference between relative and absolute paths. An absolute path is:
C:\Users\Ceri\workspace1\inputoutput\src\inputoutput\lab1task3.txt
A relative path would be just "lab1task3.txt", which is what is given. That means that lab1task3.txt can be found relative to the working directory (e.g if the working directory was "C:\Users\Ceri\workspace1\inputoutput\src\inputoutput\" then it would find it).
However, you could also use an absolute path, but remember that doing so means that it will only work if a file is in the same place on the machine running it. E.g, if you submit with "C:\Users\Ceri\workspace1\inputoutput\src\inputoutput\" in your code then it will only work if someone else has that same file and location on their computer. Please note that if this is an assignment, the module convenor/marker probably does not have afolder called C:\Users\Ceri.... If you submit your work using a relative path, anyone using your code just needs to make sure the file is relatively in the same place (e.g in the same folder).
If this doesn't matter, you need to escape the back slash characters with another back slash in the path. This should work:
package inputoutput;
import java.util.*;
import java.io.*;
public class input {
public static void main(String[] args) throws FileNotFoundException {
String name;
int lineCount = 0;
File input = new File("C:\\Users\\Ceri\\workspace1\\inputoutput\\src\\inputoutput\\lab1task3.txt");
Scanner in = new Scanner(input);
while(in.hasNextLine()){
lineCount++;
}
System.out.println(lineCount);
}
}
I notice you are using eclipse. Your "working directory" is your workspace. Therefore you want to move your file to:
C:\Users\Ceri\workspace1\inputoutput\lab1task3.txt
This should work for you using a "relative" path which you had in your opening post.
You're confusing class file location and the "user's working directory", the latter being what Java uses to determine the root of the file path (unless absolute paths are needed), and you can find its location easily via:
System.out.println(System.getProperty("user.dir"));
I advise you to forgo use of files altogether when all you need to do is read in data, and instead get the text file as a program resource:
// where you swap the name of your class for MyClass
InputStream fileResource = MyClass.class.getResourceAsStream("myFile.txt");
Scanner scanner = new Scanner(inputStream);
Note that if you must use a File, then find out what the user's working directory is, as shown above, and then tailor your file path so that it is relative to this working directory.
Try:
File file = new File("src/inputoutput/lab1task3.txt");
My guess is that your current working directory is not the same place as the project location. If your working directory were, the file would definitely be found if it does indeed have that name.
To workaround this issue you can always be using a InputStream instead, like so:
InputStream inputStream = new InputStream("lab1task3.txt");
Scanner scanner = new Scanner(inputStream);
If you want to see your current working directory you can use something like this:
public class JavaApplication1 {
public static void main(String[] args) {
System.out.println("Working Directory = " +
System.getProperty("user.dir"));
}
}

pass parameter "a" to class java for the command line argument

public static void main(String[] args)
{
for (String a : args) {
System.out.println(a);
}
public class CustomConfiguration {
public static void readConfig(String filename) {
//read from config.properties file
try {
String File = filename;
System.out.println ("ConfigFile :" + File);
String result = "";
Properties properties = new Properties();
String propFileName = filename;
InputStream inputStream = new FileInputStream(propFileName);
}
}
My question is how can i pass the "a" to the CustomConfiguration class?
As other users have pointed that out already - using propertiesFile property can make your application really flexible as you only need to change the propertiesFile content and your application will obtain the necessary information from it. For example, if you had the following in your properties file:
myFileName=C:/gherkins
typeOfMeat=Beef
typeOfRisk=Very High
you can extract the myFileName property and get the value `C:/gherkins' in your class wherever you want. In case you change the values in your properties file, your class doesn't have to do anything except getting the new information - easy. If you are unclear, follow this - http://crunchify.com/java-properties-file-how-to-read-config-properties-values-in-java/
Alternatively:
You can use String[] args in main method to pass the filename you are interested in. You can use that everywhere else. args[0] is always the path of the class file you are running and args[1], args[2], etc. will be the extra arguments supplied to the class application. In your case you want to extract the file name by doing String myFileName = args[1]; and use myFileName in other places.
p.s. in your code the filename path is C://... You sure this // is correct? you might wanted to put C:\\my_file_name escaping backslash? or just use one forward slash?

Java equivalent of Perl's File::Spec->catfile? [duplicate]

Is there a Java equivalent for System.IO.Path.Combine() in C#/.NET? Or any code to accomplish this?
This static method combines one or more strings into a path.
Rather than keeping everything string-based, you should use a class which is designed to represent a file system path.
If you're using Java 7 or Java 8, you should strongly consider using java.nio.file.Path; Path.resolve can be used to combine one path with another, or with a string. The Paths helper class is useful too. For example:
Path path = Paths.get("foo", "bar", "baz.txt");
If you need to cater for pre-Java-7 environments, you can use java.io.File, like this:
File baseDirectory = new File("foo");
File subDirectory = new File(baseDirectory, "bar");
File fileInDirectory = new File(subDirectory, "baz.txt");
If you want it back as a string later, you can call getPath(). Indeed, if you really wanted to mimic Path.Combine, you could just write something like:
public static String combine(String path1, String path2)
{
File file1 = new File(path1);
File file2 = new File(file1, path2);
return file2.getPath();
}
In Java 7, you should use resolve:
Path newPath = path.resolve(childPath);
While the NIO2 Path class may seem a bit redundant to File with an unnecessarily different API, it is in fact subtly more elegant and robust.
Note that Paths.get() (as suggested by someone else) doesn't have an overload taking a Path, and doing Paths.get(path.toString(), childPath) is NOT the same thing as resolve(). From the Paths.get() docs:
Note that while this method is very convenient, using it will imply an assumed reference to the default FileSystem and limit the utility of the calling code. Hence it should not be used in library code intended for flexible reuse. A more flexible alternative is to use an existing Path instance as an anchor, such as:
Path dir = ...
Path path = dir.resolve("file");
The sister function to resolve is the excellent relativize:
Path childPath = path.relativize(newPath);
The main answer is to use File objects. However Commons IO does have a class FilenameUtils that can do this kind of thing, such as the concat() method.
platform independent approach (uses File.separator, ie will works depends on operation system where code is running:
java.nio.file.Paths.get(".", "path", "to", "file.txt")
// relative unix path: ./path/to/file.txt
// relative windows path: .\path\to\filee.txt
java.nio.file.Paths.get("/", "path", "to", "file.txt")
// absolute unix path: /path/to/filee.txt
// windows network drive path: \\path\to\file.txt
java.nio.file.Paths.get("C:", "path", "to", "file.txt")
// absolute windows path: C:\path\to\file.txt
I know its a long time since Jon's original answer, but I had a similar requirement to the OP.
By way of extending Jon's solution I came up with the following, which will take one or more path segments takes as many path segments that you can throw at it.
Usage
Path.combine("/Users/beardtwizzle/");
Path.combine("/", "Users", "beardtwizzle");
Path.combine(new String[] { "/", "Users", "beardtwizzle", "arrayUsage" });
Code here for others with a similar problem
public class Path {
public static String combine(String... paths)
{
File file = new File(paths[0]);
for (int i = 1; i < paths.length ; i++) {
file = new File(file, paths[i]);
}
return file.getPath();
}
}
To enhance JodaStephen's answer, Apache Commons IO has FilenameUtils which does this. Example (on Linux):
assert org.apache.commons.io.FilenameUtils.concat("/home/bob", "work\\stuff.log") == "/home/bob/work/stuff.log"
It's platform independent and will produce whatever separators your system needs.
Late to the party perhaps, but I wanted to share my take on this. I prefer not to pull in entire libraries for something like this. Instead, I'm using a Builder pattern and allow conveniently chained append(more) calls. It even allows mixing File and String, and can easily be extended to support Path as well. Furthermore, it automatically handles the different path separators correctly on both Linux, Macintosh, etc.
public class Files {
public static class PathBuilder {
private File file;
private PathBuilder ( File root ) {
file = root;
}
private PathBuilder ( String root ) {
file = new File(root);
}
public PathBuilder append ( File more ) {
file = new File(file, more.getPath()) );
return this;
}
public PathBuilder append ( String more ) {
file = new File(file, more);
return this;
}
public File buildFile () {
return file;
}
}
public static PathBuilder buildPath ( File root ) {
return new PathBuilder(root);
}
public static PathBuilder buildPath ( String root ) {
return new PathBuilder(root);
}
}
Example of usage:
File root = File.listRoots()[0];
String hello = "hello";
String world = "world";
String filename = "warez.lha";
File file = Files.buildPath(root).append(hello).append(world)
.append(filename).buildFile();
String absolute = file.getAbsolutePath();
The resulting absolute will contain something like:
/hello/world/warez.lha
or maybe even:
A:\hello\world\warez.lha
If you do not need more than strings, you can use com.google.common.io.Files
Files.simplifyPath("some/prefix/with//extra///slashes" + "file//name")
to get
"some/prefix/with/extra/slashes/file/name"
Here's a solution which handles multiple path parts and edge conditions:
public static String combinePaths(String ... paths)
{
if ( paths.length == 0)
{
return "";
}
File combined = new File(paths[0]);
int i = 1;
while ( i < paths.length)
{
combined = new File(combined, paths[i]);
++i;
}
return combined.getPath();
}
This also works in Java 8 :
Path file = Paths.get("Some path");
file = Paths.get(file + "Some other path");
This solution offers an interface for joining path fragments from a String[] array. It uses java.io.File.File(String parent, String child):
public static joinPaths(String[] fragments) {
String emptyPath = "";
return buildPath(emptyPath, fragments);
}
private static buildPath(String path, String[] fragments) {
if (path == null || path.isEmpty()) {
path = "";
}
if (fragments == null || fragments.length == 0) {
return "";
}
int pathCurrentSize = path.split("/").length;
int fragmentsLen = fragments.length;
if (pathCurrentSize <= fragmentsLen) {
String newPath = new File(path, fragments[pathCurrentSize - 1]).toString();
path = buildPath(newPath, fragments);
}
return path;
}
Then you can just do:
String[] fragments = {"dir", "anotherDir/", "/filename.txt"};
String path = joinPaths(fragments);
Returns:
"/dir/anotherDir/filename.txt"
Assuming all given paths are absolute paths. you can follow below snippets to merge these paths.
String baseURL = "\\\\host\\testdir\\";
String absoluteFilePath = "\\\\host\\testdir\\Test.txt";;
String mergedPath = Paths.get(baseURL, absoluteFilePath.replaceAll(Matcher.quoteReplacement(baseURL), "")).toString();
output path is \\host\testdir\Test.txt.

Categories

Resources