JavaRush /Java Blog /Random EN /Coffee break #169. Comparison of types. Java.io - I/O Ope...

Coffee break #169. Comparison of types. Java.io - I/O Operations in Java

Published in the Random EN group

Comparison of types in Java

Source: Theflashreads In this post, you will learn about several types comparison options in Java. Coffee break #169.  Comparison of types.  Java.io - I/O Operations in Java - 1The most common way to determine whether a given object is an instance of a given class, superclass, or interface is to use the binary instanceof operator . It includes an implicit null check and generates a compile-time error if the types are not bound. However, it does not allow the use of primitives and requires that the types be known at compile time.

If you need dynamic runtime checking

In this case, use the equivalent boolean isInstance(Object obj) method in Class . It also includes null checking, but allows primitives:
a instanceof B
    // returns false for null
    null instanceof B

    a.getClass().isInstance(b);
    // commonly used for generics
    Class<T> type = b.getClass();
    type.isInstance(a);

    // Note that the parameter is autoboxed to type Integer
    int x = 4;
    Integer.class.isInstance(x);

Checking compatibility of two types

If you need to check the subtype relationship, use the boolean isAssignableFrom(Class<?> cls) method in Class . This will help catch NullPointerException .
// is it possible to B b = new A()
   Class<?> aClass = CharSequence.class;
   Class<?> bClass = String.class;
   bClass.isAssignableFrom(aClass());

   // works for arrays
   CharSequence[].class.isAssignableFrom(String[].class); // true
   Integer[].class.isAssignableFrom(String[].class); //false

Pattern Matching (Java 14)

if(a instanceof B b) {
       // b is casted
       b.toString();
   }

Special types

// Enums
    enum Color { WHITE, GRAY, BLACK }

    Color.class.isEnum(); // Enum.class.isAssignableFrom(Color.class);
    Color.WHITE instanceof Enum; // true

    // Arrays
    String[].class.isArray();
    // get the type of the variables in an array (null if obj is not an array)
    Class<?> componentType = obj.getComponentType();

    // Primitives
    int.class.isPrimitive();

Java.io - I/O Operations in Java

Source: Medium The content of this article is about I/O operations in Java. Coffee break #169.  Comparison of types.  Java.io - I/O Operations in Java - 2In Android and Java application development, input/output (Java I/O) is one of the topics that is often used, but for some reason is rarely mentioned. However, its scope of application is wide: for example, we perform I/O operations when converting a bitmap image to JPEG format or while reading/writing a regular file. The Java package java.io has all the necessary classes required to perform I/O operations. These operations are performed using threads. In turn, threads help perform read or write operations. For example, writing a message to a file.

Types of streams

There are two types of threads in Java:
  1. Byte Stream (byte stream)
  2. Character Stream

Byte stream

A Byte Stream is used to read and write one byte of data. It includes the Java InputStream and OutputStream classes . InputStream helps to read data and OutputStream helps to write data to a target (possibly a file).

Character stream

Character Stream is used to read and write one character of data. It includes the Reader and Writer Java classes . To understand Reader and Writer , you must understand derived classes such as InputStreamReader , FileReader , OutputStreamWriter , FileWriter and others.

InputStream and OutputStream

InputStream is used to read data from a source (possibly a file). It's not useful on its own, but it has several derived classes such as FileInputStream , ByteArrayInputStream , and ObjectInputStream . OutputStream is used to write data to a target (possibly a file). Its derived classes are FileOutputStream , ByteArrayOutputStream , and ObjectOutputStream .
class InputOutput {

    data class Car(val name: String): java.io.Serializable

    fun fileStream() {
        //Create FileOutputStream that used for writing to file
        val outputStream = FileOutputStream("kotlin.txt")

        //write to output stream
        outputStream.write(1) //write a int
        outputStream.write("hello".toByteArray()) //write a string as byte array

        //Create FileInputStream that used for reading from file
        val inputStream = FileInputStream("kotlin.txt")

        //reading single first byte from input stream
        //output - 1
        println(inputStream.read())

        //reading string from input stream
        //output - hello
        val msg = String(inputStream.readBytes())
        println(msg)

        //close
        outputStream.close()
        inputStream.close()
    }

    fun byteArrayStream() {
        //Create ByteArrayOutputStream
        val outputStream = ByteArrayOutputStream()

        //write to output stream
        outputStream.write(1)
        outputStream.write("hello".toByteArray())

        //Create ByteArrayInputStream
        val readByteArray = outputStream.toByteArray()
        val inputStream = ByteArrayInputStream(readByteArray)

        //Reading a single byte from input stream
        //output - 1
        println(inputStream.read())

        //Reading string from input stream
        //output - hello
        val msg = String(inputStream.readBytes())
        println(msg)

        //close
        outputStream.close()
        inputStream.close()
    }

    fun objectStream() {
        //custom object
        val car = Car(name = "BMW")

        //Create ObjectOutputStream
        val fileOutputStream = FileOutputStream("kotlin.txt")
        val objOutputStream = ObjectOutputStream(fileOutputStream)

        //writing to output stream
        objOutputStream.writeObject(car)

        //Create ObjectInputStream
        val fileInputStream = FileInputStream("kotlin.txt")
        val objInputStream = ObjectInputStream(fileInputStream)

        //Reading from input stream
        val carObject = objInputStream.readObject() as Car
        println(carObject.name) //output - BMW

        //close
        fileOutputStream.close()
        objOutputStream.close()

        fileInputStream.close()
        objInputStream.close()
    }

    fun bufferStream() {
        //Buffer - Buffer is used for storing stream of data in Java I/O
        //BufferStream is faster way to write and read bytes in streams.

        //Create BufferOutputStream
        val fileOutputStream = FileOutputStream("kotlin.txt")
        val outputStream = BufferedOutputStream(fileOutputStream)

        //Write to output stream
        outputStream.write("hello".toByteArray())

        //flush() - Sending the data from BufferedOutputStream to main stream.
        //This is required to push changes to main stream.
        outputStream.flush()

        //Create BufferInputStream
        val fileInputStream = FileInputStream("kotlin.txt")
        val inputStream = BufferedInputStream(fileInputStream)

        //Reading from input stream
        val msg = String(inputStream.readBytes())
        println(msg)

        //close
        fileOutputStream.close()
        fileInputStream.close()
    }
}
Apart from the above streams, we also have DataInputStream and DataOutputStream . They do the same work as other threads. The difference is that DataInput / OutputStream is mainly used for reading/writing primitive types, while ObjectInput / OutputStream is mainly used for objects and so on.

Readers and Writers

In Java I/O, if we read/write data to streams, we must convert them to bytes first. Only then can we read or write them to streams. InputStreamReader and OutputStreamWriter do this automatically.
class ReaderWriter {
    fun readerWriter() {
        //StreamReader or Writer:
        //It reads bytes and decodes them into characters using a specified charset.

        //Create OutputStreamWriter
        val outputStream = FileOutputStream("kotlin.txt")
        val writer = OutputStreamWriter(outputStream)

        //write to output stream
        writer.write("Hello Kotlin")
        writer.flush()

        //Create InputStreamReader
        val inputStream = FileInputStream("kotlin.txt")
        val reader = InputStreamReader(inputStream)

        //read from input stream
        //output - Hello Kotlin
        println(reader.readText())
    }
}

Parallel read and write

Sometimes we need multithreading support in Streams. Simply put, we want to read and write to streams from separate threads. For this we need to use PipedInput / OutputStream .
fun pipedStream() {
       //Create PipedInput/OutputStream for parallel read/writes
       val inputStream = PipedInputStream()
       val outputStream = PipedOutputStream()

       //make a connection
       inputStream.connect(outputStream)

       //write from separate thread
       val writeThread = object : Thread() {
           override fun run() {
               try {
                   for (i in 0..100) {
                       outputStream.write(i)
                       println("Write : $i")
                       sleep(100)
                   }
               } catch (e: Exception) {
                   e.printStackTrace()
               }
           }
       }

       //read from another thread
       val readThread = object : Thread() {
           override fun run() {
               try {
                   for (i in 0..100) {
                       println("Read : ${inputStream.read()}")
                   }
               } catch (e: Exception) {
                   e.printStackTrace()
               }
           }
       }

       //start
       writeThread.start()
       readThread.start()
   }
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION