How can I rename a file in Java? - java

My purpose is to rename one file. What I'm doing is: I'm searching a particular string in a text file. Among So many files and if that particular text is found then I want rename that text file with a given string.
Here is what I have tried:
String opcode="OPCODES"; // String that I want to search.
File file = new File("D:\\CFF1156"); // All files are inside this folder.
System.out.println("The File Name is :"+file.getName());
File[] f = file.listFiles();
System.out.println("The Length of File is :"+f.length);
Boolean flag=false;
StringBuffer contents = new StringBuffer();
BufferedReader reader = null;
for(int i=0;i<f.length;i++)
{
try{
reader = new BufferedReader(new FileReader(f[i]));
String text = null;
while ((text = reader.readLine()) != null)
{
if(text.contains(opcode))
{
System.out.println("Found");
System.out.println("The File Containing the Search text is :"+f[i]);
f[i].renameTo(new File("D://CFF1156/changed.txt"));
System.out.println("renamed :"+(f[i].renameTo(new File("D://CFF1156/changed.txt"))));
if(f[i].renameTo(new File("D://CFF1156/changed.txt")))
{
System.out.println("Successfully renamed");
}
else
{
System.out.println("Error");
}
}
}
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
finally
{
try
{
if (reader != null)
{
reader.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
The above code is searching the particular file. But I'm not able to rename it.
What would be a working Solution to this problem?

You are renaming with the same name, in a loop. Fix that thing first. Furthermore, take the returned boolean value in a variable by renameTo() method, and use that variable in your if.

I am having a hard time reading the code as given, but there is a renameTo method on File (see this javadoc). Note that it takes a File object representing the desired pathname, and returns a boolean.

From Javadoc of renameTo
..., it might not be atomic, and it
might not succeed if a file with the
destination abstract pathname already
exists.
You check the returned boolean in the second renameTo command. Remove all renameTo commands, or store the boolean of the first command and print this boolean to the console.

First thing, you sometimes use the \ and other times //, im on Mac, so not sure what you should use on Windows.
Second, you are renaming all the files to the same name.
Fix:
boolean renamed = f[i].renameTo(new File("D://CFF1156/changed"+ i + ".txt"));
System.out.println(renamed?"Succesfully renamed":"Error");

Related

How to rename a txt file using Java after copying contents from another txt file

I have created a program where there is a file called groups.txt. This file contains a list of names. To delete a group, it has to exist within the file. I used the Scanner method to search through each line for the name. If it contains the line, it sets val as 1. Which triggers the val == 1 condition. What I wanted to do during this block, is try to delete groupName from the groups.txt file. To do this, I created a new txt file called TempFile which copies all the names from groups.txt EXCEPT groupName. This file is then renamed to groups.txt and the old groups.txt file is deleted.
Everything works as intended, except the renaming. The temp.txt file still exists and the groups.txt file is unchanged. I checked the boolean success, and it always returns as false. Any ideas how to solve this?
if (method.equals("delete group")){
int val = 0;
String groupName = myClient.readLine();
try {
Scanner file = new Scanner(new File("groups.txt"));
while (file.hasNextLine()){
String line = file.nextLine();
if (line.indexOf(groupName) != -1){
val = 1;
}
}
if (val == 1){
try {
File groupFile = new File("groups.txt");
File tempFile = new File("temp.txt");
BufferedReader reader = new BufferedReader(new FileReader(groupFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile));
String currentLine;
System.out.println(groupName);
while ((currentLine = reader.readLine()) != null){
String trimLine = currentLine.trim();
if (trimLine.equals(groupName)){
continue;
} else {
writer.write(currentLine + System.getProperty("line.separator"));
}
}
writer.close();
reader.close();
groupFile.delete();
boolean success = tempFile.renameTo("groups.txt");
} catch (IOException f){
System.err.println("File Not Found: " + f.getMessage());
} }
} catch (FileNotFoundException f){
System.err.println("File Not Found Exception: " + f.getMessage());
}
}
CODE BEFORE THE ABOVE:
if (command.equals("group")){
String method = myClient.readLine();
if (method.equals("create group")){
String groupName = myClient.readLine();
int val = 0;
try {
Scanner file = new Scanner(new File("groups.txt"));
while (file.hasNextLine()){
String line = file.nextLine();
if (line.indexOf(groupName) != -1){
Report.error("group name already exists, please pick another");
val = 1;
}
}
} catch (FileNotFoundException f){
System.err.println("File Not Found: " + f.getMessage());
}
if (val == 0){
try {
PrintWriter out = new PrintWriter(new FileWriter("groups.txt", true));
out.println(groupName);
out.close();
} catch (IOException e){
Report.error("IOException: " + e.getMessage());
}
}
In the second part of the code, this is where I originally update the groups.txt file. So every time the user adds a group, it updates the groups.txt file by adding the new groupName to the end of the file. First, I make sure the groupName doesn't already exist using Scanner. myClient is a BufferedReader which reads from another class which stores what the user types in the command line.
Also do not forget to close Scanner. First you should make delete() work and make sure you know your current working directory, and write your filepath relative to it. Check with:
File file = new File("abc.txt");
System.out.println(file.getAbsolutePath());
One thing might be unrelated, also check your environment because
In the Unix'esque O/S's you cannot renameTo() across file systems. This behavior is different than the Unix "mv" command. When crossing file systems mv does a copy and delete which is what you'll have to do if this is the case. The same thing would happen on Windows if you tried to renameTo a different drive, i.e. C: -> D:

Check if a string/line that is going to write into a text file is already exist in the text file

I am analyzing a web access log and try to find out all the unique object (any file or any path) that were requested only once in the access log. Every time the program write into the text file, the content of the text file looks like this :
/~scottp/publish.html
/~ladd/ostriches.html
/~scottp/publish.html
/~lowey/
/~lowey/kevin.gif
/~friesend/tolkien/rootpage.html
/~scottp/free.html
/~friesend/tolkien/rootpage.html
.
.
.
I want to check if the line which is going to write into the text file is already exist in the text file. In order words, if it's does exist in the text file, then do nothing and skip it and analyze the next line. If not, then write it into the text file.
I tried to use equals or contains but it doesn't seems to be work, here's a little pieces of my code:
// Find Unique Object that were requested only once
if (matcher3.find()) {
if(!requestFileName.equals(bw.equals(requestFileName))) {
bw.write(requestFileName);
bw.newLine();
}
}
What should I do to actually perform a check ?
As #JB Nizet commented you should make use of Set
Set<String> set = new HashSet<String>();
BufferedReader reader = new BufferedReader(new FileReader(new File("/path/to/yourFile.txt")));
String line;
while((line = reader.readLine()) != null) {
// duplicate
if(set.contains(line))
continue;
set.add(line);
// do your work here
}
Perhaps something simple like this:
try (BufferedReader br = new BufferedReader(new FileReader(yourFilePath))) {
boolean lineExists = false;
String currentLine;
while ((currentLine = br.readLine()) != null) {
if (currentLine.trim().equalsIgnoreCase(requestFileName.trim())) {
lineExists = true;
break;
}
}
br.close();
if (!lineExists) {
bw.write(requestFileName);
bw.newLine();
}
}
catch (IOException e) {
// Do what you want with Exception...
}

How do I recursively iterate through a directory, once differentiating from a file? (Java)

So basically, I'm going to a file location, checking if its .txt. If it is then i read through that file. If it is a directory than I have to recursively and if verbose is true then I also have to output the files as i iterate through them. I am currently trying to list the files. but i keep getting "incompatible types:java.io.File[] cannot be converted to javo.io.File", but i can't think if any other way as i have to pass a file or a directory through the File parameter of collect. I'm not sure i even understand what the question is asking exactly.
Here is the question:
If file is an individual file whose name ends with the extension .txt, the method should read its contents as text one line at the time, passing each line to the previous extractIntegers method. Individual files whose name does not end with .txt should simply be ignored. If file is a directory, the method should recursively call itself for every file and directory inside that one. If the parameter verbose is set to true, the method should also output the name of each file and directory that it processes.
public static void collect(File file, Set<Integer> found, boolean verbose)
{
String fileName = file.getName();
String extension = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
String fileLine = "";
BufferedReader reader;
try{
reader = new BufferedReader(new FileReader(file));
if(extension.equals("txt"))
{
while((fileLine = reader.readLine()) != null)
{
extractIntegers(fileLine, found);
}
}
else if(file.isDirectory())
{
if(verbose = true)
{
System.out.println("Directory: " + file.getName());
collect(file.listFiles(), found, true);
}
else
{
collect(file.listFiles(), found, false);
}
}
}
catch(IOException e)
{
System.out.print("file/directory not found");
}
}
file.listFiles() returns an array of files. You have to pass them individually to your collect() method:
...
else if(file.isDirectory()) {
if (verbose)
System.out.println("Directory: " + file.getName());
for (File f : file.listFiles())
collect(f, found, verbose);
}
...
You are calling collect with an argument file.listFiles(), which returns an array of files. What I assume you want to do is call collect once for each file in your array of files.
Try replacing this:
collect(file.listFiles(), found, true);
with this:
for (File subFile : file.listFiles()) {
collect(file.listFiles(), found, true);
}
to do that. Make sure to replace the bad code both places it appears in your source code. Let me know if it doesn't work - I will investigate more.

Find a string (or a line) in a txt File Java

let's say I have a txt file containing:
john
dani
zack
the user will input a string, for example "omar"
I want the program to search that txt file for the String "omar", if it doesn't exist, simply display "doesn't exist".
I tried the function String.endsWith() or String.startsWith(), but that of course displays "doesn't exist" 3 times.
I started java only 3 weeks ago, so I am a total newbie...please bear with me.
thank you.
Just read this text file and put each word in to a List and you can check whether that List contains your word.
You can use Scanner scanner=new Scanner("FileNameWithPath"); to read file and you can try following to add words to List.
List<String> list=new ArrayList<>();
while(scanner.hasNextLine()){
list.add(scanner.nextLine());
}
Then check your word is there or not
if(list.contains("yourWord")){
// found.
}else{
// not found
}
BTW you can search directly in file too.
while(scanner.hasNextLine()){
if("yourWord".equals(scanner.nextLine().trim())){
// found
break;
}else{
// not found
}
}
use String.contains(your search String) instead of String.endsWith() or String.startsWith()
eg
str.contains("omar");
You can go other way around. Instead of printing 'does not exist', print 'exists' if match is found while traversing the file and break; If entire file is traversed and no match was found, only then go ahead and display 'does not exist'.
Also, use String.contains() in place of str.startsWith() or str.endsWith(). Contains check will search for a match in the entire string and not just at the start or end.
Hope it makes sense.
Read the content of the text file: http://www.javapractices.com/topic/TopicAction.do?Id=42
And after that just use the textData.contains(user_input); method, where textData is the data read from the file, and the user_input is the string that is searched by the user
UPDATE
public static StringBuilder readFile(String path)
{
// Assumes that a file article.rss is available on the SD card
File file = new File(path);
StringBuilder builder = new StringBuilder();
if (!file.exists()) {
throw new RuntimeException("File not found");
}
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(file));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return builder;
}
This method returns the StringBuilder created from the data you have read from the text file given as parameter.
You can see if the user input string is in the file like this:
int index = readFile(filePath).indexOf(user_input);
if ( index > -1 )
System.out.println("exists");
You can do this with Files.lines:
try(Stream<String> lines = Files.lines(Paths.get("...")) ) {
if(lines.anyMatch("omar"::equals)) {
//or lines.anyMatch(l -> l.contains("omar"))
System.out.println("found");
} else {
System.out.println("not found");
}
}
Note that it uses the UTF-8 charset to read the file, if that's not what you want you can pass your charset as the second argument to Files.lines.

How to get the last modified file from a list of files

I have list of text files in a directory carrying user name and phone number.Every time user changes phone number its saved in new file in same directory.Now i'm searching for
an user whose entry is present in multiple files.How do i find the name of last modified file..?
below is snippet of code that i hav currently come up with.
public static String queryFile() throws IOException{
File directory = new File("E:\\idm\\users\\output");
Boolean isUserPresent = false;
String queryUser = "Mar25-user6";
ArrayList arr = new ArrayList();
if(directory.isDirectory())
{
File[] fileNames = directory.listFiles();
for(int i=0;i<fileNames.length;i++)
{
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(fileNames[i])));
while((line = reader.readLine()) != null)
{
if(line.contains(queryUser))
{
arr.add(fileNames[i]);
}
}
}
/*
how to check the last modified file from among files present in Arraylist arr.
*/
if (arr.isEmpty)
{
isUserPresent = false;
return "";
}
else
{
isUserPresent = true;
// return name of file if user present
}
}
}
Going through the javadoc i found File.lastModified() function.Is comparing the value returned by this function the only option..?
You can use this code in your else block to return the newest file which contained the username (arr is the list had the names of all the files that contained the username):
Collections.sort(arr, new Comparator<File>() {
#Override
public int compare(String file1, String file2) {
return Long.valueOf(new File(file2).lastModified()).compareTo(
new File(file1).lastModified());
}
});
arr.get(0); //
I would do it like this
File lastModified = null;
for (File file : directory.listFiles()) {
if (file.isFile()) {
BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream(file)));
try {
for (String line; (line = reader.readLine()) != null;) {
if (line.contains(queryUser)) {
arr.add(file);
if (lastModified == null
|| file.lastModified() > lastModified
.lastModified()) {
lastModified = file;
}
}
}
} finally {
reader.close();
}
}
}
Use file.lastModified() for getting last date modified for each file and then compare with each other
Java does not have off the shelf API for this work but it can easily be implemented by putting some logic around dates by using the .lastModified() method or you can also use Apache FileUtils. I would recommend using Apache Utils.
I would go something like this:
Declare a List for files containing data matching your query
Iterate through the Directory and put file matching in the List above
Finally, Iterate through the first List and check the greatest modified date
This is just an idea you can also achieve same by just iterating through the directory list.
To get the last modified timestamp for a File object, you would indeed invoke the lastModified() method. You already have an ArrayList of files, so traversing it to find the last modified field should be trivial. You're also already looping the list of files, so there should't be a need to loop again and find the last modified file. I would also suggest a few other optimizations of your code:
List<File> fileNames = new ArrayList<File>(); // I would rather call this variable "files" though
long latestModified = -1;
File lastModifiedFile = null;
// ...
for(File file : directory.listFiles()) {
// Do your magic
if(line.contains(queryUser)) {
filesNames.add(file);
if(file.lastModified() > latestModified) {
lastModifiedFile = file;
latestModified = file.lastModified();
}
}
}
// After the loop, the latest modified file will be held i the variable `lastModifiedFile`
I'm not sure what the purpose of the ArrayList is, but maybe you can get rid of it all together.

Categories

Resources