Ok, I have a pretty common function to check all files from a path (including sub-folders). In the given path I have multiple folders, like Folder1, Folder2, Folder3... Foldern, and I want to skip Folder2 for example. What is the best method to do that? Down below is my function.
public void loadFileRecursiv(String pathDir)
{
File fisier = new File(pathDir);
File[] listaFisiere = fisier.listFiles();
for(int i = 0; i < listaFisiere.length; i++)
{
if(listaFisiere[i].isDirectory())
{
loadFileRecursiv(pathDir + File.separatorChar + listaFisiere[i].getName());
}
else
{
String cuExtensie = listaFisiere[i].getName();
int pos = cuExtensie.lastIndexOf(".");
String nume = cuExtensie.substring(0, pos);
String acronimBanca = nume.split("_")[0];
String tipAct = nume.split("_")[1];
String dataActString = nume.split("_")[2];
SimpleDateFormat old = new SimpleDateFormat("dd-MM-yyyy");
SimpleDateFormat newPattern = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String dataFormatata = null;
try
{
dataFormatata = newPattern.format(old.parse(dataActString));
}
catch(ParseException e)
{
e.printStackTrace();
}
//String denBanca = inlocuireAcronim(acronimBanca);
processFolder(acronimBanca, acronimBanca);
insertData(listaFisiere[i], nume, acronimBanca, tipAct, dataFormatata);
System.out.println("AICI =========== " + pathDir + File.separatorChar + listaFisiere[i].getName());
moveFile(pathDir + File.separatorChar + listaFisiere[i].getName(), "/u02/ActeConstitutive/Mutate/");
}
}
}
I would advice you to use a Set containing the folders you want to skip.
// get the folders you want to avoid and add them to your set
File Folder2 = new File(pathName);
Set<File> folderToSkip = new HashSet<File>();
folderToSkip.add(Folder2);
// add as many other folders you want to avoid
And then in the for loop, you can check whether or not you want to go inside this folder
for(int i = 0; i < listaFisiere.length; i++){
if(!folderToSkip.contains(listaFisiere[i]){
// do your stuff...
}
}
Whilst your approach is recursive, the recursive part only applies to folder levels. You can skip over a loop operation via the
continue
keyword. Such as below:
for(int i = 0;i<5;i++){
if(i == 0){
continue;
}
System.out.println(i);
}
would skip over 0, the first operation, and output the following
1
2
3
4
Example here
This allows you to build a more modular loop, in my opinion it looks better than
for(int i = 0;i<5;i++){
if(i != 0){
System.out.println(i);
}
}
especially when nesting more conditionals or loops within, like so:
for(int i = 0;i<5;i++){
if(i != 0){
if(i != 0){
if(i != 0){
if(i != 0){
if(i != 0){
// stuff
}
}
}
}
}
}
Do it like this:
for(int i = 0; i < listaFisiere.length; i++)
{
if(listaFisiere[i].isDirectory())
{
if (!listaFisiere[i].getName().equalsIgnoreCase("Folder2"))
loadFileRecursiv(pathDir + File.separatorChar + listaFisiere[i].getName());
}
else
{
add an if statement at the first of method.
public void loadFileRecursiv(String pathDir)
{
if(new File(pathDir).isDirectory() && skip(pathDir))
return;
and make skip method which takes the path and checks that if you want to skip that folder or not; which returns a boolean. true means skip that.
Related
I've been writing code that manually prints json (without the json library) after reading a CSV. It's to understand the structure for a project of this scale, which involves IO and Exception handling.
So, I've been debugging this snippet of code since yesterday. I've identified the problem, but have not been able to solve it.
I currently have an infinite loop after the exception message is printed. For context, in the part of the code that is missing, the user inputs the number of files and it creates an array of files. The snippet of code inside my message is a method which verifies if a csv has a an empty field. Count is there to count the line numbers, if count == 1 and there is an empty field, it will throw CSVFileInvalidException, which is a custom exception I made for this project. If count is bigger than 1, it throws CSVDataMissingException, i.e. another custom exception.
The timeline of the debugging goes as follows:
At first, when I had the infinite loop, I thought the regex caused my error, since I heard it could be badly implemented. I checked and each element is exactly what I want (a string, which represents a field in the csv). So, it wasn't regex since the behavior was normal.
Secondly, I realized I accidentally put my try block was inside my while loop, so I put it on the outside. No Luck. The issue still persisted.
Then, I figured out the issue. It read the line handled the exception and since there was no failsafe to exit the while loop, it did so non-stop. So, I added an exit condition for the while loop. So, I added
if ((count > 1) && (s.nextLine() == null || s.nextLine().equals(""))) {
break;
}
This checks if the line number is higher than 1 and if the nextLine is null or empty. I thought this had solved the infinite loop problem that I had. Once I implemented this, nothind after the regex ended up being outputted. I checked with multiple println().
I then realized I made a typo in one of the for loops. Now, I'm back to the same behavior it exhibited earlier. It's redoing the same sequence inside the while loop again. In this case, it's looping the message from CSVFileInvalidException, so i.e. "The file called : " + f[i] + " is invalid. A field is missing. The file is not converted to JSON."
So, I'm assuming there's something that doesn't make sense logically. I've tried multiple solutions and the exceptions are now never reached.
Sorry for the long code, the element that is being repeated is at the bottom, and everything else is inside the while loop, so I'm not sure if it's something I implemented there.
for (int i = 0; i < f.length; i++) {
int count = 1;
try {
while (s.hasNextLine()) {
lines = s.nextLine();
if ((count > 1) && (s.nextLine() == null || s.nextLine().equals(""))) {
break;
}
//isolate the commas, and remove the quotes and extra space, so that the text remains clean and similar
String[] line_parts = lines.replaceAll("^\"", "").split("\"?(,|$)(?=(([^\"]*\"){2})*[^\"]*$) *\"?", -1);
Cloned_Elements[] cloned_elements_array = new Cloned_Elements[line_parts.length];
for (int z = 0; z < cloned_elements_array.length; z++) {
String[] array_ofstring = new String[line_parts.length];
for (int x = 0; x < array_ofstring.length; x++) {
array_ofstring[x] = "lol";
}
cloned_elements_array[z] = new Cloned_Elements(array_ofstring);
}
for (int j = 0; j < line_parts.length - 1; j++) {
if (count == 1) {
if (line_parts[j].equals("") || line_parts[j] == null) {
ce.setCloned_array(line_parts);
throw new CSVFileInvalidException("The file called : " + f[i] + " is invalid. A field is missing. The file is not converted to JSON.");
} else {
if (j < line_parts.length) {
String[] length_1 = cloned_elements_array[j].getCloned_array();
cloned_elements_array[j].setCloned_array(line_parts);
}
}
} else {
if (line_parts[j].equals("") || line_parts[j] == null) {
ce.setCloned_array(line_parts);
throw new CSVDataMissingException("In file " + f[i] + ", there is missing data in line #" + (count) + ". Thus, the file is not converted to JSON.");
} else {
if (j < line_parts.length) {
cloned_elements_array[j].setCloned_array(line_parts);
}
}
}
}
count++;
}
} catch (CSVDataMissingException e2) {
System.err.println(e2.getMessage());
try {
p = new PrintWriter(new FileOutputStream(js[js.length - 1], true));
int line_nb = count+1;
String[] error_array = ce.resize_string_arr();
for (int x = 0; x < error_array.length; x++) {
if (error_array[x].equals("") || error_array[x] == null) {
error_array[x] = "xxx";
}
}
p.println("In file " + f[i] + " ,line " +line_nb + " is missing an element.");
for (int z = 0; z < error_array.length; z++) {
p.print(error_array[z] + " ");
}
p.println();
p.println();
break;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} catch (CSVFileInvalidException e1) {
System.err.println(e1.getMessage());
try {
p = new PrintWriter(new FileOutputStream(js[js.length - 1], true));
p.println("File " + f[i] + " is invalid.");
String[] error_array = ce.resize_string_arr();
for (int x = 0; x < error_array.length; x++) {
if (error_array[x].equals("") || error_array[x] == null) {
error_array[x] = "xxx";
}
}
p.println("Field is missing : " + error_array.length + " detected, 1 is missing.");
for (int z = 0; z < error_array.length; z++) {
p.print(error_array[z] + " ");
}
p.println();
p.println();
break;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
For a project in school (intro to java), we have to make a program using arrays. I decided to make a login program that stores logins. It works perfectly, except when deleting items. This is my code
public void delete() throws FileNotFoundException{
int p;
c.clear();
c.print("Please enter a website to delete it's login info: ");
String delete_name = c.readLine();
Boolean found = false;
// Search for the search key, and display the matching elements
c.println("Searching for " + delete_name + "...");
for (int i = 0; i < pass.length; i++)
if (pass[i][0].equals(delete_name)) {
c.println("Deleting login for " + pass[i][0]);
String new_array[][] = new String[pass.length - 1][3];
//remove an element
for (int w = 0; i < new_array.length; i++)
for (int j = 0; j <= 2; j++) {
p = w;
if (i >= p) {
new_array[w][j] = pass[w + 1][j];
} else {
new_array[w][j] = pass[w][j];
}
}
found = true;
pass = new_array;
}
if (found == false) {
c.println("No luck! " + delete_name + " wasn't found, please try again.");
delete();
}
fileWriter();
}
When it writes to the file, anything after the part that should have been deleted gets changed to "null".
Sorry if the format is awful, I'm just starting with java :) Any help is greatly appreciated, thanks!
When deleting a row of a 2D array in Java, you can use this shortcut (no for-loops needed)
List<String[]> tempArr = new ArrayList<String[]>(Arrays.asList(pass));
//Remove row at index of "delete_name":
for(int i = 0; i < pass.length; i++){
if(pass[i][0].equals(delete_name)){
tempArr.remove(i);
}
}
String[][] new_array = tempArr.toArray(new String[][]{});
However, this solution only works if you are only deleting one object in the List. I would suggest looking into "iterators" to make this solution better.
EDIT:
Here is an example with an iterator
String[][] pass = new String[][]{{"Name","data1","data2"}};
List<String[]> tempArr = new ArrayList<String[]>(Arrays.asList(pass));
for (Iterator<String[]> iterator = tempArr.iterator(); iterator.hasNext();) {
String id = iterator.next()[0];
if (id.equals(delete_name)){
iterator.remove();
}
}
I need to be able to count a line every time text is wrapped. I am using the javaFX "TextArea" control.
I have implemented a counter that is incremented every time a "\n" character is encountered. Unfortunately, this ignores the additional lines created due to text wrapping.
There IS a way to circumvent this using the jtextarea swing control, which is similar to javafx's text area, but I don't really want to use it because the FX version has other pieces of functionality which are much better suited to my tasks.
If anyone has any suggestions about how to increment this counter, please let me know! Alternatively, another way to count lines would be just as effective.
(I'm using scene builder 2.0 in conjunction with Netbeans 8.1/8.0.2 (both))
I had to manually put in the newline characters as follows:
String pText = Primary.getText();
Primary.clear();
StringReader reader = new StringReader(pText);
BufferedReader br = new BufferedReader(reader);
//FileReader reader = new FileReader(fileLocation);
//BufferedReader br = new BufferedReader(reader);
String s;
int index = 0;
//int charCounter = 0;
boolean endOfPara = false;
// int index = 0;
// boolean endOfPara = false;
try{
//loads the text and formats it if necessary
while((s = br.readLine()) != null)
{
index = 0;
//loading block
if(s.length() <= characterCapacity)
{
//String s = "abcdefg";
int result = s.indexOf('\n');
if(result == -1)
{
Primary.appendText(s + "\n");
}
else
{
Primary.appendText(s);
}
}
//formatting block
else
{
while(index < s.length()) //change this
{
if((index == characterCapacity) && (index < s.length() - 1))
{
while(s.charAt(index) != ' ')
{
index--;
}
String n = s.substring(0, index);
s = s.substring(index);
//if(n.charAt(n.length() - 1) == '\n')
//{
// Primary.appendText(n);
//}
//else
//{
Primary.appendText(n + "\n");
//}
index = 0;
}
else if((index == s.length() - 1) && (index <= characterCapacity) && (s.length() > 0))
{
Primary.appendText(s + "\n");
index = s.length(); //OR use break;
endOfPara = true;
Primary.forward();
Primary.deletePreviousChar();
}
else
{
index++;
}
/*if(charCounter > 90)
{
if((charCounter >= 90) && (s.charAt(index) != )
{
}
if(index == (s.length() - 1))
{
}
else
{
charCounter++;
}
}*/
}
/*if(endOfPara == true)
{
if(s.charAt(index - 2) != '\n')
{
Primary.appendText("\n");
}
}
endOfPara = false;*/
}
}
}
catch(Exception e)
{}
I had a previous version of this which worked A LOT better, but unfortunately, it would insert newline characters in the middle of words, in some cases.
So yeah, in a nutshell, this is why I want to use a third party library to "get row number"/"get total rows", or find some way to do it using textarea skin.
Please Help! I am really stuck on this...
I was working on writing a recursive program which will take a path as input. Then it will search exhaustively all files and folders under it no matter in which depth the files and folders are in.
I've already written a java program given below :
void RecursiveFileSearch(File f, String d) {
int i;
String s[] = f.list();
for (i = 0; i < s.length; i++) {
File fs = new File(d + "/" + s[i]);
if (fs.isDirectory()) {
System.out.println("#DIRECTORY :"+s[i]);
d += "/" + s[i];
RecursiveFileSearch(fs, d);
} else {
System.out.println("#FILE : "+s[i]);
}
}
}
This function is called from outside like :
String sourceDirectoryPath = "D:";
File sourceFile = new File(sourceDirectoryPath);
RecursiveFileSearch(sourceFile,sourceDirectoryPath);
But the problem is that searches only the files and folders under the source directory only. It doesn't go into further depth.
Am I missing something?
Why don't you just use the APIs the JDK has for you?
With Java 8, it is as simple as:
try (
final Stream<Path> stream = Files.walk(baseDir);
) {
stream.forEach(path -> System.out.printf("%s: %s\n",
(Files.isDirectory(path) ? "DIRECTORY": "FILE"), path));
}
The problem is that the String variable d gets changed in each recursive call to the method, each time appending a directory name to the previous directory. You can solve this by defining a new String variable instead of re-using the same one:
void RecursiveFileSearch(File f, String d) {
int i;
String s[] = f.list();
for (i = 0; i < s.length; i++) {
File fs = new File(d + "/" + s[i]);
if (fs.isDirectory()) {
System.out.println("#DIRECTORY :"+s[i]);
String d2 = d + "/" + s[i];
RecursiveFileSearch(fs, d2);
} else {
System.out.println("#FILE : "+s[i]);
}
}
}
I dont know why you make thes work arround with Strings. Use "getAbsoluteFile" to geht the Path as a String befor you print it to the console and work only on File Objects in the programming logic. That will make your code mutch cleaner.
void RecursiveFileSearch(File f) {
File[] list = f.listFiles();
for (File elem : list) {
if (elem.isDirectory()) {
System.out.println("#DIRECTORY:"+elem.getAbsoluteFile());
RecursiveFileSearch(x);
} else {
System.out.println("#FILE : "+elem.getAbsoluteFile());
}
}
}
Edit: Deleted the now useless declaration if i.
This should work:
void RecursiveFileSearch(File f, String d) {
int i;
String s[] = f.list();
for (i = 0; i < s.length; i++) {
File fs = new File(d + "/" + s[i]);
if (fs.isDirectory()) {
System.out.println("#DIRECTORY :"+s[i]);
RecursiveFileSearch(fs, d + "/" + s[i]);
} else {
System.out.println("#FILE : "+s[i]);
}
}
}
I am writing a program that reads a text file which contains match results, and then should output them in a table. I have a While loop within a While loop:
Scanner fileread1 = new Scanner(new File("demo.txt"));
int x = 0;
int y = 22;
int i = 0;
while (x <= y) {
while (fileread1.hasNext()) {
fileinput = fileread1.nextLine(); // this reads the next line of
// from the file
String line = fileinput;
String[] split = line.split(":");
boolean result = false;
int homescore1 = 0;
int awayscore1 = 0;
int goalsscored = 0;
boolean att = false;
boolean htt = false;
int atscore = 0;
int htscore = 0;
// When the text line is read, it is then split into four sections.
if (split.length == 4) {
// String text = line.trim();
String userteam = userteaminput;
String hometeam = split[0].trim();
String awayteam = split[1].trim();
String home_score = split[2].trim();
String away_score = split[3].trim();
// this is a test to try convert the goals string into a
// integer. If this fails, the result is not
// not valid and does not get outputted to the console.
try {
homescore1 = Integer.parseInt(home_score);
awayscore1 = Integer.parseInt(away_score);
result = true;
}
catch (NumberFormatException exception) {
// if the try is not able to convert, this will run
errors++;
}
if (userteam.equals(Teams.get(i))) {
if (awayteam.equalsIgnoreCase(userteam)) {
att = true;
games++;
goalsfor = goalsfor + awayscore1;
goalsagainst = goalsagainst + homescore1;
}
if (att == true && awayscore1 > homescore1) {
atwc++;
gameswon++;
}
else if (att == true && awayscore1 < homescore1) {
htwc++;
gameslost++;
}
else if (att == true && awayscore1 == homescore1) {
gamesdrawn++;
}
if (hometeam.equalsIgnoreCase(userteam)) {
htt = true;
totaluser++;
games++;
goalsfor = goalsfor + homescore1;
goalsagainst = goalsagainst + awayscore1;
}
if (htt == true && homescore1 > awayscore1) {
atwc++;
gameswon++;
}
else if (htt == true && homescore1 < awayscore1) {
htwc++;
gameslost++;
}
else if (htt == true && awayscore1 == homescore1) {
gamesdrawn++;
}
}
}
else {
errors++;
}
}
// ********************************************************************
// Leeds IF Statement
// ********************************************************************
if (Rhinos.equals(Teams.get(i)) {
Rhinos.goalsfor = Rhinos.goalsfor + goalsfor;
Rhinos.gameswon = Rhinos.gameswon + gameswon;
Rhinos.gameslost = Rhinos.gameslost + gameslost;
Rhinos.goalsagainst = Rhinos.goalsagainst;
Rhinos.gamesplayed = Rhinos.gamesplayed + games;
}
else if (Bulls.equals(Teams.get(i)) {
Bulls.goalsfor = Bulls.goalsfor + goalsfor;
Bulls.gameswon = Bulls.gameswon + gameswon;
Bulls.gameslost = Bulls.gameslost + gameslost;
Bulls.goalsagainst = Bulls.goalsagainst;
Bulls.gamesplayed = Bulls.gamesplayed + games;
}
x++;
i++;
goalsfor = 0;
gameswon = 0;
gameslost = 0;
gamesagainst = 0;
}
I know that there are only ever going to be 22 teams that have results in the text file supplied, so the first loop should run for 22 times.
The inner loop, will continue whilst the file provided has a next line. The text file may sometimes have more lines of results then other files. Within this loop, I have a reference to an Array item:
if (userteam.equals(Teams.get(i)))
In the first run, this will refer to 0 in my Array which, for the record, is Leeds Rhinos. Once the inner loop has completed, it then moves onto the outer loop - this deals with the results just recorded. If the current team is Leeds Rhinos, it should then add the values. The i should then have 1 added, so for the next loop, it refers to the index of 1 of the array, not 0. (I have more IF statements here, all identical but refer to other teams) Variables get set back to 0, ready for the next run.
The issue I have, is that i does not seem to have 1 added each time it runs through, so I am only getting results passed through for one team. If I manually specify which array index to look (say 3) it will run through, and the team will have their results successfully recorded.
Is there a way I can get 1 added to i every time it loops? I'm not sure if this is the correct java loop to use, but to me, seemed the most logical. There are some objects not declared here - this is just a snippet of the code, left out the declarations as I know they work, and there's a lot declared.
If you're worried about failed incrementation, it would be better to use a For loop.
Instead of having a while (x < y) and sticking an increment statement somewhere in your code,
a
for (i = 0; i < y; i++) { // do tests here }
loop will guarantee that you always increment and run the test for the next team.
For future reference, when using while loops and incrementing, the incrementation is almost always done at the END of the while loop, and not somewhere in between. The incrementation statement should also almost never be in a conditional statement (which might cause an infinite loop).
Your question is not clear. But let's point out something in the code you provided
1) What is the difference between your if and else if statement? They are checking exact same thing
if (userteam.equals(Teams.get(i)) {
Rhinos.goalsfor = Rhinos.goalsfor + goalsfor;
Rhinos.gameswon = Rhinos.gameswon + gameswon;
Rhinos.gameslost = Rhinos.gameslost + gameslost;
Rhinos.goalsagainst = Rhinos.goalsagainst;
Rhinos.gamesplayed = Rhinos.gamesplayed + games;
}
else if (userteam.equals(Teams.get(i)) {
Bulls.goalsfor = Bulls.goalsfor + goalsfor;
Bulls.gameswon = Bulls.gameswon + gameswon;
Bulls.gameslost = Bulls.gameslost + gameslost;
Bulls.goalsagainst = Bulls.goalsagainst;
Bulls.gamesplayed = Bulls.gamesplayed + games;
}
2) What are you doing with variable x, I don't see anywhere you are increasing it.
3) On very first run, when x<=y, the inner loop will finish reading all lines, so even if you increase the X some point, from second run the inner loop will not execute. As it already finished reading all lines. So no point doing this
Again if you provide some more inside on what you want to accomplish, may be with the sample text file data, that would probably help answering your question.
Thank you.
Your formatting is working against you here; properly indented, your code structure is something like this (note, I had to add in missing closing braces, }, at the end of the code you provided as I assume you just missed them when you copied your code over):
Scanner fileread1 = new Scanner(new File("demo.txt"));
int x = 0;
int y = 22;
int i = 0;
while (x <= y) {
while (fileread1.hasNext()) {
fileinput = fileread1.nextLine(); // this reads the next line of
/* stuff */
if (split.length == 4) {
/* stuff */
x++;
i++;
}
}
}
Your incrementation of x and i is nested within if (split.length == 4) {, meaning that x and i will only be incremented in that specific case and not at the end of each iteration of the inner while loop.