Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write Strings to an OutputStream

How can I create class that takes an implentation of OutputStream and writes the the content to it?

For example, the following print method is wrong and will not compile. What are the options or better techniques?

public class FooBarPrinter{
    private OutputStream o;
    public FooBarPrinter(OutputStream o){
        this.o=o;
    }

    public void print(String s){        
        o.write(s);
    }
}
like image 437
user1434257 Avatar asked Jun 04 '12 02:06

user1434257


People also ask

How do you write OutputStream?

Methods of OutputStream write() - writes the specified byte to the output stream. write(byte[] array) - writes the bytes from the specified array to the output stream. flush() - forces to write all data present in output stream to the destination. close() - closes the output stream.

Which writes text from character to output stream?

The Java OutputStreamWriter is useful if you need to write characters to a file, encoded as e.g. UTF-8 or UTF-16. You can then write the characters ( char values) to the OutputStreamWriter and it will encode them correctly and write the encoded bytes to the underlying OutputStream .

What is used to create an OutputStream?

Which of the following is used to create an output stream? Explanation: ofstream is used to create an output stream in C++ file handling operations.

What is an OutputStream?

1.2 OutputStream: OutputStream is an abstract class of Byte Stream that describes stream output and it is used for writing data to a file, image, audio, etc. Thus, OutputStream writes data to the destination one at a time.


3 Answers

A generic OutputStream doesn't have the ability to write a String directly to it. Instead, you need to get the byte[] of the String and then write them out to the stream.

public void print(String s){ 
    o.write(s.getBytes());
}

Refer to the OutputStream java documentation for more information on the supported write data types.

My suggestion for making this better is to make sure the OutputStream you provide in the constructor is a BufferedOutputStream, as this will improve the performance of your code. It works by buffering some of the data in memory, and writing it out to disk in big chunks instead of many smaller writes.

Here is the java documentation for BufferedOutputStream

like image 176
wattostudios Avatar answered Oct 12 '22 23:10

wattostudios


I think that the other answers are missing an important point / question.

Should you really be using an OutputStream?

The OutputStream and InputStream class hierarchies are for writing and reading byte-oriented data. But Java Strings are not byte-oriented. They are character-oriented (to a first approximation), and characters in Java are 16-bit Unicode code units.

When you write characters to a byte stream, the JVM has to do a conversion to encode the characters as bytes. In fact, there are many possible ways to do this. For example, UTF-8 will encode each character in the sequence as a one or more bytes, Latin-1 or ASCII will encode a subset of characters as single bytes and turn others into (probably) question marks. And so on.

Now, it is possible to write something like this:

  public void print(String s){ 
      o.write(s.getBytes());
  }

but it has a problem. The problem is that the getBytes() method on a String uses the JVM's default character encoding scheme to do the conversion. And this (the default encoding scheme) depends on the environment which the JVM was launched. So that code, does different things depending on the environment. Now you could fix that by specifying the charset:

  public void print(String s){ 
      o.write(s.getBytes("UTF-8"));
  }

but that gets cumbersome if you are calling getBytes in lots of places.

If you are doing a lot of text-based output, a better idea is to use the Writer API instead of the OutputStream API. The Writer API and its implementations deal with the conversion under the hood ... and more consistently and efficiently.

The final point is that there are other APIs that can be helpful in doing text-based output.

  • The BufferedWriter class (and also BufferedOutputStream) support efficient output by introducing in-memory buffering into the output process. This saves system calls, especially if you are doing lots of small write operations.
  • The PrintWriter class provides a whole lot of convenience methods, and also removes the need to handle IOExceptions. (If an IOException occurs, the PrintWriter makes a note of it. There is a method for testing whether an exception has occurred. This can be useful or dangerous, depending on what you are doing ...)
like image 29
Stephen C Avatar answered Oct 13 '22 00:10

Stephen C


To write out strings, take a look at the PrintStream class. You can see an example of a class that does what you intend here.

Also, you can wrap an OutputStream using one of the PrintStream constructors:

public class FooBarPrinter{
  private PrintStream p;
  public FooBarPrinter(OutputStream o){
    p = new PrintStream(o);
  }
  public void print(String s){      
    p.print(s);
  }
}

EDIT: note that you can also use the PrintWriter class in the same manner as PrintStream above; which is typically better because you can specify the encoding to use, avoiding any platform dependencies.

like image 40
Jordão Avatar answered Oct 13 '22 01:10

Jordão