Input IO in Java
Input and Output in Java
Stream is a passway for data transfer
- InputStream : reads data from a source
- OutputStream : writes data to a destination
1. ByteStream
- FileInputStream
- ByteArrayInputStream
- PipedInputStream
-
AudioInputStream
- In case when the file is made of characters, ‘FileReader/Writer’ can be used. All bytestreams have 1 byte unit, meaning they read and write by one byte. In Java, one character takes 2 bytes, hence using bytestream in processing characters may cause some troubles. Below is the example of using FileReader/Writer
public class IOStream {
public static void main(String[] args) {
try(FileReader in = new FileReader(new File("input.txt"));
FileWriter out = new FileWriter("output.txt")){ //try with source
int c;
while ((c = in.read()) != -1){
out.write(c);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
-
Executing above code in intelliJ may cause ‘FileNotFoundException’.
-
This is because the input.txt file is not referenced correctly when executing the compiled Java file. To tackle this problem,
- Find where .class file is located. In my case, it was out/IOSTREAM_PACKAGE/IOStream.class.
- place input.txt file in the upper directory of where IOStream.class is located.
- Run java IOSTREAM_PACKAGE.IOStream
- Observe output.txt is created.
2. FilterStream
2-1. BufferedStream
-
FilterInputStream/FilterOutputStream are inherited from InputStream/OutputStream. They cannot perform I/O by themselves, hence necessitates byteStreams for operation. Let us look at the BufferedStreams.
-
Why is BufferedStream better? (https://medium.com/@isaacjumba/why-use-bufferedreader-and-bufferedwriter-classses-in-java-39074ee1a966) It is good because it can process data in bulk, instead of in one byte. Accessing data in disc, copying the byte, and converting it back to character per byte takes a lot of resources; instead if a bulk of data is copied at once, the unnecessary repetition of accessing the disc, converting them to characters etc is no more. Here is a code example.
public static void main(String[] args) {
try(FileInputStream in = new FileInputStream(new File("input.txt"));
BufferedInputStream bufferedInputStream = new BufferedInputStream(in, 5);
FileOutputStream out = new FileOutputStream("output.txt");
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(out, 5)){ //try with source
int c;
while ((c = bufferedInputStream.read()) != -1){
bufferedOutputStream.write(c);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
2-2 SequenceInputStream
- SequenceInputStream enables multiple inputstreams to be combined to one stream. Besides its constructor, other functionalities are identical. Here goes a code example.
public static void main(String[] args) throws IOException {
byte[] arr1 = {0,1,2};
byte[] arr2 = {3,4,5};
byte[] arr3 = {6,7,8};
byte[] outSrc = null;
Vector v = new Vector();
v.add(new ByteArrayInputStream(arr1));
v.add(new ByteArrayInputStream(arr2));
v.add(new ByteArrayInputStream(arr3));
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int data = 0;
try(SequenceInputStream sequenceInputStream = new SequenceInputStream(v.elements())){
while((data = sequenceInputStream.read()) != -1){
byteArrayOutputStream.write(data);
}
}
outSrc = byteArrayOutputStream.toByteArray();
System.out.println(Arrays.toString(outSrc));
}
[0, 1, 2, 3, 4, 5, 6, 7, 8]
2-3 PipedStream
-
PipedReader/Writer is used when transferring data between two threads. Unlike other streams, pipedstreams connect input and output into one stream when exchanging the data.
-
One thread calls ‘connect()’ function to connect with the other thread. After I/O is done, closing one stream automatically closes the other.
public class PipedStream {
public static void main(String[] args) {
InputThread inputThread = new InputThread("in");
OutputThread outputThread = new OutputThread("out");
inputThread.connect(outputThread.getOutput());
inputThread.start();
outputThread.start();
}
}
public class InputThread extends Thread{
PipedReader pipedReader = new PipedReader();
StringWriter stringWriter = new StringWriter();
InputThread(String name){
super(name);
}
public void run(){
try{
int data = 0;
while((data = pipedReader.read())!=-1){
stringWriter.write(data);
}
System.out.println(getName() + " received : " + stringWriter.toString());
}catch (IOException e) {
e.printStackTrace();
}
}
public PipedReader getInput(){
return pipedReader;
}
public void connect(PipedWriter pipedWriter){
try{
pipedReader.connect(pipedWriter);
}catch(IOException e){
}
}
}
public class OutputThread extends Thread{
PipedWriter pipedWriter = new PipedWriter();
OutputThread(String name) {
super(name);
}
public void run(){
try{
String message = "hello! sending..";
System.out.println(getName() + " set : " + message);
pipedWriter.write(message);
pipedWriter.close();
}catch(IOException e){
}
}
public PipedWriter getOutput(){
return pipedWriter;
}
public void connect(PipedReader pipedReader){
try{
pipedWriter.connect(pipedReader);
} catch (IOException e) {
e.printStackTrace();
}
}
}
out set : hello! sending..
in received : hello! sending..