Reputation: 1
Trying to reverse a file line by line
public static void main(String[] args) throws FileNotFoundException {
System.out.println("filname: ");
Scanner input = new Scanner(System.in);
String filnamn = input.nextLine();
File file = new File(filnamn);
Scanner inputFile = new Scanner(file);
PrintWriter writer = new PrintWriter(file);
while (input.hasNextLine()) {
String fil = input.next();
int reverse = 0;
for (int i = fil.length(); i >= 0; i--) {
reverse = reverse + fil.charAt(i);
writer.print(reverse);
}
}
inputFile.close();
writer.close();
input.close();
}
When trying to reverse my file it just get erased instead of it being backwards
Upvotes: 0
Views: 300
Reputation: 9192
It's not quite clear if it is each entire line that is in the file that is to be revered or each word within each line is to be reversed, there is a major difference between the two. In any case the method provided below can do either.
You can not write to the file you are reading from, you will need to provide a different file name. What you can do however is when the new file is created and your code has closed both the reader and writer, you can delete the original file and then rename the new file with the name of the original file. As you will see, this is only a few small lines of code.
You're reading the User's input instead of the input file. This is why it's important to give clear, distinguishable, and meaningful names to your variables like reader instead of inputFile which is close to the Scanner Keyboard input name of input). It can be easy to make mistakes if the variable names are similar or non-descriptive.
Here is the method:
/**
* Rewrites the supplied file into a new file where every word in that file
* has its characters reversed. The new file created (in the same directory)
* is named exactly the same except it will contain the file name extension
* of ".temp" unless, the `overwriteFile` option was passed boolean true in
* which case the original file is overwritten.<br><br>
*
* This method will need to be wrapped within a try/catch block.<br>
*
* @param fileName (String) the full path and file name (including file name
* extension) to the file which is to be reversed.<br>
*
* @param options (optional - Boolean - Two of):<pre>
*
* reverseEntireLine - Default is false where each word in each file line
* will be separately reversed. If boolean true is
* optionally supplied then each entire line is
* reversed. If null is supplied then false is implied.
*
* Whitespacing (indents, etc) in the file is also
* taken into consideration and maintained.
*
* overwriteFile - Default is false where the original file being
* read is not overwriten with reversed text but
* instead a new file is created under the same name,
* within the same directory, containing a file name
* extension of ".temp". If boolean true is supplied
* to this optional parameter then the original file
* will be overwriten. It should be noted that there
* is no actual overwrite. The original file is actually
* deleted and then the new file is renamed to the
* original file name. This will allow for extremely
* large files to be overwriten without the worry of
* memory exhaustion.<pre>
*
* @throws FileNotFoundException
* @throws IOException
*/
public static void reverseFile(String fileName, Boolean... options)
throws FileNotFoundException, IOException {
// false = each word in line | true = entire line.
boolean reverseEntireLine = false;
// false = Not Overwrite File | true = Overwrite File.
boolean overwriteFile = false;
if (options.length > 0) {
if (options.length >= 1 && options[0] != null) {
reverseEntireLine = options[0];
}
if (options.length >= 2 && options[1] != null) {
overwriteFile = options[1];
}
}
File fileToRead = new File(fileName); // Create a File object.
/* Create a name for a temporary file to write in
within the same path of the file we are about
to read. This name will be the same but will
have the file name extension of ".temp". */
String fullPath = fileToRead.getAbsolutePath();
String tempFile = fullPath.substring(0, fullPath.lastIndexOf(".")) + ".temp";
/* You can not write to the file you are reading from.
Provide a different (temporary) name. */
/* 'Try With Resources' is used here for both the reader and writer so
to auto-close() them when done and free resources. */
try (BufferedReader reader = new BufferedReader(new java.io.InputStreamReader(
new java.io.FileInputStream(fullPath), "UTF-8"))) {
java.io.OutputStream os = new java.io.FileOutputStream(tempFile);
try (PrintWriter writer = new PrintWriter(new java.io.OutputStreamWriter(os, "UTF-8"))) {
// Iterate if the file has another line...
String line;
while ((line = reader.readLine()) != null) {
// If the line is blank then just print it and continue to next line
if (line.trim().isEmpty()) {
writer.println();
continue; // read next line....
}
StringBuilder sb = new StringBuilder("");
if (reverseEntireLine) {
// Reverse the entire line
sb.append(line).reverse();
}
else {
/* Reverse each word within the currently read line:
Split the line into individual words based on whitespace but,
keep any spacing in case there is indentation etc. We use a
special Regular Expression for this because spacing needs to
be in thier own elements within the created String[] Array
even though we're using it as a split() delimiter. */
String splitExpression = "((?<= )|(?= ))";
String[] lineParts = line.split(splitExpression);
for (String word : lineParts) {
if (word.matches("\\s+")) {
sb.append(word);
}
else {
word = new StringBuilder(word).reverse().toString();
sb.append(word);
}
}
}
writer.println(sb.toString()); // Write to file.
writer.flush(); // Write immediately.
}
}
}
if (overwriteFile) {
new File(fullPath).delete();
new File(tempFile).renameTo(new File(fullPath));
}
}
And here is how you might use it:
/* The Line Spearator used for the system the application
is running on. Not all Consoles or Terminals just use "\n". */
String ls = System.lineSeparator();
// Provide a distinguishable and meaningful variable name!
Scanner userInput = new Scanner(System.in);
// File name to read prompt...
String fileName = "";
while (fileName.isEmpty()) {
System.out.print("Please enter the file path and name of the file" + ls
+ "you want to reverse (q to quit): -> ");
fileName = userInput.nextLine().trim();
// If 'q' for quit was entered.
if (fileName.equalsIgnoreCase("q")) {
return;
}
/* Validate input!
Does the supplied path and fileName exist? */
if (!new File(fileName).exists()) {
// Nope! Inform User...
System.out.println("The file name (" + fileName + ") can not be found!" + ls
+ "Please, try again..." + ls);
fileName = ""; // Empty fileName so to re-loop and ask again!
}
}
// All is good, the path and or file name exists.
try {
reverseFile(fileName, true, true); // <----
}
catch (FileNotFoundException ex) {
System.err.println(ex);
}
catch (IOException ex) {
System.err.println(ex);
}
Upvotes: 0
Reputation: 9463
You are not reading the file at all, but instead input (console). That means your program is waiting for you to enter text. Also your file gets deleted since you are trying to write to it.
Switch your while loop to read from inputFile
instead of input
.
Remove the line, or come up with a different output file:
PrintWriter writer = new PrintWriter(file);
Upvotes: 1
Reputation: 126
You have an issue with the path of file. You can extract the full path by -
System.out.println("filname: ");
Scanner input = new Scanner(System.in);
String filnamn = input.nextLine();
// Add this
final String fullPath = <YOUR_CLASS>.class.getProtectionDomain().getCodeSource().getLocation().getPath();
// Then correct the path
File file = new File(fullPath_filnamn);
Scanner inputFile = new Scanner(file);
PrintWriter writer = new PrintWriter(file);
while (input.hasNextLine()) {
String fil = input.next();
int reverse = 0;
for (int i = fil.length(); i >= 0; i--) {
reverse = reverse + fil.charAt(i);
writer.print(reverse);
}
}
inputFile.close();
writer.close();
input.close();
Upvotes: 0