I'm a beginner and need some help. I'm trying to scan a text file into an array line by line, but omitting one line. My text file is
i am
you are
he is
she is
it is
I want to create a method that will scan this and put elements into an array with an exception for one line (that is chosen by entering the String as a parameter for the method). Then erase the original text file and print there the created array (without that one deleted line). Sorry, I suck at explaining.
I have tried this:
public static void deleteLine(String name, String line) throws IOException {
String sc = System.getProperty("user.dir") + new File("").separator;
FileReader fr = new FileReader(sc + name + ".txt");
Scanner scan = new Scanner(fr);
int n = countLines(name); // a well working method returning the number if lines in the file (here 5)
String[] listArray = new String[n-1];
for (int i = 0; i < n-1; i++) {
if (scan.hasNextLine() && !scan.nextLine().equals(line))
listArray[i] = scan.nextLine();
else if (scan.hasNextLine() && scan.nextLine().equals(line))
i--;
else continue;
}
PrintWriter print = new PrintWriter(sc + name + ".txt");
print.write("");
for (int i = 0; i < n-2; i++) {
print.write(listArray[i] + "\n");
}
print.close()
}
I get an error "Line not found" when I enter: deleteLine("all_names","you are") (all_names is the name of the file). I'm sure the problem lies in the for-loop, but I have no idea why this doesn't work. :(
//SOLVED//
This code worked after all. Thanks for answers!
public static void deleteLine(String name, String line) throws IOException{
String sc = System.getProperty("user.dir") + new File("").separator;
FileReader fr = null;
fr = new FileReader(sc+name+".txt");
Scanner scan = new Scanner(fr);
int n = LineCounter(name);
String[] listArray = new String[n-1];
for (int i = 0; i < n-1; i++) {
if (scan.hasNextLine()) {
String nextLine = scan.nextLine();
if (!nextLine.equals(line)) {
listArray[i] = nextLine;
}
else i--;
}
}
PrintWriter print = new PrintWriter(sc+name+".txt");
print.write("");
for(int i=0;i<n-1;i++){
print.write(listArray[i]+System.lineSeparator());
}
print.close();
}
You are reading the lines twice scan.nextLine() while comparing and because of that you run out of the lines.
Replace your loop with this one or similar
for (int i = 0; i < n; i++) {
if (scan.hasNextLine()) {
String nextLine = scan.nextLine();
if (nextLine.equals(line)) {
listArray[i] = nextLine;
}
}
}
Have a look at how you are comparing String objects. You should use the equals method to compare a String's content. Using operators like == and != compares if the String objects are identical.
Now after using equals correctly have a look at how you are using nextLine. Check its Javadoc
I feel LineCounter(name) works because you did not put a ".txt" there. Try removing the ".txt" extension from the file name in the Filereader and Printwriter objects and see if it works. Usually in windows, the extension is not a part of the file name.
Here's an alternative (easier) solution to do what you want, using easier to understand code. (I think)
Also it avoids multiple
loops, but uses a single Java 8 stream to filter instead.
public static void deleteLine(String name, String line) throws IOException {
List<String> lines = Files.readAllLines(Paths.get(name));
lines = lines.stream().filter(v -> !v.equals(line)).collect(Collectors.toList());
System.out.println(lines);
// if you want the String[] - but you don't need it
String[] linesAsStringArr = new String[lines.size()];
linesAsStringArr = lines.toArray(linesAsStringArr);
// write the file using our List<String>
Path out = Paths.get("output.txt"); // or another filename you dynamically create
Files.write(out, lines, Charset.forName("UTF-8"));
}
Related
I have a file with multiple lines. My java program must read each three lines from it and format them in one row and writes it to another file. How I can tell to ignore some lines in the file?
For example:
File that program reads from:
First,second,third
Blas,Blad,Blaff,
Mop,Mp,Sup
It must turn this three lines to:
First,Sup,Blaff
It does it correct, but how I can tell to program to ignore some lines that have particular words, for example, if it has particular word, like "sub" in one of the lines?
The example of the code is below:
public static void main(String[] args) throws Exception {
String text = "";
String changedText = "";
String first = "", second = "", third = "";
int outerCounter = 0;
int innerCounter = 0;
int arturCounter = 0;
String temp = "";
//first, we read data from file
java.io.File file = new java.io.File("test.txt");
Scanner input = new Scanner(file);
input.useDelimiter("\r");
while(input.hasNextLine()) {
text = input.next();
outerCounter += 1;
innerCounter = 0;
for (String string : text.split(",")) {
innerCounter += 1;
if(outerCounter == 1) {
second = string;
break;
}
else if(outerCounter == 2 && innerCounter == 3) {
third = string;
}
else if(outerCounter == 3 && innerCounter == 3) {
first = string;
outerCounter = 0;
second = second.replace("\n", "").replace("\r", ""); //very important part, solves the problem with new line!
changedText += second + "," + first + "," + third + "\r" + "\n";
}
}
}
//second, we write obtained data to another file
//PrintWriter creates the file
java.io.PrintWriter output = new java.io.PrintWriter("testOutput.txt");
//write formatted output to the file
output.println(changedText);
//close the file
output.close();
System.out.println(changedText);
}
}
Thank you in advance for help.
I would follow the paradigm:
Init an array pos pointer. Say (p) = 0.
Init an array. Say (arr) = []
Create a function to read the next line, name it (a)
Go into a loop.
Call a() to get the next line, say (l) the new line.
Check if EOF
Check (l) for "invalid" words if one found call continue the loop to get the next line
Add the line to (arr)[p] and increment p by one.
If p == 3 write to file (arr)[0] + (arr)[2] + (arr)[1]. Reset (p) = 0.
Else continue;
i cannot for the life of me seem to take in the contents of this file, i keep getting No such elements exception on line 25, all help appreciate. heres a link to the file link
heres my code
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class practiceFinal {
public static void main(String[] args) {
String fileName = args[0];
int length = fileLength(fileName);
int[] array = new int[length];
String[] list = new String[length];
arrayPopulate(array, list, fileName);
for (int i = 0; i < array.length; i++) {
System.out.print(array[i]);
}
}
public static int fileLength(String fileName) {
File file = new File(fileName);
Scanner fileScan = new Scanner(fileName);
int counter = 0;
while (fileScan.hasNext()) {
fileScan.next();
counter++;
}
return counter;
}
public static void arrayPopulate(int[] array, String[] list, String fileName) {
File file = new File(fileName);
Scanner fileScan = null;
try {
fileScan = new Scanner(file);
} catch (FileNotFoundException e) {
System.out.println("details: " + e.getMessage());
}
for (int i = 0; i < array.length; i++) {
array[i] = fileScan.nextInt();
list[i] = fileScan.next();
}
}
}
There are a few problems here. First of all you are using fileScan.next(); to try and get the length of a file. This is going to give you 2 times the length because you are counting each token fileScan.next() grabs which will be first the number and then the letter.
Length of lines is 144 but when you calculate it, it returns 288.
So use fileScan.nextLine();, now some people have mentioned this but your program is still not going to work correctly because you passed Scanner fileScan = new Scanner(fileName); // mistake passed fileName instead of file
Here are the changes I made inside the fileLength() method:
File file = new File(fileName);
Scanner fileScan = new Scanner(file); // mistake passed fileName instead of file, changed from Scanner fileScan = new Scanner(fileName)
while (fileScan.hasNextLine()) {
fileScan.nextLine(); // changed from fileScan.next()
counter++;
}
Your output looks like:
84c89C11w71h110B96d61H92d10B3p40c97G117X13....
When you are printing the results, change the print statements to
System.out.print(array[i]);
System.out.print(" " + list[i]);
System.out.println();
Output now looks like:
84 c
89 C
11 w
71 h
....
Instead of using int length = fileLength(fileName); to find the length, use int length = fileName.length();
From the format of your file and your current code, it looks like length represents the number of "words" in the file. In your loop, you need to advance i by 2 instead of 1, since it consumes two "words" per iteration. This also means that each array is twice as long as it should be. Instantiate them with length/2.
for (int i = 0; i < array.length; i += 2) {
array[i] = fileScan.nextInt();
list[i] = fileScan.next();
}
Alternately, you could make length represent the number of lines in the file. To do that, use hasNextLine() and nextLine() in your counting loop. Then leave all of the rest of your code as-is.
while (fileScan.hasNextLine()) {
fileScan.nextLine();
counter++;
}
Additionally, make sure your Scanner is passed the proper parameters. A String is valid, but not for File I/O. You would need to first create a File object using the fileName.
Scanner fileScan = new Scanner(new File(fileName));
I have a text file which is a game save for my java game (cookie clickers) so the stuff in the file will be numbers without spaces. Like so:
10
20
30
40
50
I need to read the lines and save each one to its string.
So the strings should be like this, so I can use them a lot easier:
lives = 10
kills = 20
score = 30
...
The saving code will be in its class file (Save.class). I only need the code, other stuff should not be a problem.
Is there some kind of easy way to make it work as I want?
You can use a Scanner as follows:
Scanner s = new Scanner(new File("your file"));
String lives = s.nextLine();
String kills = s.nextLine();
String score = s.nextLine();
...
s.close();
Scanner is good here.
List<String> list = new LinkedList<>();
Scanner scan = new Scanner(new File("the_file"));
while (scan.hasNextLine())
list.add(scan.nextLine());
I recommend you to use an ArrayList. Like this:
Scanner s = new Scanner(new File(//Here the path of your file));
ArrayList<String> list = new ArrayList<String>();
while (s.hasNext())
{
list.add(s.nextLine());
}
Now you will have stored all the lines of your file so you can access each of them like this:
for(int i = 0; i < list.size(); i++)
{
System.out.println("The content of the line " + i + " it's " + list.get(i);
}
I expect it will be helpful for you!
BufferedReader reader = new BufferedReader(new FileReader(FILE_PATH));
String line = null;
int index = 0;
while((line = reader.readLine()) != null) {
if(index == 0) {
line1 = line;
} else if(index == 1) {
line2 = line;
} else if(index == 2) {
line3 = line;
}
index++;
}
or you could read the text and save it as string array
also you might would like to use this http://ini4j.sourceforge.net
Use readAllLines:
File data = new File("textfile.txt");
List<String> lines = Files.readAllLines(data.toPath());
This way of saving game state smells. It seems that you're on your way on reinventing the wheel. Why don't you use a properties file where you can save the key(lives, kills, score) and the value ? It would make the code a lot more readable.
String gameStateFile = "gameState.properties";
Properties gameProperties = new Properties();
gameProperties.load(input);
String lives = gameProperties.get("lives");
I have a text file i already read it and return an array of string "lines" in this structure
{(1),text,(2),text,(3),text........}
I want to restructure it as
{(1)text,(2)text,(3)text........}
which mean concatenate every number like (1) with the next text and so on
public String[] openFile() throws IOException {
FileInputStream inStream = new FileInputStream(path);
InputStreamReader inReader = new InputStreamReader(inStream,"UTF-8");
BufferedReader textReader = new BufferedReader(inReader);
int numberOfLine = countLines();
String[] textData = new String[numberOfLine];
for (int i = 0; i < numberOfLine; i++) {
// if (textReader.readLine()!= null) {
textData[i] = textReader.readLine();
//}
}
textReader.close();
return textData;
}
how can i do it please using Java language ?
Thanks for your helps and your opinions
String[] newArray = new String[textData.length / 2];
for (int i = 0; i < textData.length - 1; i+=2) {
newArray[i / 2] = textData[i] + textData[i + 1];
}
But be sure that your textData has an even length
Put this snippet before the return statement and return newArray instead;
It seems that the comma you want to omit is always preceded by a closing bracket. Assuming that that is the only time it happens in your string you could just do a simple replacement in your for-loop:
textData[i] = textData[i].replace("),", ")");
If that isn't the case, then another thing you could do is work on the basis that the comma you want to remove is the first in the string:
//Locate index of position of first comma in string
int firstComma = x.indexOf(',');
//Edit string by concatenating the bit of the string before the comma
and the bit after it, stepping over the comma in the process
textData[i] = (textData[i].substring(0, firstComma)).concat(textData[i].substring(firstComma + 1));
Here is my code:
import java.util.Scanner;
import java.io.*;
import java.util.ArrayList;
public class Filter{
Message myMessage;
Scanner input;
Scanner input2;
String sender;
String subject;
String emailMIN;
String line;
String line2;
ArrayList<String> blacklist = new ArrayList<String>();
ArrayList<String> keywords = new ArrayList<String>();
ArrayList<String> subjectWords = new ArrayList<String>();
ArrayList<String> emails = new ArrayList<String>();
//String[] lines;
File SpamMessage;
File inFile;
File inFile2;
File tempFile;
String[] lines;
public Filter(Message m,String blacklistFile, String keywordFile, String Spam)throws IOException{
inFile = new File(blacklistFile);
inFile2 = new File(keywordFile);
input = new Scanner (inFile);
input2 = new Scanner (inFile2);
myMessage =m;
SpamMessage=new File(Spam);
}
public void filter() throws IOException{
PrintWriter output = new PrintWriter(SpamMessage);
while(input.hasNextLine()){
line = input.nextLine();
//System.out.println(line);
if(line!=null)
blacklist.add(line);
}
while(input2.hasNextLine()){
line2 = input2.nextLine();
//System.out.println(line2);
if(line!=null)
keywords.add(line2);
}
emails=myMessage.getEmails();
// System.out.println(emails.size() + emails.get(1));
for(int i = 0; i < emails.size(); i++){
// boolean isSpam = false;
lines = emails.get(i).split("\n");
// System.out.println(lines[5] + lines[7]);
sender = lines[2].substring(lines[2].indexOf('<'), lines[2].indexOf('>'));
//` System.out.println(sender);
emailMIN = lines[6].substring(lines[6].indexOf('<'), lines[6].indexOf('>'));
// System.out.println(emailMIN);
for(int j =0; j<lines.length; j++)
{
if(j==2)
{
for(String blacklist2: blacklist)
{
// System.out.println(blacklist2);
if(lines[j].contains(blacklist2))
{
output.println(emailMIN);
}
// output.close();
}
}
if(j==5 || j>=7)
{
// System.out.println(keywords.size());
for(String keywords2: keywords)
{
// System.out.println(keywords2);
if(lines[j].contains(keywords2))
{
output.println(emailMIN);
}
// output.close();
}
}
//addKeywords();
}
}
output.close();
addKeywords();
}
public void addKeywords() throws IOException
{
tempFile = new File("tempFile.txt");
PrintWriter pw = new PrintWriter(new FileWriter(tempFile));
for(int i=0; i<lines.length; i++)
{
if(i==5){
String[] words = lines[i].split(" ");
for(String word: words){
if(word.length()>=6){
subjectWords.add(word +"\n");
//System.out.println(subjectWords);
}
}
keywords.addAll(subjectWords);
pw.println(keywords);
}
}
pw.close();
if (!inFile2.delete()) {
//System.out.println("Could not delete file");
return;
}
// Rename the new file to the filename the original file had.
if (!tempFile.renameTo(inFile2)){
//System.out.println("Could not rename file");
}
}
}
I'm trying to update the list of words in the keywords txt file right now it does update it but it puts it in the format [generic, pharmacy, little, inside]
Which is wrong because then if I run my code again it is searching if the file contains [generic, pharmacy, little, inside] and I need it to search for every word not the plus a comma or brace. So basically I want it to copy the words in a list format like this
generic
pharmacy
little
inside
That way it searches for each individual word. I figured out how to do this part. Now, how do I add the senders to a different text file? Also is there a way to modify this so it doesn't add the same keywords twice? Thanks
It is because you are writing an array to the file which causes the toString method of it to be called. Write every single item instead.
Instead of pw.println(keywords);
Do:
for (String keyword : keywords)
{
pw.println(keyword.trim());
}
Or, if every word contains \n already, this should work
for (String keyword : keywords)
{
pw.print(keyword);
}
Instead of doing:
pw.println(keywords);
you should instead loop through the array and add each line individually.
for(int i = 0; i < keywords.length; i++) {
pw.println(keywords[i]);
}
That was because you are printing an ArrayList object. In your code, keywords is instance of the List and which would you give you an output of [aa,bb] . More over you would get duplicate words since these list instance are class variables, and printed inside a loop
keywords.addAll(subjectWords);
pw.println(keywords);
Either you can loop around keywords outside the for loop or print the word before adding to list.