FileWriter / BufferedReader Java word finder - java

I have this code set up and I am trying to write a program that looks through a file and finds a specific hidden secret word then replaces the word with "found!" then re-prints the text file in the console. I know how to use reader and writer but I am unsure how i can use them in unison to do this. Code is as follows:
Reader Class:
package Main;
import java.io.*;
public class Read {
private static String line;
FileReader in;
File file;
public Read() {
line = "";
}
public void readFile() throws IOException {
file = new File("C:examplePathName\\ReadWriteExp.txt");
in = new FileReader(file);
BufferedReader br = new BufferedReader(in);
while((line = br.readLine()) != null) {
System.out.println(line);
}
in.close();
}
public String getLine() {
return line;
}
public File getFile() {
return file;
}
}
Writer(change) class:
package Main;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
public class Change {
public static void main(String[] args) throws IOException{
Read r = new Read();
String line = r.getLine();
FileWriter fw = new FileWriter(r.getFile());
while(line != null) {
if(line.equals("example")) {
fw.write("found!");
}
System.out.println(line);
}
}
}
Am i on the right path or should i combine both of these into one class. Also is this the proper way of writing to a specific line in a text file?

If the file is a reasonable size, you can read it into memory, change what you need and write it back out again:
public static void replaceOccurrences(String match, String replacement, Path path) throws IOException {
Files.write(path, Files.lines(path).map(l -> {
if(l.contains(match)) {
return l.replace(match, replacement);
} else {
return l;
}
}).collect(Collectors.toList()));
}
Alternatively, if you know that the search term occurs only once and you just need to find the position of the occurrence, use the following:
try(BufferedReader reader = Files.newBufferedReader(path)) {
int lineIndex = 0;
String line;
while(!(line = reader.readLine()).contains(match)) {
lineIndex++;
}
System.out.println(lineIndex); // line which contains match, 0-indexed
System.out.println(line.indexOf(match)); // starting position of match in line, 0-indexed
}

If all you have to do is print the converted text to system out (rather than writing it out to a file), the second class isn't really needed. You can accomplish what you need in the readFile() method of the Read class:
public void readFile() throws IOException {
file = new File("C:examplePathName\\ReadWriteExp.txt");
in = new FileReader(file);
BufferedReader br = new BufferedReader(in);
while((line = br.readLine()) != null) {
System.out.println(line.replaceAll("example", "found!"));
}
in.close();
}
There are a lot of other tweaks you could make, but that's the core of the functionality you specified in your question.

Related

java update txt file content line by line

I am trying to update a txt file in place, namely without creating a temp file or writing a file in a new file destination but I've tried all the solutions on stack overflow and none of these have worked so far.
It always give me an empty file as result. it simply delete all the content of the source file.
So I am trying to modify the following code, which takes two files as input, in order to take only one input (the file source) but without success.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.PrintWriter;
public class CopyFiles {
private static void copyFile(String sourceFileName, String destinationFileName) {
try (BufferedReader br = new BufferedReader(new FileReader(sourceFileName));
PrintWriter pw = new PrintWriter(new FileWriter(destinationFileName))) {
String line;
while ((line = br.readLine()) != null) {
line += " ENDING ";
pw.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
String destinationFileName = "destination.csv";
String sourceFileName = "source.csv";
copyFile(sourceFileName, destinationFileName);
}
}

Displaying text retrieved from a Java class

I'm a beginner in Java. I have a 2 Java file that will passed the text retrieved from one Java file to the main Java file. But it doesnt seems to be working.
Main.java
import java.io.IOException;
public class LSAalgo extends Preprocessing {
public static void main(String[] args) throws IOException {
Preprocessing x = new Preprocessing(?);
}
}
Retrieve.java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Preprocessing {
public void preprocessing(String text) throws IOException
{
BufferedReader in = new BufferedReader(new FileReader("input7.txt"));
String line;
while((line = in.readLine()) != null)
{
System.out.println(line);
}
in.close();
}
}
Please help. Thanks.
You are just printing the text in console only. If you want to return complete text from one method to other just change your method return type to String (Since you are returning text) from void. Next change your code to
public String preprocessing() throws IOException
{
BufferedReader in = new BufferedReader(new FileReader("input7.txt"));
String line = "";
while((line = in.readLine()) != null)
{
System.out.println(line);
line += line;//appending complete text
}
in.close();
return line;//returning text
}
In main(-) change code to call preprocessing() method of Preprocessing class.
Preprocessing x = new Preprocessing();
String text = x.preprocessing();//getting text from Preprocessing class

how to read the data from the files of a directory

public class FIlesInAFolder {
private static BufferedReader br;
public static void main(String[] args) throws IOException {
File folder = new File("C:/filesexamplefolder");
FileReader fr = null;
if (folder.isDirectory()) {
for (File fileEntry : folder.listFiles()) {
if (fileEntry.isFile()) {
try {
fr = new FileReader(folder.getAbsolutePath() + "\\" + fileEntry.getName());
br = new BufferedReader(fr);
System.out.println(""+br.readLine());
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
finally {
br.close();
fr.close();
}
}
}
}
}
}
how to print the first word from first file of a directory and the second word from second file and third word from a third file of the same directory.
i am able to open directory and print the line from each file of the directory,
but tell me how to print the first word from first file and second word from second file and so on . .
Something like the below will read first word from first file, second word from second file, ... nth word from nth file. You'll likely want to do some additional work to improve the codes stability.
import java.io.File;
import java.io.IOException;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
public class SOAnswer {
private static void printFirst(File file, int offset) throws FileNotFoundException, IOException {
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
String line = null;
while ( (line = br.readLine()) != null ) {
String[] split = line.split(" ");
if(split.length >= offset) {
String targetWord = split[offset];
}
// we do not care if files are read that do not match your requirements, or
// for reading complete files as you only care for the first word
break;
}
br.close();
fr.close();
}
public static void main(String[] args) throws Exception {
File folder = new File(args[0]);
if(folder.isDirectory()) {
int offset = 0;
for(File fileEntry : folder.listFiles()) {
if(fileEntry.isFile()) {
printFirst(fileEntry, offset++); // handle exceptions if you wish
}
}
}
}
}

Buffered reader not accessable by other methods

Sorry if this is obvious, I am inexperienced with Java. I have 2 methods, one that creates a BufferedReader, and one that processes it. However, the processing method can not access the BufferedReader, even though it is in a public method. Am I doing something wrong?
package textfiles;
import java.io.IOException;
import java.io.FileReader;
import java.io.BufferedReader;
public class ReadFile {
private String path;
public ReadFile(String filePath) {
path = filePath;
}
public void Open() throws IOException {
FileReader read = new FileReader(path);
BufferedReader buff = new BufferedReader(read);
}
public String[] OpenFile() throws IOException {
int numberOfLines = readLines();
String[] textData = new String[numberOfLines];
int i;
for (i=0; i < numberOfLines; i++) {
textData[i] = buff.readLine();
}
buff.close();
return textData;
}
int readLines() throws IOException {
FileReader linedFile = new FileReader(path);
BufferedReader findLines = new BufferedReader(linedFile);
String lines;
int noLines = 0;
while ((lines = findLines.readLine()) != null) {
noLines++;
}
findLines.close();
return noLines;
}
}
Define BufferedReader at instance level just after declaring your path variable like
BufferedReader buff;
And in your method open, initialize it like
buff = new BufferedReader(read);
Your code should return compile time error as buff undefined variable. So declare it as instance variable and use it in any method directly.

python-like Java IO library?

Java is not my main programming language so I might be asking the obvious.
But is there a simple file-handling library in Java, like in python?
For example I just want to say:
File f = Open('file.txt', 'w')
for(String line:f){
//do something with the line from file
}
Thanks!
UPDATE: Well, the stackoverflow auto-accepted a weird answer. It has to do with bounty that I placed - so if you want to see other answers, just scroll down!
I was thinking something more along the lines of:
File f = File.open("C:/Users/File.txt");
for(String s : f){
System.out.println(s);
}
Here is my source code for it:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
public abstract class File implements Iterable<String>{
public final static String READ = "r";
public final static String WRITE = "w";
public static File open(String filepath) throws IOException{
return open(filepath, READ);
}
public static File open(String filepath, String mode) throws IOException{
if(mode == READ){
return new ReadableFile(filepath);
}else if(mode == WRITE){
return new WritableFile(filepath);
}
throw new IllegalArgumentException("Invalid File Write mode '" + mode + "'");
}
//common methods
public abstract void close() throws IOException;
// writer specific
public abstract void write(String s) throws IOException;
}
class WritableFile extends File{
String filepath;
Writer writer;
public WritableFile(String filepath){
this.filepath = filepath;
}
private Writer writer() throws IOException{
if(this.writer == null){
writer = new BufferedWriter(new FileWriter(this.filepath));
}
return writer;
}
public void write(String chars) throws IOException{
writer().write(chars);
}
public void close() throws IOException{
writer().close();
}
#Override
public Iterator<String> iterator() {
return null;
}
}
class ReadableFile extends File implements Iterator<String>{
private BufferedReader reader;
private String line;
private String read_ahead;
public ReadableFile(String filepath) throws IOException{
this.reader = new BufferedReader(new FileReader(filepath));
this.read_ahead = this.reader.readLine();
}
private Reader reader() throws IOException{
if(reader == null){
reader = new BufferedReader(new FileReader(filepath));
}
return reader;
}
#Override
public Iterator<String> iterator() {
return this;
}
#Override
public void close() throws IOException {
reader().close();
}
#Override
public void write(String s) throws IOException {
throw new IOException("Cannot write to a read-only file.");
}
#Override
public boolean hasNext() {
return this.read_ahead != null;
}
#Override
public String next() {
if(read_ahead == null)
line = null;
else
line = new String(this.read_ahead);
try {
read_ahead = this.reader.readLine();
} catch (IOException e) {
read_ahead = null;
reader.close()
}
return line;
}
#Override
public void remove() {
// do nothing
}
}
and here is the unit-test for it:
import java.io.IOException;
import org.junit.Test;
public class FileTest {
#Test
public void testFile(){
File f;
try {
f = File.open("File.java");
for(String s : f){
System.out.println(s);
}
} catch (IOException e) {
e.printStackTrace();
}
}
#Test
public void testReadAndWriteFile(){
File from;
File to;
try {
from = File.open("File.java");
to = File.open("Out.txt", "w");
for(String s : from){
to.write(s + System.getProperty("line.separator"));
}
to.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
Reading a file line by line in Java:
BufferedReader in = new BufferedReader(new FileReader("myfile.txt"));
String line;
while ((line = in.readLine()) != null) {
// Do something with this line
System.out.println(line);
}
in.close();
Most of the classes for I/O are in the package java.io. See the API documentation for that package. Have a look at Sun's Java I/O tutorial for more detailed information.
addition: The example above will use the default character encoding of your system to read the text file. If you want to explicitly specify the character encoding, for example UTF-8, change the first line to this:
BufferedReader in = new BufferedReader(
new InputStreamReader(new FileInputStream("myfile.txt"), "UTF-8"));
If you already have dependencies to Apache commons lang and commons io this could be an alternative:
String[] lines = StringUtils.split(FileUtils.readFileToString(new File("myfile.txt")), '\n');
for(String line: lines){
//do something with the line from file
}
(I would prefer Jesper's answer)
If you want to iterate through a file by strings, a class you might find useful is the Scanner class.
import java.io.*;
import java.util.Scanner;
public class ScanXan {
public static void main(String[] args) throws IOException {
Scanner s = null;
try {
s = new Scanner(new BufferedReader(new FileReader("myFile.txt")));
while (s.hasNextLine()) {
System.out.println(s.nextLine());
}
} finally {
if (s != null) {
s.close();
}
}
}
}
The API is pretty useful: http://java.sun.com/javase/7/docs/api/java/util/Scanner.html
You can also parse the file using regular expressions.
I never get tired of pimping Google's guava-libraries, which takes a lot of the pain out of... well, most things in Java.
How about:
for (String line : Files.readLines(new File("file.txt"), Charsets.UTF_8)) {
// Do something
}
In the case where you have a large file, and want a line-by-line callback (rather than reading the whole thing into memory) you can use a LineProcessor, which adds a bit of boilerplate (due to the lack of closures... sigh) but still shields you from dealing with the reading itself, and all associated Exceptions:
int matching = Files.readLines(new File("file.txt"), Charsets.UTF_8, new LineProcessor<Integer>(){
int count;
Integer getResult() {return count;}
boolean processLine(String line) {
if (line.equals("foo")
count++;
return true;
}
});
If you don't actually want a result back out of the processor, and you never abort early (the reason for the boolean return from processLine) you could then do something like:
class SimpleLineCallback extends LineProcessor<Void> {
Void getResult{ return null; }
boolean processLine(String line) {
doProcess(line);
return true;
}
abstract void doProcess(String line);
}
and then your code might be:
Files.readLines(new File("file.txt"), Charsets.UTF_8, new SimpleLineProcessor(){
void doProcess(String line) {
if (line.equals("foo");
throw new FooException("File shouldn't contain 'foo'!");
}
});
which is correspondingly cleaner.
public static void main(String[] args) throws FileNotFoundException {
Scanner scanner = new Scanner(new File("scan.txt"));
try {
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
} finally {
scanner.close();
}
}
Some caveats:
That uses the default system encoding, but you should specify the file encoding
Scanner swallows I/O exceptions, so you may want to check ioException() at the end for proper error handling
Simple example using Files.readLines() from guava-io with a LineProcessor callback:
import java.io.File;
import java.io.IOException;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import com.google.common.io.LineProcessor;
public class GuavaIoDemo {
public static void main(String[] args) throws Exception {
int result = Files.readLines(new File("/home/pascal/.vimrc"), //
Charsets.UTF_8, //
new LineProcessor<Integer>() {
int counter;
public Integer getResult() {
return counter;
}
public boolean processLine(String line) throws IOException {
counter++;
System.out.println(line);
return true;
}
});
}
}
You could use jython which lets you run Python syntax in Java.
Nice example here: Line by line iteration
Try looking at groovy!
Its a superset of Java that runs in hte JVM. Most valid Java code is also valid Groovy so you have access any of the million java APIs directly.
In addition it has many of the higher level contructs familiar to Pythonists, plus
a number of extensions to take the pain out of Maps, Lists, sql, xml and you guessed it -- file IO.

Categories