First Java program (writing permutations to a file) - java

I'm trying to write combinations with repetitions to a text file, the problems is I'm trying to hack together some code without knowing the inner workings of java. I'm not really sure what I'm effecting when I'm rearranging the code.
import java.io.*;
public class Main {
public static void main(String args[]) {
brute("123", 3, new StringBuffer());
}
static void brute(String input, int depth, StringBuffer output) {
if (depth == 0) {
// System.out.println(output);
{
try{
// Create file
FileWriter fstream = new FileWriter("out.txt",true);
BufferedWriter out = new BufferedWriter(fstream);
out.write("blah" + output);}
else {
for (int i = 0; i < input.length(); i++) {
output.append(input.charAt(i));
brute(input, depth - 1, output);
output.deleteCharAt(output.length() - 1);
}
}
}
}
}
Any help is appreciated

I guess the problem is that you get an empty file at the end of running the application?
You should simplify the bit that writes the code out:
FileWriter fstream = new FileWriter("out.txt",true);
BufferedWriter out = new BufferedWriter(fstream);
out.write("blah" + output);
You're opening a file each time and writing it out. That's ok (best to write it to an already opened stream), but you don't need to create a BufferedWriter and you can simplify the code a bit more.
FileWriter fstream = new FileWriter("out.txt", true);
fstream.append(output);
If you run this code you'll still find that it doesn't work and it just produces an empty file on disk. It's important to close the after you've used it. Changing the above to:
FileWriter fstream = new FileWriter("out.txt", true);
fstream.append(output).append('\n');
fstream.close();
Seems to make the program work (there's a few syntax errors in the code, such as forgetting to catch/throw the checked exceptions, but I assume that's just because the code was copied in manually).
Suggestions for how to tidy this up more:
Write to a stream instead of opening and closing the file every time you write an item out
Use finally to ensure that your files are always closed, even in the event of an exception

Related

Is it incorrect to open a file for writing before it has been closed for reading?

I am refactoring a small tool which needs to iterate over a list of files and modify them on the fly.
At the moment it performs the modification operation in one method, which means it reads the file to memory, modifies the content within memory, and writes that content back to the same file location.
It is doing so all within a couple of try-with-resource statements. However, this means that the 'open for write' gets done before the read is closed.
I provide here below a small approximation (see method "correctTxt").
To test that, please create a file "FileQuestion.txt"
with text such as
The quick brown elephant jumps over the lazy dog
public class Demo
{
public static void main(String[] args) throws Exception
{
final File txtFile = new File("FileQuestion.txt");
correctTxt(txtFile);
}
static void correctTxt(File txtFile) throws IOException
{
try (BufferedReader reader = new BufferedReader(new InputStreamReader (new BufferedInputStream(new FileInputStream(txtFile))))) {
String line = reader.readLine();
if (line!=null) {
line = line.replace("elephant", "fox");
try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(txtFile))) {
bos.write(line.getBytes());
bos.flush();
}
}
}
}
}
It works. It is all done in a single process (single thread).
The question is,
Is it fundamentally incorrect to perform the write operation before the close of the read, in the way that is done in the method correctTxt ?
Note: It is not intended, after the first read, that any further read be done.
Good question. I'd say it's probably technically not a problem, but... I see is that the scope of the try-with is unnecessarily big and if you would reduce the scope to where it's needed, you wouldn't even be in this situation.
See this version of the correctTxt with minimized try-with scopes
static void correctTxt(File txtFile) throws IOException {
String line;
try (BufferedReader reader = new BufferedReader(new InputStreamReader (new BufferedInputStream(new FileInputStream(txtFile))))) {
line = reader.readLine();
}
if (line!=null) {
line = line.replace("elephant", "fox");
try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(txtFile))) {
bos.write(line.getBytes());
bos.flush();
}
}
}

How can I prevent PrintWriter from printing a blank line at the beginning of each file?

I'm trying to write a couple of methods to save a binary tree to a file. They work correctly, except for a slight problem. The problem is that a blank line is inserted at the beginning of each file that's created. Why is PrintWriter doing this, and how can I prevent it from happening?
Here's my code:
import java.io.*;
void callSaveGame(String fileName) throws IOException {
PrintWriter out = new PrintWriter(new FileWriter("X:\\path\\to\\save\\directory\\" + fileName)); // associate PrintWriter with file
saveGame(root, out);
out.close();
}
void saveGame(Node current, PrintWriter out) {
if (current != null) {
out.println(current.getData()); // print node to file
saveGame(current.getLChild(), out); // call for left child(ren)
saveGame(current.getRChild(), out); // call for right child(ren)
}
}
It is not PrintWriter that is inserting the blank line. PrintWriter won't do that.
The actual cause of the problem is not shown in the code snippet you provided, but if the code is an accurate reflection of your real application, then the offending blank line is already in the result of the first getData() call.
Try to use out.print(current.getData()) instead of println().
It helped me to resolve this problem.
UPD:
In case if you need to print several lines, let's say from an ArrayList (myList):
for (int i = 0; i < myList.size(); i++) {
if (i == (myList.size() - 1)) {
out.print(myList.get(i));
} else {
out.println(myList.get(i));
}
}

Java - Scanner not scanning after a certain number of lines

I'm doing some relatively simple I/O in Java. I have a .txt files that I'm reading from using a Scanner and a .txt file I'm writing to using a BufferedWriter. Another Scanner then reads that file and another BufferedWriter then creates another .txt file. I've provided the code below just in case, but I don't know if it will help too much, as I don't think the code is the issue here. The code compiles without any errors, but it's not doing what I expect it to. For some reason, charReader will only read about half of its file, then hasNext() will return false, even though the end of the file hasn't been reached. These aren't big text files - statsReader's file is 34 KB and charReader's file is 29 KB, which is even weirder, because statsReader reads its entire file fine, and it's bigger! Also, I do have that code surrounded in a try/catch, I just didn't include it.
From what I've looked up online, this may happen with very large files, but these are quite small, so I'm pretty lost.
My OS is Windows 7 64-bit.
Scanner statsReader = new Scanner(statsFile);
BufferedWriter statsWriter = new BufferedWriter(new FileWriter(outputFile));
while (statsReader.hasNext()) {
statsWriter.write(statsReader.next());
name = statsReader.nextLine();
temp = statsReader.nextLine();
if (temp.contains("form")) {
name += " " + temp;
temp = statsReader.next();
}
statsWriter.write(name);
statsWriter.newLine();
statsWriter.write(temp);
if (! (temp = statsReader.next()).equals("-"))
statsWriter.write("/" + temp);
statsWriter.write("\t");
statsWriter.write(statsReader.nextInt() + "\t");
statsWriter.write(statsReader.nextInt() + "\t");
statsWriter.write(statsReader.nextInt() + "\t");
statsWriter.write(statsReader.nextInt() + "\t");
statsWriter.write(statsReader.nextInt() + "\t");
statsWriter.write(statsReader.nextInt() + "");
statsWriter.newLine();
statsReader.nextInt();
}
Scanner charReader = new Scanner(charFile);
BufferedWriter codeWriter = new BufferedWriter(new FileWriter(codeFile));
while (charReader.hasNext()) {
color = charReader.next();
name = charReader.nextLine();
name = name.replaceAll("\t", "");
typing = pokeReader.next();
place = charReader.nextInt();
area = charReader.nextInt();
def = charReader.nextInt();
shape = charReader.nextInt();
size = charReader.nextInt();
spe = charReader.nextInt();
index = typing.indexOf('/');
if (index == -1) {
typeOne = determineType(typing);
typeTwo = '0';
}
else {
typeOne = determineType(typing.substring(0, index));
typeTwo = determineType(typing.substring(index+1, typing.length()));
}
}
SSCCE:
public class Tester {
public static void main(String[] args) {
File statsFile = new File("stats.txt");
File testFile = new File("test.txt");
try {
Scanner statsReader = new Scanner(statsFile);
BufferedWriter statsWriter = new BufferedWriter(new FileWriter(testFile));
while (statsReader.hasNext()) {
statsWriter.write(statsReader.nextLine());
statsWriter.newLine();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
This is a classic problem: You need to flush and close the output stream (in this case statsWriter) before reading the file.
Being buffered, it doesn't actually write to the file with ever call to write. Calling flush forces it to complete any pending write operations.
Here's the javadoc for OutputStream.flush():
Flushes this output stream and forces any buffered output bytes to be written out. The general contract of flush is that calling it is an indication that, if any bytes previously written have been buffered by the implementation of the output stream, such bytes should immediately be written to their intended destination.
After you have written your file with your statsWriter, you need to call:
statsWriter.flush();
statsWriter.close();
or simply:
statsWriter.close(); // this will call flush();
This is becuase your are using a Buffered Writer, it does not write everything out to the file as you call the write functions, but rather in buffered chunks. When you call flush() and close(), it empties all the content it still has in it's buffer out to the file, and closes the stream.
You will need to do the same for your second writer.

java print stream and printwriter

I am stuck on why my program is not working, I am trying to print to a file however, where it says student[i].listCourses(System.out); I actually need it to print to the test.txt file also but I tried putting in outputFile and it didn't work
System.out.println("Please Enter A FileName");
// Create a PrintWriter object and open the file.
PrintWriter outputFile = new PrintWriter("test.txt");
// Get data and write it to the file.
// Continue reading till a blank line is entered
int i=0;
do
{
while ((student[i] != null)&&(i <= student.length)){
student[i].addCourse(course[i]);
outputFile.println(student[i].toString());
student[i].listCourses(System.out);
i++;
}
and this is how listcourses is declared
public void listCourses(PrintStream p) {
for (Course crs: courses)
if (crs != null)
p.println(crs);
}
Here's an issue
while ((student[i] != null)&&(i <= student.length)){
lets assume that i == student.length, what happens?
I'm assuming that your code does not compile for you at the moment. The issue is that your outputFile is a PrintWriter while System.out is a PrintStream. These are not interchangeable. Check out the inheritance hierarchy on each documentation page:
http://download.oracle.com/javase/6/docs/api/java/io/PrintWriter.html
http://download.oracle.com/javase/6/docs/api/java/io/PrintStream.html
If you need to use the same function for both objects, you'll have to reconsider what you're passing in (e.g. an OutputStream with System.out and FileOutputStream instead) or make two functions, one that takes in a PrintWriter and one that takes in a PrintStream.

How Can I Reset The File Pointer to the Beginning of the File in Java?

I am writing a program in Java that requires me to compare the data in 2 files. I have to check each line from file 1 against each line of file 2 and if I find a match write them to a third file. After I read to the end of file 2, how do I reset the pointer to the beginning of the file?
public class FiFo {
public static void main(String[] args)
{
FileReader file1=new FileReader("d:\\testfiles\\FILE1.txt");
FileReader file2=new FileReader("d:\\testfiles\\FILE2.txt");
try{
String s1,s2;
while((s1=file1.data.readLine())!=null){
System.out.println("s1: "+s1);
while((s2=file2.data.readLine())!=null){
System.out.println("s2: "+s2);
}
}
file1.closeFile();
file2.closeFile();
}catch (IOException e) {
e.printStackTrace();
}
}
}
class FileReader {
BufferedReader data;
DataInputStream in;
public FileReader(String fileName)
{
try{
FileInputStream fstream = new FileInputStream(fileName);
data = new BufferedReader(new InputStreamReader(fstream));
}
catch (IOException e) {
e.printStackTrace();
}
}
public void closeFile()
{
try{
in.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
I believe RandomAccessFile is what you need. It contains: RandomAccessFile#seek and RandomAccessFile#getFilePointer.
rewind() is seek(0)
I think the best thing to do would be to put each line from file 1 into a HashMap; then you could check each line of file 2 for membership in your HashMap rather than reading through the entire file once for each line of file 1.
But to answer your question of how to go back to the beginning of the file, the easiest thing to do is to open another InputStream/Reader.
Obviously you could just close and reopen the file like this:
while((s1=file1.data.readLine())!=null){
System.out.println("s1: "+s1);
FileReader file2=new FileReader("d:\\testfiles\\FILE2.txt");
while((s2=file2.data.readLine())!=null){
System.out.println("s2: "+s2);
//compare s1 and s2;
}
file2.closeFile()
}
But you really don't want to do it that way, since this algorithm's running time is O(n2). if there were 1000 lines in file A, and 10000 lines in file B, your inner loop would run 1,000,000 times.
What you should do is read each line and store it in a collection that allows quick checks to see if an item is already contained(probably a HashSet).
If you only need to check to see that every line in file 2 is in file 1, then you just add each line in file one to a HashSet, and then check to see that every line in file 2 is in that set.
If you need to do a cross comparison where you find every string that's in one but not the other, then you'll need two hash sets, one for each file. (Although there's a trick you could do to use just one)
If the files are so large that you don't have enough memory, then your original n2 method would never have worked anyway.
well, Gennady S. answer is what I would use to solve your problem.
I am writing a program in Java that requires me to compare the data in 2 files
however, I would rather not code this up again.. I would rather use something like http://code.google.com/p/java-diff-utils/
As others have suggested, you should consider other approaches to the problem. For the specific question of returning to a previous point in a file, java.io.FileReader would appear to inherit mark() and reset() methods that address this goal. Unfortunately, markSupported() returns false.
Alternatively, BufferedReader does support mark(). The program below prints true, illustrating the effect.
package cli;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class FileReaderTest {
public static void main(String[] args) {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(
new FileInputStream("src/cli/FileReaderTest.java")));
in.mark(1);
int i1 = in.read(); in.read(); in.read();
in.reset();
int i2 = in.read();
System.out.println(i1 == i2);
} catch (IOException e) {
e.printStackTrace(System.err);
}
}
}
As noted, there are better algorithms - investigate these
aside:
FileReader doesn't implement mark and reset, so trashgod's comments are inaccurate.
You'd either have to implement a version of this (using RandomAccessFile or what not) or wrap in a BufferedReader. However, the latter will load the whole thing in memory if you mark it
Just a quick Question. can't you keep one object pointed at the start of the file and traverse through the file with another object? Then when you get to the end just point it to the object at the beginning of the file(stream). I believe C++ has such mechanisms with file I/O ( or is it stream I/O)
I believe that you could just re-initialize the file 2 file reader and that should reset it.
If you can clearly indentify the dimension of your file you can use mark(int readAheadLimit) and reset() from the class BufferedReader.
The method mark(int readAhedLimit) add a marker to the current position of your BufferedReader and you can go back to the marker using reset().
Using them you have to be careful to the number of characters to read until the reset(), you have to specify them as the argument of the function mark(int readAhedLimit).
Assuming a limit of 100 characters your code should look like:
class MyFileReader {
BufferedReader data;
int maxNumberOfCharacters = 100;
public MyFileReader(String fileName)
{
try{
FileInputStream fstream = new FileInputStream(fileName);
data = new BufferedReader(new InputStreamReader(fstream));
//mark the current position, in this case the beginning of the file
data.mark(maxNumberOfCharacters);
}
catch (IOException e) {
e.printStackTrace();
}
}
public void resetFile(){
data.reset();
}
public void closeFile()
{
try{
in.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
If you just want to reset the file pointer to the top of the file, reinitialize your buffer reader. I assume that you are also using the try and catch block to check for end of the file.
`//To read from a file.
BufferedReader read_data_file = new BufferedReader(new FileReader("Datafile.dat"));'
Let's say this is how you have your buffer reader defined. Now, this is how you can check for end of file=null.
boolean has_data= true;
while(has_data)
{
try
{
record = read_data_file.readLine();
delimit = new StringTokenizer(record, ",");
//Reading the input in STRING format.
cus_ID = delimit.nextToken();
cus_name = delimit.nextToken();'
//And keep grabbing the data and save it in appropriate fields.
}
catch (NullPointerException e)
{
System.out.println("\nEnd of Data File... Total "+ num_of_records
+ " records were printed. \n \n");
has_data = false; //To exit the loop.
/*
------> This point is the trouble maker. Your file pointer is pointing at the end of the line.
-->If you want to again read all the data FROM THE TOP WITHOUT RECOMPILING:
Do this--> Reset the buffer reader to the top of the file.
*/
read_data_file = new BufferedReader(new FileReader(new File("datafile.dat")));
}
By reinitializing the buffer reader you will reset the file reader mark/pointer to the top of the file and you won't have to recompile the file to set the file reader marker/pointer to beginning/top of the file.
You need to reinitialize the buffer reader only if you don't want to recompile and pull off the same stunt in the same run. But if you wish to just run loop one time then you don't have to all this, by simply recompiling the file, the file reader marker will be set to the top/beginning of the file.

Categories