Working with BufferedOutputStream - java

Im using BufferedOutputStream for writing in a file ,it writes list of files and directories in th specified driver, heres the code:
import java.io.File;
import java.nio.file.*;
import java.io.*;
import static java.nio.file.StandardOpenOption.*;
public class DirectoryReader {
static int spc_count=-1;
static void Process(File aFile)
{
String s;
Path file =
Paths.get("C:\\Java\\Files1.txt");
try
{
OutputStream output= new
BufferedOutputStream(Files.newOutputStream(file,CREATE));
spc_count++;
String spcs = "";
byte [] data= new byte [2048 * 2048];
for (int i = 0; i < spc_count; i++)
spcs += " ";
if(aFile.isFile())
{
System.out.println(spcs + "[FILE] " + aFile.getPath());
s=aFile.getPath();
System.out.println(" " + s);
data = s.getBytes();
output.write(data);
output.write(13);
output.write(10);
output.flush();
}
else if (aFile.isDirectory()) {
{
System.out.println(spcs + "[DIR] " + aFile.getPath());
s=aFile.getPath();
data = s.getBytes();
output.write(data);
output.write(13);
output.write(10);
output.flush();
}
File[] listOfFiles = aFile.listFiles();
if(listOfFiles!=null) {
for (int i = 0; i < listOfFiles.length; i++)
Process(listOfFiles[i]);
} else {
System.out.println(spcs + " [ACCESS DENIED]");
}
}
output.close();
spc_count--;
}
catch(Exception e)
{
System.out.println("Message: " + e);
}
}
public static void main(String[] args) {
String nam = "D:\\Notes";
File aFile = new File(nam);
Process(aFile);
}
}
but when I go to see the file , I only find the last file written and sometimes I find mixed words .

You are using recurrent calls to your Process method. This method is creating NEW FILE upon execution, so previous content is simply overriden. I would suggest, that you should create output stream, and pass it as argument to every call Process message. This way, you will provide single output stream for storing data. And the problem will be gone.

Related

BufferedRead stuck in infinite loop

I am doing a class project that is supposed to read a .txt file and have the program also replace some text. But after I run the code it just constantly runs in a loop and only reading one line of the text. Not really sure what I did wrong but I think it's the reader part of my code.
public class FormLetter
{
final static int MAX_LINES = 20;
final static int NUM_INSERTIONS = 4;
String[] formLetter = new String[MAX_LINES];
int lines = 0;
public static void main(String[] args)
{
FormLetter letter1 = new FormLetter("formLetter..txt");
FormLetter letter2 = new FormLetter("longLetter.txt");
FormLetter letter3 = new FormLetter("formLetter.txt");
letter3.generateLetter("insertions.txt");
}
public FormLetter(String formFileName)
{
Scanner formFileIn;
String line;
Path file = Paths.get("H:\\Eclipse\\Programming Project 1\\formLetter.txt");
InputStream input = null;
try
{
formFileIn = new Scanner(new FileReader(formFileName));
while (lines < MAX_LINES && formFileIn.hasNextLine())
{
input = Files.newInputStream(file);
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
Charset.defaultCharset();
line = reader.readLine();
System.out.println(line);
}
if (formFileIn.hasNextLine())
{
System.out.println("File " + formFileName + " is too large to process.\n");
}
}
catch(FileNotFoundException fnfe)
{
System.out.println("Cannot open " + formFileName + "\n");
}
catch(IOException ioe)
{
System.out.println("Error reading from file" + formFileName);
}
}
As mentioned in the comments I was using two readers by mistake causing an infinite loop. I removed the second reader and during my loop now only put to output the next line from the file.
import java.util.Scanner;
import java.io.*;
import java.nio.file.*;
import java.nio.charset.*;
import java.nio.file.StandardOpenOption;
public class FormLetter
{
final static int MAX_LINES = 20;
final static int NUM_INSERTIONS = 4;
String[] formLetter = new String[MAX_LINES];
int lines = 0;
public static void main(String[] args)
{
FormLetter letter1 = new FormLetter("formLetter..txt");
FormLetter letter2 = new FormLetter("longLetter.txt");
FormLetter letter3 = new FormLetter("formLetter.txt");
letter3.generateLetter("insertions.txt");
}
public FormLetter(String formFileName)
{
Scanner formFileIn;
String line;
try
{
formFileIn = new Scanner(new FileReader("H:\\Eclipse\\Programming Project 1\\formLetter.txt"));
while (lines < MAX_LINES && formFileIn.hasNextLine())
{
System.out.println(formFileIn.next());
}
if (formFileIn.hasNextLine())
{
System.out.println("File " + formFileName + " is too large to process.\n");
}
}
catch(FileNotFoundException fnfe)
{
System.out.println("Cannot open " + formFileName + "\n");
}
catch(IOException ioe)
{
System.out.println("Error reading from file" + formFileName);
}
}

breaking the lines while chunking into multiple files

I am dividing my file into chunks but only problem i am facing is,
i have .srt file, but while doing chunks, it's cutting the characters i.e in first .srt file it's like 00:26:20,230 --> . in next file it continuing the next time stamp 00:27:40,343.
I need to check the timestamp to be complete and then next full subtitle sentence too. i.e if it's cutting the subtitle timesstamp or dialogue in in file, that tect to be append to next file. Please suggest me how can i achieve.
I am trying like below,
String FilePath = "/Users/meh/Desktop/escapeplan.srt";
FileInputStream fin = new FileInputStream(FilePath);
System.out.println("size: " +fin.getChannel().size());
long abc = 0l;
abc = (fin.getChannel().size())/3;
System.out.println("6: " +abc);
System.out.println("abc: " +abc);
//FilePath = args[1];
File filename = new File(FilePath);
long splitFileSize = 0,bytefileSize=0;
if (filename.exists()) {
try {
//bytefileSize = Long.parseLong(args[2]);
splitFileSize = abc;
Splitme spObj = new Splitme();
spObj.split(FilePath, (long) splitFileSize);
spObj = null;
} catch (Exception e) {
e.printStackTrace();
}
} else {
System.out.println("File Not Found....");
}
public void split(String FilePath, long splitlen) {
long leninfile = 0, leng = 0;
int count = 1, data;
try {
File filename = new File(FilePath);
InputStream infile = new BufferedInputStream(new FileInputStream(filename));
data = infile.read();
System.out.println("data");
System.out.println(data);
while (data != -1) {
filename = new File("/Users/meh/Documents/srt" + count + ".srt");
//RandomAccessFile outfile = new RandomAccessFile(filename, "rw");
OutputStream outfile = new BufferedOutputStream(new FileOutputStream(filename));
while (data != -1 && leng < splitlen) {
outfile.write(data);
leng++;
data = infile.read();
}
leninfile += leng;
leng = 0;
outfile.close();
changeTimeStamp(filename, count);
count++;
}
} catch (Exception e) {
e.printStackTrace();
}
}
i am trying to check the time stamp is in correct format or not. Then i need to check next line to be a dialogue and then the next line to be empty line. then it can stop chunk or else it should append the text from the previous chunk to next chunk file in the beginning of line . so that it may get in correct format.
I tried checking the format like,
while ((strLine = br.readLine()) != null) {
String[] atoms = strLine.split(" --> ");
if (atoms.length == 1) {
out.write(strLine + "\n");
} else {
String startTS = atoms[0];
String endTS = atoms[1];
System.out.print("sri atmos start" + startTS);
System.out.print("sri atmos end" + endTS);
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss,SSS");
sdf.setLenient(false);
try
{
sdf.parse(startTS);
sdf.parse(endTS);
System.out.println("Valid time");
System.out.println("File path" + srcFileNm);
}
catch(Exception e) {
System.out.println("Invalid time");
System.out.println("Exception start" + startTS);
System.out.println("Exception end" + endTS);
}
}
some screens of my output chunks,
Help me how can i make this possible.
I think you should change approach, and fully use basic I/O methods. I tried to encapsulate logic in a small class, that produces a triple with id, msecs and a list of subtitles (if I'm not wrong, you can have more than a line). Then I leaved the remainder externally. Chunker is a class that reads a triple (class Three) from file, so that you can manage it and write it somewhere.
This is just a "quick&dirty" idea that you can refine, but it should work.
package org.norsam.stackoverflow;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Chunker
{
BufferedReader r;
int chunk = 0;
File dir;
public Chunker(File dir, String filename) throws IOException
{
File f = new File(dir, filename);
this.dir = dir;
this.r = new BufferedReader(new FileReader(f));
}
public Three readThree() throws IOException
{
Integer id = Integer.parseInt(r.readLine());
String msecs = r.readLine();
String s = null;
List<String> srt = new ArrayList<>();
while (!(s = r.readLine().trim()).isEmpty()) {
srt.add(s);
}
return new Three(id, msecs, srt);
}
class Three
{
Integer id;
String msecs;
List<String> srts;
Three(Integer id, String msecs, List<String> srts)
{
this.id = id;
this.msecs = msecs;
this.srts = srts;
}
Three doSomething() {
// here you can do something with your data,
// e.g. split msecs on "-->" and check times
return this;
}
void write(BufferedWriter r) throws IOException
{
r.write(id);
r.newLine();
r.write(msecs);
r.newLine();
for (String s : srts) {
r.write(s);
r.newLine();
}
r.newLine();
}
}
public static void main(String[] args) throws IOException
{
String baseDir = "/dir/where/resides/srt";
String filename = "filename.srt";
int elemPerChunk = 50;
int fileNum = 0;
File dir = new File(baseDir);
Chunker chunker = new Chunker(dir, filename);
boolean completed = false;
while (!completed) {
int srtCount = 0;
File f = new File(baseDir, "ch." + (fileNum++) + "." + filename);
BufferedWriter w = new BufferedWriter(new FileWriter(f));
try {
while (srtCount++ < elemPerChunk) {
chunker.readThree().doSomething().write(w);
}
} catch (NullPointerException e) {
completed = true;
}
w.close();
}
}
}

Storing data into a file for one time and avoid any changes after running the code again

My code
Here I take a name from a user and save it to a file, my purpose is to give that name an index (Out) and save it into a file, so that each time I run the code, I will still have the same name and index(not new values). So how can I do that?
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
public class h_main {
public static void main(String[] args) {
contact[] table = new contact[3]; //Create an object of contact class
int tablesize = 3;
// Input from user
//**Inserting from user**//
Scanner reader = new Scanner(System.in); // Reading from System.in
System.out.println("Enter a name: ");
String names = reader.nextLine();
// Save the inserted name inside a table array with an index Out(from the hash function)
int Out = calc_hash(names, tablesize);
table[Out] = new contact();
table[Out].Name = names;
System.out.println(Out);
// Writing
for (int i = 0; i < table.length; i++) {
FileWriter fWriter = null;
BufferedWriter writer = null;
try {
fWriter = new FileWriter("text.txt");
writer = new BufferedWriter(fWriter);
writer.write(table[i].Name);
writer.write(table[i].phone);
writer.newLine();
writer.close();
}
// System.err.println("Your input of " + table[i].Name.length + " characters was saved.");
catch (Exception e) {
System.out.println("Error!");
}
// Reading
// The name of the file to open.
String fileName = "text.txt";
// This will reference one line at a time
String line = null;
try {
// FileReader reads text files in the default encoding.
FileReader fileReader = new FileReader("text.txt");
// Always wrap FileReader in BufferedReader.
BufferedReader bufferedReader = new BufferedReader(fileReader);
while ((line = bufferedReader.readLine()) != null) {
System.out.println("Name: " + line);
}
// Always close files.
bufferedReader.close();
} catch (FileNotFoundException ex) {
System.out.println(
"Unable to open file '" +
"text.txt" + "'");
} catch (IOException ex) {
System.out.println(
"Error reading file '" +
"text.txt" + "'");
// Or we could just do this:
// ex.printStackTrace();
}
}
}
//**Generate hash function**//
public static int calc_hash(String names, int table_size) {
int i, l = names.length();
int hash = 0;
for (i = 0; i < l; i++) {
hash += Character.getNumericValue(names.charAt(i));
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
if (hash > 0) return hash % table_size;
else return -hash % table_size;
}
}
Class contact
public class contact {
String Name ;
int phone ;
}
Have the file not exist when you run the program for the first time. After you do, use the existence of the file to determine whether the program has been run before or not. Your code could look like this:
import java.nio.file.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
// It's recommended to follow Java naming and style conventions:
// Class names always begin with an uppercase letter
Contact[] table = new Contact[3];
String fileName = "text.txt";
Path file = Paths.get(fileName);
// Check for persistence file:
if(Files.exists(file)) {
// If all you need to do is print each line, try this:
try {
Files.lines(file).forEach(l -> System.out.println("Name: " + l));
} catch(IOException e) {
System.err.println("Error reading data file!");
}
} else {
// Take data input
Scanner scanner = new Scanner(System.in);
// ...
// When program is terminated, save everything:
try(BufferedWriter writer = Files.newBufferedWriter(file)) {
// use writer to write data...
} catch(IOException e) {
System.err.println("Error writing data file!");
}
}
}
}

Make faster a read from file

I'm going to pass my data from MongoDB to Neo4j.
So, I exported my MongoDB documents in .csv. As you can read here I have a problem with the array uniform.
So I wrote a java program to fix this problem.
Here is the .csv exported from MongoDB (note the different about uniform array):
_id,official_name,common_name,country,started_by.day,started_by.month,started_by.year,championship,stadium.name,stadium.capacity,palmares.first_prize,palmares.second_prize,palmares.third_prize,palmares.fourth_prize,average_age,squad_value,foreigners,uniform
0,yaDIXxLAOV,WWYWLqPcYM,QsVwiNmeGl,7,9,1479,oYKGgstIMv,qskcxizCkd,8560,10,25,9,29,16,58,6,"[""first_colour"",""second_colour"",""third_colour""]"
Here is how it must be to import in Neo4j:
_id,official_name,common_name,country,started_by.day,started_by.month,started_by.year,championship,stadium.name,stadium.capacity,palmares.first_prize,palmares.second_prize,palmares.third_prize,palmares.fourth_prize,average_age,squad_value,foreigners,uniform.0,uniform.1,uniform.2
0,yaDIXxLAOV,WWYWLqPcYM,QsVwiNmeGl,7,9,1479,oYKGgstIMv,qskcxizCkd,8560,10,25,9,29,16,58,6,first_colour,second_colour,third_colour
My code works, but I have to convert 500k line of the .csv file and the program it is too much slow(it's still working after 20 minutes :/):
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
public class ConvertireCSV {
public static void main(String[] args) throws IOException {
FileReader f;
f=new FileReader("output.csv");
BufferedReader b;
b=new BufferedReader(f);
String firstLine= b.readLine();
int uniform = firstLine.indexOf("uniform");
firstLine=firstLine.substring(0, uniform);
firstLine = firstLine + "uniform.0,uniform.1,uniform.2\n";
String line="";
String csv="";
while(true) {
line=b.readLine();
if(line==null)
break;
int u = line.indexOf("\"[");
line=line.substring(0, u);
line=line + "first_colour,second_colour,third_colour \n";
csv=csv+line;
}
File file = new File("outputForNeo4j.csv");
if(file.createNewFile()) {
PrintWriter pw = new PrintWriter(file);
pw.println(firstLine + csv);
System.out.println("New file \"outputForNeo4j.csv\" created.");
pw.flush();
pw.close();
}
}
}
How can I make it faster?
Okay some basic ways to improve your code:
Make sure that your variables got the minimal scope required. If you don't need line outside your loop, don't declare it outside your loop.
Concatenation of simple strings is in general slow. Use a StringBuilder to speed things to there.
Why are you buffering the string anyway? Seems like a waste of memory. Just open the output stream to your target file and write the lines to the new file as you process them.
Examples:
I don't think you need a example on the first point.
For the second things could look like this:
...
StringBuilder csv = new StringBuilder();
while(true) {
...
csv.append(line);
}
...
if(file.createNewFile()) {
...
pw.println(firstLine + csv.toString());
...
}
For the third point the rewriting would be a little more extensive:
public static void main(String[] args) throws IOException {
FileReader f;
f=new FileReader("output.csv");
BufferedReader b;
b=new BufferedReader(f);
String firstLine= b.readLine();
int uniform = firstLine.indexOf("uniform");
firstLine=firstLine.substring(0, uniform);
firstLine = firstLine + "uniform.0,uniform.1,uniform.2\n";
File file = new File("outputForNeo4j.csv");
if(!file.createNewFile()) {
// all work would be for nothing! Bailing out.
return;
}
PrintWriter pw = new PrintWriter(file);
pw.print(firstLine);
while(true) {
String line=b.readLine();
if(line==null)
break;
int u = line.indexOf("\"[");
line=line.substring(0, u);
line=line + "first_colour,second_colour,third_colour \n";
pw.print(line);
}
System.out.println("New file \"outputForNeo4j.csv\" created.");
pw.flush();
pw.close();
b.close()
}
csv=csv+line;
string concatenation is expensive operation. I would suggest using bufferedWriter.
something like this:
FileReader f;
f=new FileReader("output.csv");
BufferedReader b;
BufferedWriter out;
b=new BufferedReader(f);
try{
out = new BufferedWriter(new FileWriter("outputForNeo4j.csv"));
} catch(Exception e){
//cannot create file
}
System.out.println("New file \"outputForNeo4j.csv\" created.");
String firstLine= b.readLine();
int uniform = firstLine.indexOf("uniform");
firstLine=firstLine.substring(0, uniform);
firstLine = firstLine + "uniform.0,uniform.1,uniform.2\n";
String line="";
String csv="";
out.write(firstLine);
while(true) {
line=b.readLine();
if(line==null)
break;
int u = line.indexOf("\"[");
line=line.substring(0, u);
line=line + "first_colour,second_colour,third_colour \n";
out.write(line);
}
out.flush();
}
Results :
test0 : Runs: 241 iterations ,avarage milis = 246
test1 : Runs: 249 iterations ,avarage milis = 118
test2 : Runs: 269 iterations ,avarage milis = 5
test3 : Runs: 241 iterations ,avarage milis = 2
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Random;
public class Tester {
private static final String filePath = "c:\\bigFile.txt";
//private static final String filePath = "c:\\bigfileNewLine.txt";
private static final int numOfMethods = 4;
private static final int numOfIter = 1000;
public Tester() throws NoSuchMethodException {
System.out.println("Tester.Tester");
int[] milisArr = new int [numOfMethods];
int[] actualRun = new int [numOfMethods];
Random rnd = new Random(System.currentTimeMillis());
Long startMs = 0l, endMs = 0l;
Method[] method = new Method[numOfMethods];
for (int i = 0; i < numOfMethods; i++)
method[i] = this.getClass().getMethod("test" + i);
int testCount = 0;
while (testCount++ < numOfIter) {
int testMethod = rnd.nextInt(numOfMethods);
Method m = method[testMethod];
try {
System.gc();
startMs = System.currentTimeMillis();
String retval = (String) m.invoke(null);
endMs = System.currentTimeMillis();
} catch (IllegalAccessException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (InvocationTargetException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
milisArr[testMethod] += (endMs - startMs);
actualRun[testMethod]++;
System.out.println("Test name: " + m.getName() + " testCount=" + testCount + " Of " + numOfIter + " iteration, Total time :" + (endMs - startMs) / 1000.0 + " seconds");
}
System.out.println("Test Summery :");
for (int i = 0; i < numOfMethods; i++)
System.out.println("test" + i + " : Runs: " + actualRun[i] + " iterations ,avarage milis = " + milisArr[i]/numOfIter);
}
public static String test0() throws IOException {
InputStream file = getInputStream();
StringBuffer textBuffer = new StringBuffer();
int c;
while ((c = file.read()) != -1)
textBuffer.append((char) c);
file.close();
return textBuffer.toString();
}
public static String test1() throws IOException {
Reader reader = new FileReader(new File(filePath));
BufferedReader br = new BufferedReader(reader);
String line = br.readLine();
String result = line;
while (line != null) {
line = br.readLine();
if (line == null) {
} else {
result = result + "\n" + line;
}
}
br.close();
reader.close();
return result;
}
public static String test2() throws IOException {
byte[] buf = new byte[1024];
int l;
InputStream is = getInputStream();
StringBuffer tmpBuf = new StringBuffer();
while ((l = is.read(buf)) != -1) {
tmpBuf.append(new String(buf, 0, l));
}
is.close();
return tmpBuf.toString();
}
public static String test3() throws IOException {
File source = new File(filePath);
final DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(source)));
final byte[] buffer = new byte[(int) source.length()];
dis.readFully(buffer);
dis.close();
return new String(buffer, "UTF-8");
}
private static InputStream getInputStream() {
try {
return new FileInputStream(filePath);
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) {
try {
new Tester();
} catch (NoSuchMethodException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
}

Java Exception Handling with Try in a method

I am trying to design two different methods for a Java application. The first method will pass in a string of the name of a file, and return the text of a text file as a string. The second method will pass in the name of a file and the text, and create a new text file and output the string into the file.
Currently my code works without the methods, but I am trying to design it with a separation of concerns and low coupling. I am trying to modify it so I can just call a method to output any sort of data I have in a string to a text file.
Here is my code without the methods:
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class FileCopier {
public static void main(String[] args) {
//What file should be input for reading?
String inputFile = askForInput("Please enter the name of the file to be read in: ");
//What file should be created to display output ?
String outputFile = askForInput("Please come up with a name of the file to be written backwards: ");
//Check to make sure we got the names
System.out.println("inputFile: " + inputFile + " outputFile: " + outputFile);
// Variables to read and write the files
//Call the readTextFile method to read text file into string data
String line = null;
String total = null;
BufferedReader input = null;
try {
// FileReader reads text files in the default encoding.
FileReader fileReader = new FileReader(inputFile);
// Always wrap FileReader in BufferedReader.
input = new BufferedReader(fileReader);
total = input.readLine() + "\n";
while ((line = input.readLine()) != null && total != null) {
total += line + "\n";
System.out.println("Proof that the file says: " + line);
}
input.close();
//Check to make sure we got the text files data
System.out.println("The total string says: \n" + total);
//Call the reverseWords method to switch 'Hello' with 'World'
String info = reverseWords(total);
//Check to make sure the string was reversed
System.out.println("The reversed string says: \n" + info);
File file = new File(outputFile);
BufferedWriter output = null;
output = new BufferedWriter(new FileWriter(file));
output.write(info);
System.out.println("The output file: " + outputFile + " has been written.");
output.close();
} catch (FileNotFoundException ex) {
System.out.println("Unable to open file '" +
inputFile + "'");
} catch (IOException ex) {
System.out.println("Error reading file '" + inputFile + "'");
// Or we could just do this:
// ex.printStackTrace();
}
}
public static String reverseWords(String sentence) {
String[] parts = sentence.trim().split("\\s+");
StringBuilder builder = new StringBuilder();
builder.append(parts[parts.length - 1]);
for (int i = parts.length - 2; i >= 0; --i) {
builder.append(" ").append(parts[i]);
}
return builder.toString();
}
public static String askForInput(String question) {
System.out.println(question);
Scanner in = new Scanner(System.in);
String inputFile = in.nextLine();
return inputFile;
}
}
When creating a method for each of the "read" and "write" portions of my code, I constantly get errors that I assume are from the exception handling. Any thoughts on how to separate code that has exceptions involved?
Think in terms of single responsibility. You have two distinct operations that need to happen: reading and writing.
Let's start with reading. What you're doing right now to read the file surmises these lines:
// FileReader reads text files in the default encoding.
FileReader fileReader = new FileReader(inputFile);
// Always wrap FileReader in BufferedReader.
input = new BufferedReader(fileReader);
total = input.readLine() + "\n";
while ((line = input.readLine()) != null && total != null) {
total += line + "\n";
System.out.println("Proof that the file says: " + line);
}
input.close();
Move that to a method.
private static String readFile(String inputFile) throws IOException {
BufferedReader input;
String total;
String line;// FileReader reads text files in the default encoding.
FileReader fileReader = new FileReader(inputFile);
// Always wrap FileReader in BufferedReader.
input = new BufferedReader(fileReader);
total = input.readLine() + "\n";
while ((line = input.readLine()) != null) {
total += line + "\n";
System.out.println("Proof that the file says: " + line);
}
input.close();
return total;
}
Here's what we did:
We have a variable total which is used elsewhere in the program, so that usage has to be preserved. We're returning String and will declare total = readFile(inputFile); on the outside.
We've changed nothing. This code will run the same way as it did without the method.
Now, if we want to move the writing functionality, which is:
File file = new File(outputFile);
BufferedWriter output = null;
output = new BufferedWriter(new FileWriter(file));
output.write(info);
System.out.println("The output file: " + outputFile + " has been written.");
output.close();
...we just do.
private static void writeFile(String outputFile, String info) throws IOException {
File file = new File(outputFile);
BufferedWriter output = null;
output = new BufferedWriter(new FileWriter(file));
output.write(info);
System.out.println("The output file: " + outputFile + " has been written.");
output.close();
}
Again, nothing's changed on this method. We don't have any other usages of any of the variables in here to worry about, so we can directly bring it across.
All said, that try block looks a bit anemic:
try {
total = readFile(inputFile);
//Check to make sure we got the text files data
System.out.println("The total string says: \n" + total);
//Call the reverseWords method to switch 'Hello' with 'World'
String info = reverseWords(total);
//Check to make sure the string was reversed
System.out.println("The reversed string says: \n" + info);
writeFile(outputFile, info);
} catch (FileNotFoundException ex) {
System.out.println("Unable to open file '" +
inputFile + "'");
} catch (IOException ex) {
System.out.println("Error reading file '" + inputFile + "'");
// Or we could just do this:
// ex.printStackTrace();
}
...which is a good thing.
I am not sure what are you asking about but try to create your own Exceptions and make your methods throw them like this
package com.qmic.test;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class FileCopier {
public static void main(String[] args) {
// What file should be input for reading?
String inputFile = askForInput("Please enter the name of the file to be read in: ");
// What file should be created to display output ?
String outputFile = askForInput("Please come up with a name of the file to be written backwards: ");
// Check to make sure we got the names
System.out.println("inputFile: " + inputFile + " outputFile: "
+ outputFile);
// Variables to read and write the files
// Call the readTextFile method to read text file into string data
String line = null;
String total = null;
BufferedReader input = null;
try {
String readData = readFileContents(inputFile);
// Check to make sure we got the text files data
System.out.println("The total string says: \n" + readData);
// Call the reverseWords method to switch 'Hello' with 'World'
String reversedContents = reverseWords(readData);
writeToFile(outputFile, reversedContents);
} catch (ReadException ex) {
System.out.println("Error reading file '" + inputFile + "'");
// Or we could just do this:
// ex.printStackTrace();
} catch (WriteException ex) {
System.out.println("Error Writing file '" + outputFile + "'");
// Or we could just do this:
// ex.printStackTrace();
}
}
public static String reverseWords(String sentence) {
String[] parts = sentence.trim().split("\\s+");
StringBuilder builder = new StringBuilder();
builder.append(parts[parts.length - 1]);
for (int i = parts.length - 2; i >= 0; --i) {
builder.append(" ").append(parts[i]);
}
return builder.toString();
}
public static String askForInput(String question) {
System.out.println(question);
Scanner in = new Scanner(System.in);
String inputFile = in.nextLine();
return inputFile;
}
public static void writeToFile(String fileName, String data)
throws WriteException {
BufferedWriter output = null;
try {
// Check to make sure the string was reversed
System.out.println("The reversed string says: \n" + data);
File file = new File(fileName);
output = new BufferedWriter(new FileWriter(file));
output.write(data);
System.out.println("The output file: " + fileName
+ " has been written.");
}catch(IOException e){
throw new WriteException();
}finally{
try {
output.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static String readFileContents(String fileName) throws ReadException {
// FileReader reads text files in the default encoding.
BufferedReader input = null;
String line = null;
String total = null;
try {
FileReader fileReader = new FileReader(fileName);
// Always wrap FileReader in BufferedReader.
input = new BufferedReader(fileReader);
total = input.readLine() + "\n";
while ((line = input.readLine()) != null && total != null) {
total += line + "\n";
System.out.println("Proof that the file says: " + line);
}
} catch (IOException e) {
throw new ReadException();
}finally{
//This is ugly code, if you are using java 7 you have extra option to better this
try {
input.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return total;
}
}
//make me public and move me to a separate file
class WriteException extends IOException {
}
//make me public and move me to a separate file
class ReadException extends IOException {
}

Categories