I want to make a tool that does the 2 following things::
Open files that are not .txt but can be opened as .txt and return them as a string. It just returns an empty string at the moment.
The filenames are unknown, just the file extension at the end and the the YYYYMMDD number in front are always the same, therefore I'd like the app to simply scan every file in the same folder (not the same file twice, obviously). How can this be done?
That's what I've got so far. Java Code:
public String readFile(String filename) throws FileNotFoundException {
Scanner scanner = null;
File file = new File(filename);
String output = "";
try{
scanner = new Scanner(file);
}catch(FileNotFoundException e){
System.out.println("Error: File " + filename + " not found!");
}
while (scanner.hasNextLine()){
output=output+scanner.nextLine();
}
return output;
}
So you want to call your readFile(file) method for every file in your directory.
You can use the File.listFiles() method to get the list of files in a directory:
File f = new File("your/directory");
File[] files = f.listFiles();
Then you can loop through the files (continuing previous example):
for (File file : files) {
System.out.println(readFile(file.toString()));
}
By the way, you should use a StringBuilder to append the strings so you won't have to make a new object every time a new line is read.
// define method that accept `dir`, `matcher` - will be called on each file to check if file name corret or not, `consumer` - will be called on each mathed file
public static void readFiles(Path dir, BiPredicate<Path, BasicFileAttributes> matcher, Consumer<Path> consumer) throws IOException {
BiPredicate<Path, BasicFileAttributes> localMatcher = (path, attr) -> attr.isRegularFile();
localMatcher = matcher != null ? localMatcher.and(matcher) : localMatcher;
Files.find(dir, Integer.MAX_VALUE, localMatcher).forEach(consumer);
}
Client code:
// define matcher to check if given file name match pattern or not
BiPredicate<Path, BasicFileAttributes> matcher = (path, attr) -> {
String fileName = path.getFileName().toString();
int dot = fileName.lastIndexOf('.');
String ext = dot >= 0 ? fileName.substring(dot + 1) : null;
String name = dot >= 0 ? fileName.substring(0, dot) : fileName;
// check 'name' and 'ext' match the required pattern
return true;
};
// define consumer to accept file path and read it line by line
Consumer<Path> consumer = path -> {
try {
String content = Files.lines(path, StandardCharsets.UTF_8).collect(Collectors.joining(System.lineSeparator()));
System.out.println("file name: " + path);
System.out.println(content);
} catch(IOException e) {
e.printStackTrace();
}
};
readFiles(Paths.get("H://one"), matcher, consumer);
i have a problem with my code, the User.txt file does exist, and i tried to catch the exception, but this error always keeps on showing after i call the readUser function. this is my code, please help me if you can, thank you
private static void readUser_(String fileName)
{
obj_User = null;
countUser_ = 0;
VectorClear_(V_User);
obj_User = new User[countObjectQuantity_(fileName)];
try {
File file = new File(fileName);
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine())
{
String inputLine = scanner.nextLine();
StringTokenizer st = new StringTokenizer(inputLine,DELIMITERS_);
Vector<String> temp= new Vector();
VectorClear_(temp);
while(st.hasMoreTokens())
{ temp.addElement(st.nextToken()); }
if(temp.size() == 0) return;
String id = temp.elementAt(0);
String password = temp.elementAt(1);
String status = temp.elementAt(2);
String contactNumber = temp.elementAt(3);
String firstName = temp.elementAt(4);
String lastName = temp.elementAt(5);
String email = temp.elementAt(6);
if(status.compareToIgnoreCase("admin")==0 )
{
//String adminLevel = temp.elementAt(7);
String staffId = temp.elementAt(7);
String staffIcNo = temp.elementAt(8);
obj_User[countUser_] = new Admin(id,password,contactNumber,firstName,lastName,email,/*adminLevel,*/staffId,staffIcNo);
V_User.addElement(obj_User[countUser_]);
countUser_++;
}
else if(status.compareToIgnoreCase("customer")==0 )
{
String gender = temp.elementAt(7);
Date dateOfBirth = convertStringToDate( temp.elementAt(8));
String address = temp.elementAt(9);
obj_User[countUser_] = new Customer(id,password,contactNumber,firstName,lastName,email,gender,dateOfBirth,address);
V_User.addElement(obj_User[countUser_]);
countUser_++;
}
}
scanner.close();
} catch (FileNotFoundException e)
{
e.printStackTrace();
}
}
If the path you are trying to use is Database\User.txt as mentioned in the question, then using the forward slash ('/') instead of the backward slash ('\') should solve the problem.
So the path is Database/User.txt. This is because the backward slash is a special character in java and should be escaped if you must use it (ie, place another backward slash in front of it).
This error usually means there is no directory
Database in your working directory,
or if it exists, there is no file User.txt in it.
You need to check what your working directory is for your program (at runtime)
and see if this directory and this file exist. Apparently it does not find them.
Add this print out in your program and see what your working directory is.
System.out.println("Working Directory = " + System.getProperty("user.dir"));
For more details you may want to check these pages.
http://docs.oracle.com/javase/tutorial/essential/io/pathOps.html
http://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html
I am fairly new to Java and am having issue with the code below. The doAggregate method below is reading through the columns of data from a csv file. I want to be able to check the value of fields[i] for special characters and non-escaped quotes and remove them from the value before they are appended. The code as is errors at the point noted below: java.lang.Double cannot be cast to java.lang.String. So it sounds like not all the types of fields will convert to a String value. Is there a good way to test if the String is a String? Or is there a better way of going about this?
public String doAggregate(Object[] fields) {
if (ObjectUtils.isEmpty(fields)) {
return "";
}
if (fields.length == 1) {
return "\"" + ObjectUtils.nullSafeToString(fields[0]) + "\"";
}
String tmp_field_value;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < fields.length; i++) {
if (i > 0) {
sb.append(getDelimiter());
}
sb.append("\"");
//start new code
tmp_field_value = (String) fields[i];
//error on line below
sb.append(getCleanUTF8String(tmp_field_value));
//end new code
//start old code
//sb.append(fields[i]);
//end old code
sb.append("\"");
}
return sb.toString();
}
public String getCleanUTF8String(String dirtyString){
String cleanString = "";
try {
byte[] cleanBytes = dirtyString.getBytes("UTF-8");
cleanString = new String(cleanBytes, "UTF-8");
cleanString = cleanString.replace("\"", "\\\"");
cleanString = cleanString.replace("'", "\\'");
} catch (UnsupportedEncodingException uee){
System.out.println("*******ERROR********: Unable to remove non UTF-8 characters in string: |" + dirtyString + "| -- Java Error Message:" + uee.getMessage());
//TODO - may need to revisit this next line, some additional character checks may need to take place if the character set exclusion fails.
cleanString = dirtyString;
}
return cleanString;
}
instead of doing tmp_field_value = (String) fields[i] do like below code.
if(fields[i]!=null){
tmp_field_value = fields[i].toString();
}
I was writing a program in Java to search for a piece of text
I took these 3 as inputs
The directory, from where the search should start
The text to be searched for
Should the search must be recursive (to or not to include the directories inside a directory)
Here is my code
public void theRealSearch(String dirToSearch, String txtToSearch, boolean isRecursive) throws Exception
{
File file = new File(dirToSearch);
String[] fileNames = file.list();
for(int j=0; j<fileNames.length; j++)
{
File anotherFile = new File(fileNames[j]);
if(anotherFile.isDirectory())
{
if(isRecursive)
theRealSearch(anotherFile.getAbsolutePath(), txtToSearch, isRecursive);
}
else
{
BufferedReader bufReader = new BufferedReader(new FileReader(anotherFile));
String line = "";
int lineCount = 0;
while((line = bufReader.readLine()) != null)
{
lineCount++;
if(line.toLowerCase().contains(txtToSearch.toLowerCase()))
System.out.println("File found. " + anotherFile.getAbsolutePath() + " at line number " + lineCount);
}
}
}
}
When recursion is set true, the program returns a FILENOTFOUNDEXCEPTION
So, I referred to the site from where I got the idea to implement this program and edited my program a bit. This is how it goes
public void theRealSearch(String dirToSearch, String txtToSearch, boolean isRecursive) throws Exception
{
File[] files = new File(dirToSearch).listFiles();
for(int j=0; j<files.length; j++)
{
File anotherFile = files[j];
if(anotherFile.isDirectory())
{
if(isRecursive)
theRealSearch(anotherFile.getAbsolutePath(), txtToSearch, isRecursive);
}
else
{
BufferedReader bufReader = new BufferedReader(new FileReader(anotherFile));
String line = "";
int lineCount = 0;
while((line = bufReader.readLine()) != null)
{
lineCount++;
if(line.toLowerCase().contains(txtToSearch.toLowerCase()))
System.out.println("File found. " + anotherFile.getAbsolutePath() + " at line number " + lineCount);
}
}
}
}
It worked perfectly then. The only difference between the two snippets is the way of creating the files, but they look the same to me!!
Can anyone point me out where I messed up?
In the second example it is used listFiles() whichs returns files. In your example it is used list() which returns only the names of the files - here the error.
The problem in the first example is in the fact that file.list() returns an array of file NAMES, not paths. If you want to fix it, simply pass file as an argument when creating the file, so that it's used as the parent file:
File anotherFile = new File(file, fileNames[j]);
Now it assumes that anotherFile is in the directory represented by file, which should work.
You need to include the base directory when you build the File object as #fivedigit points out.
File dir = new File(dirToSearch);
for(String fileName : file.list()) {
File anotherDirAndFile = new File(dir, fileName);
I would close your files when you are finished and I would avoid using throws Exception.
What's the most efficient way to trim the suffix in Java, like this:
title part1.txt
title part2.html
=>
title part1
title part2
This is the sort of code that we shouldn't be doing ourselves. Use libraries for the mundane stuff, save your brain for the hard stuff.
In this case, I recommend using FilenameUtils.removeExtension() from Apache Commons IO
str.substring(0, str.lastIndexOf('.'))
As using the String.substring and String.lastIndex in a one-liner is good, there are some issues in terms of being able to cope with certain file paths.
Take for example the following path:
a.b/c
Using the one-liner will result in:
a
That's incorrect.
The result should have been c, but since the file lacked an extension, but the path had a directory with a . in the name, the one-liner method was tricked into giving part of the path as the filename, which is not correct.
Need for checks
Inspired by skaffman's answer, I took a look at the FilenameUtils.removeExtension method of the Apache Commons IO.
In order to recreate its behavior, I wrote a few tests the new method should fulfill, which are the following:
Path Filename
-------------- --------
a/b/c c
a/b/c.jpg c
a/b/c.jpg.jpg c.jpg
a.b/c c
a.b/c.jpg c
a.b/c.jpg.jpg c.jpg
c c
c.jpg c
c.jpg.jpg c.jpg
(And that's all I've checked for -- there probably are other checks that should be in place that I've overlooked.)
The implementation
The following is my implementation for the removeExtension method:
public static String removeExtension(String s) {
String separator = System.getProperty("file.separator");
String filename;
// Remove the path upto the filename.
int lastSeparatorIndex = s.lastIndexOf(separator);
if (lastSeparatorIndex == -1) {
filename = s;
} else {
filename = s.substring(lastSeparatorIndex + 1);
}
// Remove the extension.
int extensionIndex = filename.lastIndexOf(".");
if (extensionIndex == -1)
return filename;
return filename.substring(0, extensionIndex);
}
Running this removeExtension method with the above tests yield the results listed above.
The method was tested with the following code. As this was run on Windows, the path separator is a \ which must be escaped with a \ when used as part of a String literal.
System.out.println(removeExtension("a\\b\\c"));
System.out.println(removeExtension("a\\b\\c.jpg"));
System.out.println(removeExtension("a\\b\\c.jpg.jpg"));
System.out.println(removeExtension("a.b\\c"));
System.out.println(removeExtension("a.b\\c.jpg"));
System.out.println(removeExtension("a.b\\c.jpg.jpg"));
System.out.println(removeExtension("c"));
System.out.println(removeExtension("c.jpg"));
System.out.println(removeExtension("c.jpg.jpg"));
The results were:
c
c
c.jpg
c
c
c.jpg
c
c
c.jpg
The results are the desired results outlined in the test the method should fulfill.
String foo = "title part1.txt";
foo = foo.substring(0, foo.lastIndexOf('.'));
BTW, in my case, when I wanted a quick solution to remove a specific extension, this is approximately what I did:
if (filename.endsWith(ext))
return filename.substring(0,filename.length() - ext.length());
else
return filename;
Use a method in com.google.common.io.Files class if your project is already dependent on Google core library. The method you need is getNameWithoutExtension.
you can try this function , very basic
public String getWithoutExtension(String fileFullPath){
return fileFullPath.substring(0, fileFullPath.lastIndexOf('.'));
}
String fileName="foo.bar";
int dotIndex=fileName.lastIndexOf('.');
if(dotIndex>=0) { // to prevent exception if there is no dot
fileName=fileName.substring(0,dotIndex);
}
Is this a trick question? :p
I can't think of a faster way atm.
I found coolbird's answer particularly useful.
But I changed the last result statements to:
if (extensionIndex == -1)
return s;
return s.substring(0, lastSeparatorIndex+1)
+ filename.substring(0, extensionIndex);
as I wanted the full path name to be returned.
So "C:\Users\mroh004.COM\Documents\Test\Test.xml" becomes
"C:\Users\mroh004.COM\Documents\Test\Test" and not
"Test"
filename.substring(filename.lastIndexOf('.'), filename.length()).toLowerCase();
Use a regex. This one replaces the last dot, and everything after it.
String baseName = fileName.replaceAll("\\.[^.]*$", "");
You can also create a Pattern object if you want to precompile the regex.
If you use Spring you could use
org.springframework.util.StringUtils.stripFilenameExtension(String path)
Strip the filename extension from the given Java resource path, e.g.
"mypath/myfile.txt" -> "mypath/myfile".
Params: path – the file path
Returns: the path with stripped filename extension
private String trimFileExtension(String fileName)
{
String[] splits = fileName.split( "\\." );
return StringUtils.remove( fileName, "." + splits[splits.length - 1] );
}
String[] splitted = fileName.split(".");
String fileNameWithoutExtension = fileName.replace("." + splitted[splitted.length - 1], "");
create a new file with string image path
String imagePath;
File test = new File(imagePath);
test.getName();
test.getPath();
getExtension(test.getName());
public static String getExtension(String uri) {
if (uri == null) {
return null;
}
int dot = uri.lastIndexOf(".");
if (dot >= 0) {
return uri.substring(dot);
} else {
// No extension.
return "";
}
}
org.apache.commons.io.FilenameUtils version 2.4 gives the following answer
public static String removeExtension(String filename) {
if (filename == null) {
return null;
}
int index = indexOfExtension(filename);
if (index == -1) {
return filename;
} else {
return filename.substring(0, index);
}
}
public static int indexOfExtension(String filename) {
if (filename == null) {
return -1;
}
int extensionPos = filename.lastIndexOf(EXTENSION_SEPARATOR);
int lastSeparator = indexOfLastSeparator(filename);
return lastSeparator > extensionPos ? -1 : extensionPos;
}
public static int indexOfLastSeparator(String filename) {
if (filename == null) {
return -1;
}
int lastUnixPos = filename.lastIndexOf(UNIX_SEPARATOR);
int lastWindowsPos = filename.lastIndexOf(WINDOWS_SEPARATOR);
return Math.max(lastUnixPos, lastWindowsPos);
}
public static final char EXTENSION_SEPARATOR = '.';
private static final char UNIX_SEPARATOR = '/';
private static final char WINDOWS_SEPARATOR = '\\';
The best what I can write trying to stick to the Path class:
Path removeExtension(Path path) {
return path.resolveSibling(path.getFileName().toString().replaceFirst("\\.[^.]*$", ""));
}
dont do stress on mind guys. i did already many times. just copy paste this public static method in your staticUtils library for future uses ;-)
static String removeExtension(String path){
String filename;
String foldrpath;
String filenameWithoutExtension;
if(path.equals("")){return "";}
if(path.contains("\\")){ // direct substring method give wrong result for "a.b.c.d\e.f.g\supersu"
filename = path.substring(path.lastIndexOf("\\"));
foldrpath = path.substring(0, path.lastIndexOf('\\'));;
if(filename.contains(".")){
filenameWithoutExtension = filename.substring(0, filename.lastIndexOf('.'));
}else{
filenameWithoutExtension = filename;
}
return foldrpath + filenameWithoutExtension;
}else{
return path.substring(0, path.lastIndexOf('.'));
}
}
I would do like this:
String title_part = "title part1.txt";
int i;
for(i=title_part.length()-1 ; i>=0 && title_part.charAt(i)!='.' ; i--);
title_part = title_part.substring(0,i);
Starting to the end till the '.' then call substring.
Edit:
Might not be a golf but it's effective :)
Keeping in mind the scenarios where there is no file extension or there is more than one file extension
example Filename : file | file.txt | file.tar.bz2
/**
*
* #param fileName
* #return file extension
* example file.fastq.gz => fastq.gz
*/
private String extractFileExtension(String fileName) {
String type = "undefined";
if (FilenameUtils.indexOfExtension(fileName) != -1) {
String fileBaseName = FilenameUtils.getBaseName(fileName);
int indexOfExtension = -1;
while (fileBaseName.contains(".")) {
indexOfExtension = FilenameUtils.indexOfExtension(fileBaseName);
fileBaseName = FilenameUtils.getBaseName(fileBaseName);
}
type = fileName.substring(indexOfExtension + 1, fileName.length());
}
return type;
}
String img = "example.jpg";
// String imgLink = "http://www.example.com/example.jpg";
URI uri = null;
try {
uri = new URI(img);
String[] segments = uri.getPath().split("/");
System.out.println(segments[segments.length-1].split("\\.")[0]);
} catch (Exception e) {
e.printStackTrace();
}
This will output example for both img and imgLink
private String trimFileName(String fileName)
{
String[] ext;
ext = fileName.split("\\.");
return fileName.replace(ext[ext.length - 1], "");
}
This code will spilt the file name into parts where ever it has " . ", For eg. If the file name is file-name.hello.txt then it will be spilted into string array as , { "file-name", "hello", "txt" }. So anyhow the last element in this string array will be the file extension of that particular file , so we can simply find the last element of any arrays with arrayname.length - 1, so after we get to know the last element, we can just replace the file extension with an empty string in that file name. Finally this will return file-name.hello. , if you want to remove also the last period then you can add the string with only period to the last element of string array in the return line. Which should look like,
return fileName.replace("." + ext[ext.length - 1], "");
public static String removeExtension(String file) {
if(file != null && file.length() > 0) {
while(file.contains(".")) {
file = file.substring(0, file.lastIndexOf('.'));
}
}
return file;
}