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
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);
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();
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);
}
Related
What the program does: A user loads a file and it saves the file name, creation date and a file number to a text file. I want the program to check the file to see if the filename is already stored. If it is, to then check the creation date to see if it matches the one the user is currently trying to save. If it differs, to save over the currently saved creation date with the new one.
An example of Info.txt:
CreationDate: 140319, FileName: example1.txt, FileNumber: 1
CreationDate: 110219, FileName: example2.txt, FileNumber: 6
CreationDate: 100319, FileName: example3.txt, FileNumber: 14
How I create and write to the file:
public void fileCreation() throws IOException {
String fileinformation = File.creationdate + ", " + File.name + ", " + "Number: " + File.Number;
FileWriter wr = new FileWriter("Info.txt", true);
PrintWriter output = new PrintWriter(wr);
output.println(fileinformation);
output.close();
}
How I'm currently checking the file, at the moment it only prints the file contents, so if a User goes to save example2.txt with a different creation date, then the new one should overwrite the current one
public void scanFile() throws IOException {
BufferedReader br = new BufferedReader(new FileReader("Info.txt"));
String readfile;
while ((readfile = br.readLine()) != null) {
System.out.println(readfile);
}
System.out.println("file not found");
}
Creation date is a long number and File.creationdate is a string such as "CreationDate: 140319", it would also be good to put a check to see if the FileNumber matches, but this is not necessary.
You should use split on your line with ',' as a separator.
Then you can go through every line and for each line check if first the name is the same as the file name, if it is, go and check the date and then finally check the FileNumber.
But why do you need to check it one by one ? Better to write it in with &&, like this
public boolean scanFile() throws IOException {
BufferedReader br = new BufferedReader(new FileReader("Info.txt"));
String readfile;
Boolean isAlreadyIn = false;
while ((readfile = br.readLine()) != null) {
String[] parts = readFile.split(',');
if(parts[1].replace("FileName: ","").equals(File.name) &&parts[0].replace("CreationDate: ","").equals(File.creationdate) &&parts[2].replace("FileNumber: ","").equals(File.number){
isAlreadyIn = true; // you can also write directly in this fonction
}
return isAlreadyIn;
}
}
if you really need to check it one by one, just make a if(if( if()) with the condition in it
i'm trying to delete a whole line after entering the Association Name but isnt working. it keeps showing the error, could not delete original input file can you please help me with this?
String inputFileName = "Association Record.txt";
String outputFileName = "Association Report.txt";
String lineToRemove = JOptionPane.showInputDialog("Enter Association Name to Delete the Record");
try{
File inputFile = new File(inputFileName);
File outputFile = new File(outputFileName);
try{
BufferedReader r1= new BufferedReader(new FileReader(inputFile));
BufferedWriter w1 = new BufferedWriter(new FileWriter(outputFile));
String line = null;
while ((line = r1.readLine()) != null) {
if (!line.equals(lineToRemove)) {
w1.write(line);
w1.newLine();
}
}//end while
}
catch (IOException ex) {ex.printStackTrace();}
if (inputFile.delete()) {
if (!outputFile.renameTo(inputFile))
throw new IOException("Could not rename " + outputFileName + " to " + inputFileName);
}
else {throw new IOException("Could not delete original input file " + inputFileName);}
}
catch (Exception e){System.out.println(e.getMessage());}
}
example of one of the line in the file:
COMPUTER,pc,08/07/2018,brandon
*COMPUTER is the association name
If the word COMPUTER is the association word and the line you want to delete starts with the word COMPUTER then the String#equals() method is not the one to use in your IF statement. You would want to use the String#startsWith() method, for example:
boolean ignoreLetterCase = true; // ignore Letter Case by default
String lineToRemove = "computer";
String criteria = ignoreLetterCase ? lineToRemove.toLowerCase() : lineToRemove;
while ((line = r1.readLine()) != null) {
String procString = ignoreLetterCase ? line.toLowerCase : line;
if (!procString.startsWith(criteria)) {
w1.write(line);
w1.newLine();
}
}
The file data line COMPUTER,pc,08/07/2018,brandon will not be written to the destination file.
If however you want to ignore a file line that contains the associative word COMPUTER anywhere within a retrieved data line then you will want to utilize the String#contains() method, for example:
boolean ignoreLetterCase = true; // ignore Letter Case by default
String lineToRemove = "computer";
String criteria = ignoreLetterCase ? lineToRemove.toLowerCase() : lineToRemove;
while ((line = r1.readLine()) != null) {
String procString = ignoreLetterCase ? line.toLowerCase : line;
if (!procString.contains(criteria)) {
w1.write(line);
w1.newLine();
}
}
The file data line COMPUTER,pc,08/07/2018,brandon will not be written to the destination file. However a file data line which contains PRINTER,pc-computer,09/27/2018,joseph will also not be written to the destination file since the word computer is contained within the original file line.
I highly doubt this will ever be the case with your data file but if a retrieved file data line only contains the associative word (COMPUTER) then by all means you would want to use the String#equals() or String#equalsIgnoreCase() method.
If you want to ignore original file lines where the associative word is only pertinent within a specific data column of any retrieved file data line then you would want to parse (split) each line into a columnar data array and do your comparisons on the desired column (array elemental index). For example:
// Delete all file lines where the NAME column equals
// the name 'brandon' or 'Brandon' or 'BRANDON'.
boolean ignoreLetterCase = true; // ignore Letter Case by default
int deleteIfInColumn = 3;
String nameToDelete = "Brandon";
String criteria = ignoreLetterCase ? nameToDelete .toLowerCase() : nameToDelete;
while ((line = r1.readLine()) != null) {
String procString = ignoreLetterCase ? line.toLowerCase : line;
String[] columnData = procString.split(",");
if (columnData[deleteIfInColumn].equals(criteria)) {
continue; // Skip to next file line
}
w1.write(line);
w1.newLine();
}
I have the below integers in File :
758 29
206 58
122 89
I have to read these integers in an integer array and then need to store the values in key value pair. Then print the output as :
Position 29 has been initialized to value 758.
Position 89 has been initialized to value 122.
I have tried as of now :
private static Scanner readFile() {
/*
* Your program will prompt for the name of an input file and the read
* and process the data contained in this file. You will use three
* integer arrays, data[], forward[] and backward[] each containing 100
* elements
*/
int data[] = new int[100];
int forward[] = new int[100];
int backward[] = new int[100];
System.out.print("Please enter File Name : ");
#SuppressWarnings("resource")
Scanner scanner = new Scanner(System.in);
String filename = scanner.nextLine();
File inputFile = new File(filename);
Scanner linReader = null;
try {
linReader = new Scanner(new File(filename));
while (linReader.hasNext()) {
String intStringSplit = linReader.nextLine();
String[] line = intStringSplit.split("\t",-1);
data = new int[line.length];
for (int i = 0; i < data.length; i++) {
data[i] = Integer.parseInt(line[i]);
}
System.out.println(data);
}
linReader.close();
} catch (Exception e) {
System.out.println("File Not Found");
}
return linReader;
}
I am not able to figure out how to get the key and value from the read data.
When posting information related to your question it is very important that you provide the data (in file for example) exactly as it is intended in reality so that we can make a more positive determination as to why you are experiencing difficulty with your code.
What you show as an in file data example indicates that each file line (which contains actual data) consists of two specific integer values. The first value being the initialization value and the second being the position value.
There also appears to be a blank line after ever line which contains actual data. This really doesn't matter since the code provided below has a code line to take care of such a thing but it could be the reason as to why you may be having difficulty.
To me, it looks like the delimiter used to separate the two integer values in each file line is indeed a whitespace as #csm_dev has already mentioned within his/her comment but you claim you tried this in your String.split() method and determined it is not a whitespace. If this is truly the case then it will be up to you to determine exactly what that delimiter might be. We couldn't possibly tell you since we don't have access to the real file.
You declare a File object within your provided code but yet nowhere do you utilize it. You may as well delete it since all it's doing is sucking up oxygen as far as I'm concerned.
When using try/catch it's always good practice to catch the proper exceptions which in this case is: IOException. It doesn't hurt to also display the stack trace as well upon an exception since it can solve a lot of your coding problems should an exception occur.
This code should work:
private static Scanner readFile() {
/*
* Your program will prompt for the name of an input file and the read
* and process the data contained in this file. You will use three
* integer arrays, data[], forward[] and backward[] each containing 100
* elements
*/
int data[] = new int[100];
int forward[] = new int[100];
int backward[] = new int[100];
System.out.print("Please enter File Name : ");
Scanner scanner = new Scanner(System.in);
String filename = scanner.nextLine();
File inputFile = new File(filename); // why do you have this. It's doing nothing.
Scanner linReader = null;
try {
linReader = new Scanner(new File(filename));
while (linReader.hasNext()) {
String intStringSplit = linReader.nextLine();
// If the file line is blank then just
// continue to the next file line.
if (intStringSplit.trim().equals("")) { continue; }
// Assuming at least one whitespace is used as
// the data delimiter but what the heck, we'll
// use a regular expression within the split()
// method to handle any number of spaces between
// the integer values.
String[] line = intStringSplit.split("\\s+");
data = new int[line.length];
for (int i = 0; i < line.length; i++) {
data[i] = Integer.parseInt(line[i]);
}
System.out.println("Position " + data[1] +
" has been initialized to value " +
data[0] + ".");
// do whatever else you need to do with the
// data array before reading in the next file
// line......................................
}
linReader.close();
}
catch (IOException ex) {
System.out.println("File Not Found");
ex.printStackTrace();
}
return linReader;
}
Please consider the following code. I'm not very familiar with StringBuilders or reading/writing data. I need to:
1.) Open source file
2.) Grab words and check for old string, if an old string, then append new string
3.) Use PrintWriter and Close. I am revising the following code below:
import java.io.*;
import java.util.*;
public class ReplaceText {
public static void main(String[] args) throws Exception {
// Check command line parameter usage
if (args.length != 4) {
System.out.println(
"Usage: java ReplaceText sourceFile targetFile oldStr newStr");
System.exit(1);
}
// Check if source file exists
File sourceFile = new File(args[0]);
if (!sourceFile.exists()) {
System.out.println("Source file " + args[0] + " does not exist");
System.exit(2);
}
// Check if target file exists
File targetFile = new File(args[1]);
if (targetFile.exists()) {
System.out.println("Target file " + args[1] + " already exists");
System.exit(3);
}
// Create input and output files
Scanner input = new Scanner(sourceFile);
PrintWriter output = new PrintWriter(targetFile);
while (input.hasNext()) {
String s1 = input.nextLine();
String s2 = s1.replaceAll(args[2], args[3]);
output.println(s2);
}
input.close();
output.close();
}
}
I'd also like to ask the user for the source file, old string, and new string at run time instead of using command line arguments.
I know I still need to incorporate StringBuilder. Here is what I have so far:
public class ReplaceText {
public static void main(String [] args) throws Exception {
Scanner scan = new Scanner(System.in);
System.out.println("What is the source file");
java.io.File file = new java.io.File(scan.next());
System.out.println("Enter old line");
String oldLine = scan.nextLine();
System.out.println("Enter new line");
String newLine = scan.nextLine();
//scan.exit;
/** Read one line at a time, append, replace oldLine with
* newLine using a loop */
//Scanner scan2 = new Scanner(file);
//PrintWriter that replaces file
java.io.PrintWriter output = new java.io.PrintWriter(file);
output.println(file);
output.close();
}
}
I have a method like this:
public int getIncrement() {
String extractFolder = "/mnt/sdcard/MyFolder";
boolean newFolder = new File(extractFolder).mkdir();
int counter = 0;
try {
File root = new File(extractFolder);
if (root.canWrite()){
File gpxfile = new File(root, "gpxfile.txt");
FileWriter gpxwriter = new FileWriter(gpxfile);
BufferedWriter out = new BufferedWriter(gpxwriter);
Scanner scanner = new Scanner(new FileInputStream(gpxfile.getAbsolutePath()), "UTF-8");
Log.i("PATH: ", extractFolder + "/gpxfile.txt");
while(scanner.hasNextLine()) {
String inc = scanner.nextLine();
counter = Integer.parseInt(inc);
Log.i("INSIDE WHILE: ", Integer.toString(counter));
}
counter++;
out.write(Integer.toString(counter));
out.close();
}
} catch (IOException e) {
Log.e("GEN_PCN: ", "Could not write file " + e.getMessage());
}
return counter;
}
What I am trying to accomplish is returning the content of this file, and increment the integer by 1. But it seems that I can't get in the while loop, because LogCat doesn't print out anything. Yes, am sure that the path is correct.
I guess the constructor of FileWriter gpxwriter has already blanked out the file by the time the Scanner is created, so the file is empty and hasNextLine returns false. Why do you open a file for writing when you want to read it?
From what I can tell the file doesn't exist. Try adding gpxfile.createNewFile()
To get a little more in depth, creating a File instance, does not create a file on the file system.
So, this line -> File gpxfile = new File(path, filename);
is not sufficient to create the file on the sd card. You must follow it with
gpxfile.createNewFile() which quoting the docs says:
Atomically creates a new, empty file named by this abstract pathname if and only if a file with this name does not yet exist. The check for the existence of the file and the creation of the file if it does not exist are a single operation that is atomic with respect to all other filesystem activities that might affect the file.
OK I MARK YOUR FILE NAME
Just add a BACKSLASH in extractFolder at END
v
v
v
String extractFolder = "/mnt/sdcard/MyFolder/";
^ // <--- HERE
^
^
Because File gpxfile = new File(root, "gpxfile.txt"); doesn't have BackSlash / as Log have
Just try Once Following:
while(scanner.hasNextLine()) {
String inc = scanner.nextLine();
// // counter = Integer.parseInt(inc);
Log.i("INSIDE WHILE: ", inc);
System.out.println("Next Line ::"+inc); // Also check this
}