Remove certain characters from a directory's name in Java - java

So I wrote a little program to use on a Unix machine that has to get all the names of the files and folders in a directory where it is stored and then remove all the characters from them. These characters (or a character) will be defined by a user. Use case: I put the program in the directory containing various useless files and directories named, for example, "NaCl2!!!!!!!!!", "H2O!", "O2" and "Lithium!!!!!" and I "ask" it to get rid of all the bangs in all the directores' names so it will result in this:
ls
NaCl2 H2O O2 Lithium Unreal3.zip
Ok I guess you get it. So here's the code and it doesn't compile (
DirRename.java:18: error: method renameTo in class File cannot be applied to given types;
tempDir.renameTo(name);
). I guess this error is caused with a substantial problem in my code. Is there a way to get it working, can you tell me, please?
import java.io.*; import java.util.Scanner;
class DirRename {
public static void main(String[] s) {
//DECLARING
String name, curDir, annoyngChar;
Scanner scan = new Scanner(System.in);
//WORKING
curDir = System.getProperty("user.dir");
File dir = new File(curDir);
File[] listOfFiles = dir.listFiles();
System.out.print("Type a character (or a line of them) that you want to remove from directories' names:");
annoyngChar = scan.nextLine();
System.out.println("\nAll directories will get rid of " + annoyngChar + " in their names.");
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isDirectory() ) {
File tempDir = listOfFiles[i];
name = tempDir.getName().replaceAll(annoyngChar, "");
tempDir.renameTo(name);
}
}
}
}
Need to say, the program is unfinished, I am sorry for that.

File.renameTo(File dest) takes a File parameter, not a String. So, you need to create a File instance with the correct path (using the new name), and pass that instance to renameTo.
Try this (not tested):
import java.io.*; import java.util.Scanner;
class DirRename {
public static void main(String[] s) {
//DECLARING
String name, curDir, annoyngChar;
Scanner scan = new Scanner(System.in);
//WORKING
curDir = System.getProperty("user.dir");
File dir = new File(curDir);
File[] listOfFiles = dir.listFiles();
System.out.print("Type a character (or a line of them) that you want to remove from directories' names:");
annoyngChar = scan.nextLine();
System.out.println("\nAll directories will get rid of " + annoyngChar + " in their names.");
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isDirectory() ) {
File f = listOfFiles[i];
String oldName = f.getName();
name = oldName.replaceAll(annoyngChar, "");
if (!oldName.equals(name)) {
File newF = new File(dir, name);
f.renameTo(newF);
}
}
}
}
}
Alternatively, you can use Files.move to rename the file. The documentation has an example of how to rename a file while keeping it in the same directory.

Related

How to read content of files in directory using java and return the files which have particular keyword

In my code, I am able to list all the files from the folder on my pc but to check whether the keyword is present in those files I used indexOf() in StringBuffer. The problem I am facing is that desired output of filenames having that keyword is not getting printed.
I am not able to find where the error is or what mistake I am making.
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class ListOfFiles {
public static void main(String args[]) throws IOException {
// Creating a File object for directory
File directoryPath = new File("C:\\Users\\nanis\\Downloads\\New folder");
// List of all files and directories
File filesList[] = directoryPath.listFiles();
// System.out.println("List of files and directories in the specified directory:");
Scanner sc = null;
for (File file: filesList) {
// System.out.println("File name: "+file.getName());
// System.out.println("File path: "+file.getAbsolutePath());
// System.out.println("Size :"+file.getTotalSpace());
// Instantiating the Scanner class
sc = new Scanner(file);
String input;
StringBuffer sb = new StringBuffer();
while (sc.hasNextLine()) {
input = sc.nextLine();
sb.append(input + " ");
int integer = sb.indexOf("VM"); // the keyword is "VM" that I want to search
if (integer > 0) {
System.out.println("keyword is present in " + file.getAbsolutePath())
}
}
}
}
}
I think the problem is your scanner. You are taking user input input = sc.nextLine(); and to do that you need System.in. Also if I try to print something using sc it prints nothing and that would make while (sc.hasNextLine()) false therefore there is something wrong with your algorithm.
You are doing a search algorithm right? but you are inserting the while loop inside the for each loop. This doesn't work because in the first iteration of the for each loop only the first file is present and so if your search keyword is for the last file it will be false.
A basic search algorithm would be:
1. Input keyword to find
2. Loop through the lists to check if found
3. return either true or false
EDIT: You want to search the .txt files. It is the same concept. You need to store them all first. Not search while storing. If you have stored them you can now search them.
I changed the code to read txt files. Also your directory should only contain .txt files otherwise it will not work because you are reading the content of the files. In your case HashMap would be useful because you need to store two values. File name and the content of it.
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Scanner;
public class ListOfFiles {
public static void main(String args[]) throws IOException {
// Creating a File object for directory
File directoryPath = new File("C:\\Users\\nanis\\Downloads\\New folder\\");
// List of all files and directories
File filesList[] = directoryPath.listFiles();
// System.out.println("List of files and directories in the specified
// directory:");
Scanner sc = new Scanner(System.in);
Scanner myReader = null;
HashMap<String, String> fff = new HashMap<String, String>(); // storage for the file name and content
for (File file : filesList) {
File myObj = new File("C:\\Users\\nanis\\Downloads\\New folder\\" + file.getName());
myReader = new Scanner(myObj);
String read = "";
while (myReader.hasNextLine()) {
read += myReader.nextLine();
}
fff.put(file.getName(), read); // store file name and its contents
}
System.out.print("Search The File By Keyword:");
String find = sc.nextLine();
for (String i : fff.keySet()) {
if (fff.get(i).contains(find)) { // check the contents if it contains the keyword u are search for
File found = new File("C:\\Users\\nanis\\Downloads\\New folder\\" + i);
System.out.println("keyword is present in " + found.getAbsolutePath());
}
}
sc.close();
myReader.close();
}
}

Having a variable from another class as the file name (GUI)

One class of my GUI has a variable for the file name. I want to pass this to another class so that I can process a file without having to hard code the file's name every time. The program compiles fine but I can't seem to run it correctly.
public void run() {
WordsCounter2 fileName = new WordsCounter2();
essayName = fileName.getFileList();
File f = new File(essayName);
//other code
WordsCounter2 is the class that houses the variable fileName, I'm calling it from this class and assigning it as the file's name, but this doesn't work. Could someone help?
if (rVal == JFileChooser.APPROVE_OPTION) {
File[] selectedFile = fileChooser.getSelectedFiles();
fileList = "nothing";
if (selectedFile.length > 0)
fileList = selectedFile[0].getName();
for (int i = 1; i < selectedFile.length; i++) {
fileList += ", " + selectedFile[i].getName();
}
statusBar.setText("You chose " + fileList);
}
else {
statusBar.setText("You didn't choose a file.");
}
fileList isn't empty because I have a label on the GUI that lists whatever file I chose.
Here's my new edit: now the exception occurs at the last line with the scanner and throws a NPE. Can you help?
public void run() {
WordsCounter2 pathNamesList = new WordsCounter2();
essayName = pathNamesList.getPathNamesList();
essayTitle = new String[essayName.size()];
essayTitle = essayName.toArray(essayTitle);
for (int i = 0; i < essayTitle.length; i++) {
f = new File(essayTitle[i]);
}
try {
Scanner scanner = new Scanner(f);
Your code is failing because File will not accept comma separated file names, in fact, it needs a single file path to create the file in the mentioned path. See here: https://docs.oracle.com/javase/7/docs/api/java/io/File.html
You'll have to get complete paths in an array and put the file creation statement as follows:
File f;
for (int i=0; i<fileList.length; i++)
f = new File(fileList[i]);
where fileList is a String array holding the list of pathnames.
In case you're trying to write some content to these files as well, this should be helpful: Trying to Write Multiple Files at Once - Java

How to create a file object for which some part is always changing

I'd like to create a file object as follows
File file = new File("MyFile-abcdfg.txt");
where the string between - and . is random and always changing. The length is also not the same.
I want to check the file.exist(), but the problem is I am not sure what will be the name of the file, as it keeps on changing.
You can find the Possible solution over here.
List of files starting with a particular letter in java
Thanks
You can create a String variable for example like this:
String dynamicPartOfFileName = "abcdfg";
If you want to you can replace the literal "abcdfg" by any other mechanism (such as generating a randomized String).
And use it as part of the filename like this:
File file = new File("MyFile-" + dynamicPartOfFileName + ".txt");
The +-operator will join the Strings together. Afterwards the new File()-constructor will use the joined String.
You can use random numbers to randomly pick values from your possible file names.
Random rand = new Random();
int randomNumber = rand.nextInt(2); // 0-1.
String s1 = "-";
if(randomNumber == 0){
s1 = "_";
}
int nameLength = rand.nextInt(100); //0-99
String characters = "";
String possibleCharacters = "abcdefg";
for(int i = 0; i < nameLength; i++){
characters += possibleCharacters[rand.nextInt(possibleCharacters.length)];
}
String filename = "MyFile" + s1 + characters + ".txt";
File file = new File(filename);
if(file.exists() && !file.isDirectory()) {
// do something
}
As far as I can tell, your problem is not how to create the file name, but rather, how to check if a file with that possible name exists.
If you know the formation rule for the names (suppose "aBeginning" + "aDatePresentation" + "anEnd"), then you can test for possible files, such as
boolean checkFileToday(){
Date today = new Date();
String name = "aBeginning"+today.getDate()+"anEnd";
File file = new File(name);
return file.exists();
}
The following code, generates new file with the unique name.
import java.io.File;
import java.io.IOException;
import java.util.UUID;
public class DynamicFile {
public static void main(String[] args) throws IOException {
int i = 4;
do {
//UUID creates random string.
String randomID = UUID.randomUUID().toString();
File file = new File("A:/NewFolder/MyFile-" + randomID.substring(0, 5) + ".txt");
file.createNewFile();
} while (i-- > 0);
}
}
Will create files like:
MyFile-1d2ef.txt

Java iterative reading of Files

at the moment I'm having a problem with writing a tool for my company. I have 384 XML files that i have to read and parse with a SAX Parser into txt files.
What i got until now is the parsing of all XML-Files into one txt File, size 43 MB. With a BufferedReader and line.startsWith i want to extract all relevant information out of the textfile.
Edit: Done
(So my Problem is how to solve this more efficiently. I'm having an idea (but unfortunately not in code as you might think) but i dont know if its possible: I want to iterate through a Directory, find the XML-File i want, then parse it and create a new txt File with the parsed content. If done for all 384 XML files i want the same thing for the 384 txt files, read them with a BufferedReader to get my relevant information. Its important to read them one at a time. Another Problem is the Directory path, its a bit complex: "C:\Users\xxx\Documents\Data\ProjectName\A1\1\1SLin\wanted.xml" for each file there is a own directory. The variable is A1, it reaches from A-P and 1-24. Alternatively I have all the relevant files with thir absolute path in an arraylist, so its also okay to iterate over this list if its easier.)
Edit:
I came to a solution: Below contains the search directories method and a method to parse the xml Files of a List into the same directory with the same filename but another file extension
public List<File> searchFile(File dir, String find) {
File[] files = dir.listFiles();
List<File> matches = new ArrayList<File>();
if (files != null) {
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
matches.addAll(searchFile(files[i], find));
} else if (files[i].getName().equalsIgnoreCase(find)) {
matches.add(files[i]);
}
}
}
Collections.sort(matches);
return matches;
}
public static void main(String[] args) throws IOException {
Import_Files im = new Import_Files();
File dir = new File("C:\\Users\\xxx\\Desktop\\MS-Daten\\");
String name = "snp_result_5815.xml";
List<File> matches = im.searchFile(dir, name);
System.out.println(matches);
for (int i=0; i<matches.size(); i++) {
String j = String.valueOf(i);
String xml_name = matches.get(i).getAbsolutePath();
File f = new File(matches.get(i).getAbsolutePath().replaceFirst(".xml", ".txt"));
System.setOut(new PrintStream(new FileOutputStream(f)));
System.out.println("\nstarting File: "+ i + "\n");
xml_parse myReader = new xml_parse(xml_name);
myReader.setContentHandler(new MyContentHandler());
myReader.setErrorHandler(new MyErrorHandler());
myReader.run();
}
}
The searchFolder method below will take a path and file extension, search the path and all sub-directories, and pass any matching file types to the processFile method.
public static void main(String[] args) {
String path = "c:\\temp";
Pattern filePattern = Pattern.compile("(?i).*\\.xml$");
searchFolder(path, filePattern);
}
public static void searchFolder(String searchPath, Pattern filePattern){
File dir = new File(searchPath);
for(File item : dir.listFiles()){
if(item.isDirectory()){
//recursively search subdirectories
searchFolder(item.getAbsolutePath(), filePattern);
} else if(item.isFile() && filePattern.matcher(item.getName()).matches()){
processFile(item);
}
}
}
public static void processFile(File aFile){
String filename = aFile.getAbsolutePath();
String txtFilename = filename.substring(0, filename.lastIndexOf(".")) + ".txt";
//Do your xml file parsing and write to txtFilename
}
The complexity of the path makes no difference, just specify the root path to search (looks like C:\Users\xxx\Documents\Data\ProjectName in your case) and it will find all the files.

How to get files with a filename starting with a certain letter?

I wrote some code to read a text file from C drive directly given a path.
String fileName1 = "c:\\M2011001582.TXT";
BufferedReader is = new BufferedReader(new FileReader(fileName1));
I want to get a list of files whose filename starts with M. How can I achieve this?
"but how can i write a code that file is exist in local drive or not"
To scan a directory for files matching a condition:
import java.io.File;
import java.io.FilenameFilter;
public class DirScan
{
public static void main(String[] args)
{
File root = new File("C:\\");
FilenameFilter beginswithm = new FilenameFilter()
{
public boolean accept(File directory, String filename) {
return filename.startsWith("M");
}
};
File[] files = root.listFiles(beginswithm);
for (File f: files)
{
System.out.println(f);
}
}
}
(The files will exist, otherwise they wouldn't be found).
You can split the string based on the token '\' and take the second element in the array and check it by using the startsWith() method avaialble on the String object
String splitString = fileName1.split("\\") ;
//check if splitString is not null and size is greater than 1 and then do the following
if(splitString[1].startsWith("M")){
// do whatever you want
}
To check if file exist, you can check in File Class docs
In Nutshell:
File f = new File(fileName1);
if(f.exists()) {
//do something
}

Categories