Dot Tool BinarySearchTree Java - java

I simply try to write to a dot file following addition of integers to a BinarySearchTree, but no file is generated to the project file upon execution.
public void testadd()
{
BinarySearchTree<Integer> bst = new BinarySearchTree<Integer>();
bst.add(1);
bst.add(2);
bst.add(3);
bst.add(4);
bst.add(5);
bst.writeDot("BST.dot");
}

public static PrintStream out;
public void writeToFile( ) throws IOException{
out = new PrintStream(new FileOutputStream("BST.dot"));
writeToFile(root);
out.close();
}
public void writeToFile(BinaryTreeNode t) throws IOException
{
if (t != null)
{
System.setOut(out);
System.out.println(t.info);
writeToFile(t.left);
writeToFile(t.right);
}
}

Related

Printing method that returns void to a text file

I feel like a noob for asking this question but in my current driver, I've printed out a preorder of a tree using an iterator to a text file successfully. I don't know how to print my recursive methods because I can't just put them into a println statement since they are void methods. I know that I'm supposed to make the method take the writer as a parameter but don't know how to do it (Last couple println statements of driver). Any help is appreciated!
Driver:
package driver;
import java.io.*;
import java.util.*;
public class Driver {
private static Scanner file;
static PrintWriter outputFilePrinter;
static Scanner inputFileScanner;
public static void main(String[] args) throws FileNotFoundException {
Scanner inFile; //Declaring scanner obj
PrintWriter printWriter = new PrintWriter("output.txt"); //Text file where results are printed to
inFile = new Scanner(new File("input.txt")); //Text file where student names and associated number are read from
BinarySearchTreeInterface<String> aTree = new BinarySearchTree<>() {}; //Giving access to BinarySearchTree methods
while (inFile.hasNext()) { //Scans input file
String name = inFile.nextLine(); //Assigns contents to string obj
aTree.add(name); //Add string to a tree
} //End while
Iterator<String> traverse = aTree.getPreorderIterator(); //Using iterator to print tree in an "postorder" fashion
while (traverse.hasNext())
printWriter.println(traverse.next()); //Prints tree
System.out.println("Postorder Recrusive: ");
aTree.postorderTraverse();
System.out.println("");
System.out.println("Inorder Recursive: ");
aTree.inorderTraverse();
printWriter.close(); //Closes file
} //End Main
} //End Driver
Recursive methods that I'm trying to print:
public void inorderTraverse() {
inorderTraverse(root);
}
public void inorderTraverse(BinaryNode<T> node) {
if (node != null) {
inorderTraverse(node.getLeftChild());
System.out.println(node.getData());
inorderTraverse(node.getRightChild());
}
}
public void postorderTraverse() {
postorderTraverse(root);
}
public void postorderTraverse(BinaryNode<T> node) {
if (node != null) {
postorderTraverse(node.getLeftChild());
postorderTraverse(node.getRightChild());
System.out.println(node.getData());
}
}
You could change your traversing code to
public void inorderTraverse(PrintWriter printWriter) {
inorderTraverse(root, printWriter);
}
public void inorderTraverse(BinaryNode<T> node, PrintWriter printWriter) {
if (node != null) {
inorderTraverse(node.getLeftChild(), printWriter);
printWriter.println(node.getData());
inorderTraverse(node.getRightChild(), printWriter);
}
}
public void postorderTraverse(PrintWriter printWriter) {
postorderTraverse(root, printWriter);
}
public void postorderTraverse(BinaryNode<T> node, PrintWriter printWriter) {
if (node != null) {
postorderTraverse(node.getLeftChild(), printWriter);
postorderTraverse(node.getRightChild(), printWriter);
printWriter.println(node.getData());
}
}
Or even
public void inorderTraverse(Consumer<T> consumer) {
inorderTraverse(root, consumer);
}
public void inorderTraverse(BinaryNode<T> node, Consumer<T> consumer) {
if (node != null) {
inorderTraverse(node.getLeftChild(), consumer);
consumer.accept(node.getData());
inorderTraverse(node.getRightChild(), consumer);
}
}
public void postorderTraverse(Consumer<T> consumer) {
postorderTraverse(root, consumer);
}
public void postorderTraverse(BinaryNode<T> node, Consumer<T> consumer) {
if (node != null) {
postorderTraverse(node.getLeftChild(), consumer);
postorderTraverse(node.getRightChild(), consumer);
consumer.accept(node.getData());
}
}
and call the second variant like this:
aTree.postorderTraverse(printWriter::println);
aTree.postorderTraverse(System.out::println);

Java Writing out data to an outside file

I found a way to write out the data, except, of all the words that should have been written out to the file only the last word appears in the output file.
Here's the code:
public static void main(String[] args) throws IOException {
for (String s: args) {
//here it gets the file from the doc name in the command line, goes through it, and adds all
//the words to a vector
incorporteVocab();
}
}
public static void incorporteVocab() {
String filename = "C:\\projectTests\\vocabulary.txt"; //file where to write out the vocabulary
for (String w : commonDocumentWords) {
if (!inStopList(w))
addToVocabulary(w, filename);
}
}
public static void addToVocabulary(String word, String filename) {
Vocabulary.add(word);
toDataFile(word, filename);
}
public static void toDataFile(String word, String filename) {
try {
FileWriter myWriter = new FileWriter(filename);
myWriter.write(word);
myWriter.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
Please help,
Thank you!
you can change the second parameter of FileWriter to true to make it append the new data to file:
FileWriter myWriter = new FileWriter(filename, true);

Slow performance when wrapping BufferedReader in custom FilterReader

While tinkering around with some I/O stuff, I made an interesting observation: my custom FilterReader seemed to have some unexpected performance overhead. To try and diagnose the issue, I threw together a simple performance test:
import java.io.*;
abstract class Test
{
public final long timeRun(Reader in) throws IOException
{
long start = System.nanoTime();
run(in);
long end = System.nanoTime();
return end - start;
}
protected abstract void run(Reader in) throws IOException;
}
class WrapInFilterTest extends Test
{
private class LetterFilterReader extends FilterReader
{
public LetterFilterReader(Reader in)
{
super(in);
}
#Override
public int read() throws IOException
{
int read;
while ((read = in.read()) != -1)
{
if (Character.isLetter(read))
break;
}
return read;
}
}
#Override
public void run(Reader in) throws IOException
{
try (Reader letterReader = new LetterFilterReader(in))
{
while (letterReader.read() != -1);
}
}
}
class RawReaderTest extends Test
{
#Override
public void run(Reader in) throws IOException
{
while (readLetter(in) != -1);
}
public int readLetter(Reader in) throws IOException
{
int read;
while ((read = in.read()) != -1)
{
if (Character.isLetter(read))
break;
}
return read;
}
}
public class PerformanceTest
{
public static void main(String[] args) throws IOException
{
String filePath = "/path/to/file.txt";
Test[] tests = new Test[] { new WrapInFilterTest(), new RawReaderTest() };
for (Test test : tests)
{
Reader r = new BufferedReader(new FileReader(filePath));
System.out.println(test.timeRun(r) + "ns");
}
}
}
In general, I've found that the custom filter approach can be as much as 3x slower than straight up reading from the buffered reader. However, it seems dependent on the file content. For example, if a file contains strictly letters, I've found that the custom filter approach actually performs marginally faster! What's going on?

How to tie a PrintStream to the System.out and err streams

I'm trying to tie my PrintStream object to the console's output and error streams so that whatever I write there will also be written to my log file.
public static void tieOutputStreams(String fileName) {
try {
File output = new File(fileName);
FileWriter writer = new FileWriter(output);
writer.close();
outputStream = new TiedOutputStream(output);
}
catch (Exception e) {
e.printStackTrace();
}
System.setErr(outputStream);
System.setOut(outputStream);
}
Once I'm done writing, I could reset it back to the way things were.
public static void resetOutputStreams() {
outputStream.close();
System.setErr(System.err);
System.setOut(System.out);
}
TiedOutputStream class looks like this:
public class TiedOutputStream extends PrintStream {
public TiedOutputStream(File logFile) throws FileNotFoundException {
super(logFile);
}
#Override
public void print(Object obj) {
super.print(obj);
System.out.print(obj);
}
#Override
public PrintStream printf(String format, Object... args) {
super.printf(format, args);
System.out.printf(format, args);
return this;
}
#Override
public void println(Object args) {
super.println(args);
System.out.println(args);
}
}
And my main method:
public static void main(String[] args) {
try {
TieOutputStreams.tieOutputStreams("./sample.log");
System.out.println("Output console");
System.err.println("Error console");
float num = 1.123456f;
System.out.printf("A float: %.6f", num);
} catch (Exception e) {
e.printStackTrace();
}
finally {
TieOutputStreams.resetOutputStreams();
}
}
I want these statements to be printed on both my log file and the System consoles (out / err). For reasons I don't know, this isn't working. I appreciate all the answers and comments. Thanks in advance!
I know there is Log4j. But I want to do this anyway.
This doesn't work mainly because you didn't save the original System.out and because you didn't override println(String obj) When you call System.out.println("Output console"); you won't hit in the method you override because that one expects and object and there is a more specific method in PrintStream that expects a String argument
This seems to work:
public class TiedOutputStream extends PrintStream {
private final PrintStream sout;
private final PrintStream serr;
public TiedOutputStream(File logFile) throws FileNotFoundException {
super(logFile);
sout = System.out;//save standard output
serr = System.err;
}
#Override
public void print(Object obj) {
super.print(obj);
sout.print(obj);
}
#Override
public void println(String obj) {
super.println(obj);
sout.println(obj);
}
#Override
public PrintStream printf(String format, Object... args) {
super.printf(format, args);
sout.printf(format, args);
return this;
}
#Override
public void println(Object args) {
super.println(args);
sout.println(args);
}
}
Not sure why tieOutputStreams created that FileWriter
public static void tieOutputStreams(String fileName) {
try {
File output = new File(fileName);
outputStream = new TiedOutputStream(output);
System.setErr(outputStream);
System.setOut(outputStream);
} catch (Exception e) {
e.printStackTrace();
}
}
main method remains the same. You should update resetOutputStreams to restore to original out and err. I would override all print* method from PrintStream if I would use this.

Java - Capturing System.err.println or Capturing a PrintStream

Java Newbie question :
I need to capture the text being written to a printStream by a 3rd party component.
The PrintStream is defaulted to System.err, but can be changed to another PrintStream.
Looking through the docs, I couldn't find an easy way to direct the contents of a PrintStream to a string writer / buffer.
Can someone please assist?
PipedOutputStream pipeOut = new PipedOutputStream();
PipedInputStream pipeIn = new PipedInputStream(pipeOut);
System.setOut(new PrintStream(pipeOut));
// now read from pipeIn
import java.io.*;
public class Test {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream("errors.txt");
} catch(IOException ioe) {
System.err.println("redirection not possible: "+ioe);
System.exit(-1);
}
PrintStream ps = new PrintStream(fos);
System.setErr(ps);
System.err.println("goes into file");
}
}
You can create a PrintStream around any other OutputStream.
The simplest way to create one that goes to a buffer in memory would be:
PrintStream p = new PrintStream( new ByteArrayOutputStream() )
Then you could read and reset the contents of the byte array at whatever points you like.
Another possibility would be to use pipes.
InputStream third_party_output = new PipedInputStream();
PrintStream p = new PrintStream( new PipedOutputStream( third_party_output ) );
Then you could read from the third_party_output stream to get the text written by the library.
Are you looking for something like this?
OutputStream redirect = System.err;
PrintStream myPrintStream = new PrintStream(redirect);
myPrintStream.println("hello redirect");
If you can pass myPrintStream to the 3rd party application, you can redirect it anywhere you want.
I use the following class to log System.out and System.err to a set of rotating files (where xxx-001.log is the most recent). It contains a few call to utility methods, which you will need to implement before it will compile - they should be self-explanatory.
import java.io.*;
import java.lang.reflect.*;
public class LoggerOutputStream
extends OutputStream
{
// *****************************************************************************
// INSTANCE PROPERTIES
// *****************************************************************************
private FileOutputStream log=null; // the base output stream
private String fnmBase,fnmExt; // filename base, file extension
private int fnmCount,fnmLast; // count for filename index, last filename used
private int logSize,totWritten; // max log size, current number of bytes written
// *****************************************************************************
// INSTANCE CONSTRUCTORS/INIT/CLOSE/FINALIZE
// *****************************************************************************
public LoggerOutputStream(String baseFilename) throws IOException {
this(baseFilename,".log",2,1024000);
}
public LoggerOutputStream(String baseFilename, String extension) throws IOException {
this(baseFilename,extension,2,1024000);
}
public LoggerOutputStream(String baseFilename, String extension, int numberOfFiles, int maxFileSize) throws IOException {
fnmBase=baseFilename;
if(Character.isLetterOrDigit(fnmBase.charAt(fnmBase.length()-1))) { fnmBase=(fnmBase+"-"); }
fnmExt=extension;
if(!fnmExt.startsWith(".")) { fnmExt=('.'+fnmExt); }
fnmCount=numberOfFiles;
logSize=maxFileSize;
if(fnmCount>MAXLOGS) { fnmCount=MAXLOGS; }
fnmLast=0;
for(int xa=1; xa<=MAXLOGS; xa++) {
if(!new File(constructFilename(xa)).exists()) {
while((--xa)>fnmCount) { IoUtil.deleteFile(constructFilename(xa)); }
fnmLast=xa;
break;
}
}
log=null;
openFile(false);
if(numberOfFiles>MAXLOGS) { System.out.println("** Log File Count Limited To "+MAXLOGS); }
}
public void close() throws IOException {
close(false);
}
private void openFile(boolean ovrflw) throws IOException {
close(true);
if (fnmLast< fnmCount) { fnmLast++; }
else if(fnmLast==fnmCount) { IoUtil.deleteFile(constructFilename(fnmCount)); }
for(int xa=fnmLast; xa>0; xa--) { IoUtil.renameFile(constructFilename(xa-1),constructFilename(xa)); }
log=new FileOutputStream(constructFilename(1));
totWritten=0;
}
private String constructFilename(int index) {
return constructFilename(fnmBase,index,fnmExt);
}
private synchronized void close(boolean ovrflw) throws IOException {
if(log!=null) {
log.flush();
log.close();
log=null;
}
}
// *****************************************************************************
// INSTANCE METHODS - ACCESSORS
// *****************************************************************************
public String getFilename() {
return constructFilename(1);
}
public String getFilename(int idx) {
return constructFilename(idx);
}
public synchronized void cycleLogFile() throws IOException {
openFile(true);
}
// *****************************************************************************
// INSTANCE METHODS
// *****************************************************************************
public synchronized void flush() throws IOException {
if(log!=null) {
log.flush();
}
}
public synchronized void write(int val) throws IOException {
if(log!=null) {
log.write(val);
totWritten++;
if(val=='\n') {
if(totWritten>logSize) { openFile(true); }
else { log.flush(); }
}
}
}
public synchronized void write(byte[] bytes) throws IOException {
if(log!=null) {
log.write(bytes);
totWritten+=bytes.length;
if(bytes.length>0 && bytes[bytes.length-1]=='\n') {
if(totWritten>logSize) { openFile(true); }
else { log.flush(); }
}
}
}
public synchronized void write(byte[] bytes, int str, int len) throws IOException {
if(log!=null) {
log.write(bytes,str,len);
totWritten+=len;
if(bytes.length>(str+len-1) && bytes[str+len-1]=='\n') {
if(totWritten>logSize) { openFile(true); }
else { log.flush(); }
}
}
}
// *****************************************************************************
// STATIC PROPERTIES
// *****************************************************************************
static public final int MAXLOGS=999; // maximum log files allowed
// *****************************************************************************
// STATIC METHODS
// *****************************************************************************
static public String constructFilename(String bas, int idx, String ext) {
if(!bas.endsWith("-") && !bas.endsWith("_") && !bas.endsWith(".")) { bas=(bas+"-"); }
if(!ext.startsWith(".") ) { ext=('.'+ext); }
return (bas+TextUtil.raZeros(idx,3)+ext);
}
} /* END PUBLIC CLASS */

Categories