Skip to content

Latest commit

 

History

History
325 lines (223 loc) · 22.8 KB

File metadata and controls

325 lines (223 loc) · 22.8 KB

Interview Questions

Input/Output Streams in Java

back to table of contents

What is the difference between IO and NIO?

  • Java IO (input-output) is stream-oriented, while Java NIO (new/non-blocking IO) is buffer-oriented. Stream-oriented input/output implies reading/writing one or more bytes at a time from/to a stream sequentially. This data is not cached anywhere. Thus, it is impossible to move arbitrarily forward or backward through the data stream. In Java NIO, data is first read into a buffer, which provides more flexibility when processing data.
  • Input/output streams in Java IO are blocking. This means that when a read() or write() method of any class from the java.io.* package is called in a thread, blocking occurs until the data is read or written. The thread cannot do anything else at that moment. The non-blocking mode of Java NIO allows requesting read data from a channel and receiving only what is currently available, or nothing at all if no data is available yet. Instead of remaining blocked until data becomes available for reading, the thread can do something else. The same applies to non-blocking output. A thread can request writing some data to a channel without waiting for it to be fully written.
  • Java NIO has selectors that allow a single thread to monitor multiple input channels. That is, it is possible to register multiple channels with a selector, and then use one thread to service channels that have data available for processing, or to select channels ready for writing.

back to table of contents

What features of NIO do you know?

  • Channels and selectors: NIO supports various types of channels. A channel is an abstraction of lower-level file system objects (such as memory-mapped files and file locks), which allows data to be transferred at higher speeds. Channels are non-blocking, so Java also provides tools such as a selector, which allows selecting a ready channel for data transfer, and a socket, which is a tool for blocking.
  • Buffers: there is buffering for all primitive type wrapper classes (except Boolean). An abstract Buffer class was introduced, providing operations such as clear, flip, mark, etc. Its subclasses provide methods for getting and setting data.
  • Encodings: encoders and decoders were introduced for mapping bytes and Unicode characters.

back to table of contents

What are "channels"?

Channels are logical (not physical) portals, abstractions of lower-level file system objects (such as memory-mapped files and file locks), through which data input/output is performed, while buffers are the sources or receivers of this transferred data. When organizing output, the data you want to send is placed in a buffer, which is then passed to the channel. On input, data from the channel is placed into a buffer you provide in advance.

Channels resemble pipelines through which data is efficiently transported between byte buffers and entities on the other side of the channels. Channels are gateways that provide access to the operating system's I/O services with minimal overhead, while buffers are the internal endpoints of these gateways, used for sending and receiving data.

back to table of contents

What types of input/output streams exist?

Name the main classes of input/output streams

There are two types of input/output streams:

  • byte streamsjava.io.InputStream, java.io.OutputStream;
  • character streamsjava.io.Reader, java.io.Writer.

back to table of contents

In which packages are the input/output stream classes located?

java.io, java.nio. For working with compressed data streams, classes from the java.util.zip package are used.

back to table of contents

What subclasses of the InputStream class do you know, and what are they used for?

  • InputStream — an abstract class describing an input stream;
  • BufferedInputStream — a buffered input stream;
  • ByteArrayInputStream allows using a memory buffer (byte array) as a data source for the input stream;
  • DataInputStream — an input stream for byte data, including methods for reading standard Java data types;
  • FileInputStream — an input stream for reading information from a file;
  • FilterInputStream — an abstract class providing an interface for decorator classes that add useful properties to existing streams;
  • ObjectInputStream — an input stream for objects;
  • StringBufferInputStream converts a string (String) into an InputStream data input stream;
  • PipedInputStream implements the concept of an input pipe;
  • PushbackInputStream — a type of buffering that provides reading a byte with the ability to return it back to the stream, allowing you to "peek" into the input stream and see what will come next without extracting the information.
  • SequenceInputStream is used to merge two or more InputStream streams into a single one.

back to table of contents

What is PushbackInputStream used for?

A type of buffering that provides reading a byte with the ability to return it back to the stream. The PushbackInputStream class provides a mechanism to "peek" into the input stream and see what will come next without extracting the information.

The class has an additional method unread().

back to table of contents

What is SequenceInputStream used for?

The SequenceInputStream class allows merging several instances of the InputStream class together. The constructor accepts either a pair of InputStream objects or an Enumeration interface as an argument.

During operation, the class performs read requests from the first InputStream object until the end, and then switches to the second. When using the Enumeration interface, processing continues across all InputStream objects. Upon reaching the end, the associated stream is closed. Closing the stream created by the SequenceInputStream object causes all open streams to be closed.

back to table of contents

Which class allows reading data from an input byte stream in the format of primitive data types?

The DataInputStream class represents an input stream designed for reading primitive data types such as int, double, etc. Each primitive type has its own method for reading:

  • boolean readBoolean(): reads a single-byte boolean value from the stream
  • byte readByte(): reads 1 byte from the stream
  • char readChar(): reads a char value from the stream
  • double readDouble(): reads an 8-byte double value from the stream
  • float readFloat(): reads a 4-byte float value from the stream
  • int readInt(): reads an int integer value from the stream
  • long readLong(): reads a long value from the stream
  • short readShort(): reads a short value
  • String readUTF(): reads a UTF-8 encoded string from the stream

back to table of contents

What subclasses of the OutputStream class do you know, and what are they used for?

  • OutputStream — an abstract class defining byte stream output;
  • BufferedOutputStream — a buffered output stream;
  • ByteArrayOutputStream — all data sent to this stream is placed in a pre-created buffer;
  • DataOutputStream — a byte output stream including methods for writing standard Java data types;
  • FileOutputStream — writing data to a file on a physical medium;
  • FilterOutputStream — an abstract class providing an interface for decorator classes that add useful properties to existing streams;
  • ObjectOutputStream — an output stream for writing objects;
  • PipedOutputStream implements the concept of an output pipe;
  • PrintStream — an output stream including print() and println() methods.

back to table of contents

What subclasses of the Reader class do you know, and what are they used for?

  • Reader — an abstract class describing character input;
  • BufferedReader — a buffered character input stream;
  • CharArrayReader — an input stream that reads from a character array;
  • FileReader — an input stream that reads a file;
  • FilterReader — an abstract class providing an interface for decorator classes;
  • InputStreamReader — an input stream that translates bytes into characters;
  • LineNumberReader — an input stream that counts lines;
  • PipedReader — an input pipe;
  • PushbackReader — an input stream that allows returning characters back to the stream;
  • StringReader — an input stream that reads from a string.

back to table of contents

What subclasses of the Writer class do you know, and what are they used for?

  • Writer — an abstract class describing character output;
  • BufferedWriter — a buffered character output stream;
  • CharArrayWriter — an output stream that writes to a character array;
  • FileWriter — an output stream that writes to a file;
  • FilterWriter — an abstract class providing an interface for decorator classes;
  • OutputStreamWriter — an output stream that translates bytes into characters;
  • PipedWriter — an output pipe;
  • PrintWriter — a character output stream including print() and println() methods;
  • StringWriter — an output stream that writes to a string;

back to table of contents

What is the difference between PrintWriter and PrintStream?

First of all, the PrintWriter class uses an improved method of handling Unicode characters and a different output buffering mechanism: in the PrintStream class, the output buffer was flushed every time the print() or println() method was called, whereas with the PrintWriter class, it is possible to opt out of automatic buffer flushing, performing it explicitly using the flush() method.

Additionally, the methods of the PrintWriter class never throw exceptions. To check for errors, you must explicitly call the checkError() method.

back to table of contents

What are the differences and similarities between InputStream, OutputStream, Reader, and Writer?

  • InputStream and its descendants — a set of classes for receiving byte data from various sources;
  • OutputStream and its descendants — a set of classes defining byte stream output;
  • Reader and its descendants define Unicode character stream input;
  • Writer and its descendants define Unicode character stream output.

back to table of contents

Which classes allow converting byte streams to character streams and vice versa?

  • OutputStreamWriter — a "bridge" between the OutputStream class and the Writer class. Characters written to the stream are converted to bytes.
  • InputStreamReader — the analogous class for reading. Using methods of the Reader class, bytes are read from the InputStream stream and then converted to characters.

back to table of contents

Which classes allow speeding up reading/writing through the use of a buffer?

  • BufferedInputStream(InputStream in) / BufferedInputStream(InputStream in, int size),
  • BufferedOutputStream(OutputStream out) / BufferedOutputStream(OutputStream out, int size),
  • BufferedReader(Reader r) / BufferedReader(Reader in, int sz),
  • BufferedWriter(Writer out) / BufferedWriter(Writer out, int sz)

back to table of contents

Which class is designed for working with file system elements?

File works directly with files and directories. This class allows creating new elements and obtaining information about existing ones: size, access rights, creation time and date, path to the parent directory.

back to table of contents

What methods of the File class do you know?

The most commonly used methods of the File class:

  • boolean createNewFile(): attempts to create a new file;
  • boolean delete(): attempts to delete a directory or file;
  • boolean mkdir(): attempts to create a new directory;
  • boolean renameTo(File dest): attempts to rename a file or directory;
  • boolean exists(): checks whether the file or directory exists;
  • String getAbsolutePath(): returns the absolute path for the path passed to the object's constructor;
  • String getName(): returns the short name of the file or directory;
  • String getParent(): returns the name of the parent directory;
  • boolean isDirectory(): returns true if a directory is located at the specified path;
  • boolean isFile(): returns true if a file is located at the specified path;
  • boolean isHidden(): returns true if the directory or file is hidden;
  • long length(): returns the file size in bytes;
  • long lastModified(): returns the time of the last modification of the file or directory;
  • String[] list(): returns an array of files and subdirectories located in a specific directory;
  • File[] listFiles(): returns an array of files and subdirectories located in a specific directory.

back to table of contents

What do you know about the FileFilter interface?

The FileFilter interface is used to check whether a File object meets some condition. This interface contains a single method boolean accept(File pathName). This method must be overridden and implemented. For example:

public boolean accept(final File file) {
    return file.isExists() && file.isDirectory();
}

back to table of contents

How to select all elements of a specific directory by criteria (for example, with a specific extension)?

The File.listFiles() method returns an array of File objects contained in the directory. The method can accept as a parameter an object of a class implementing FileFilter. This allows including in the list only those elements for which the accept method returns true (the criterion can be the file name length or its extension).

back to table of contents

What do you know about RandomAccessFile?

The java.io.RandomAccessFile class provides reading and writing data at an arbitrary location in a file. It is not part of the InputStream or OutputStream hierarchy. It is a completely separate class with its own (mostly native) methods. The explanation for this may be that RandomAccessFile has largely different behavior compared to other I/O classes, as it allows moving forward and backward within a file.

RandomAccessFile has such specific methods as:

  • getFilePointer() for determining the current location in the file;
  • seek() for moving to a new position in the file;
  • length() for finding out the file size;
  • setLength() for setting the file size;
  • skipBytes() for attempting to skip a specified number of bytes;
  • getChannel() for working with the unique file channel associated with the given file;
  • methods for performing normal and formatted output from a file (read(), readInt(), readLine(), readUTF(), etc.);
  • methods for normal or formatted writing to a random-access file (write(), writeBoolean(), writeByte(), etc.).

It should also be noted that the RandomAccessFile constructors require a second argument specifying the desired file access mode — read-only ("r"), read and write ("rw"), or other variants.

back to table of contents

What file access modes does RandomAccessFile have?

  • "r" opens the file for reading only. Running any data write methods will result in an IOException being thrown.
  • "rw" opens the file for reading and writing. If the file has not been created yet, an attempt is made to create it.
  • "rws" opens the file for reading and writing similar to "rw", but requires the system to synchronously write any changes to the file's content or metadata to the physical device with each modification.
  • "rwd" opens the file for reading and writing similar to "rws", but requires the system to synchronously write changes to the physical device only when the file's content changes. If metadata changes, synchronous writing is not required.

back to table of contents

Which classes support reading and writing streams in a compressed format?

  • DeflaterOutputStream — data compression in deflate format.
  • Deflater — data compression in ZLIB format.
  • ZipOutputStream — a descendant of DeflaterOutputStream for data compression in Zip format.
  • GZIPOutputStream — a descendant of DeflaterOutputStream for data compression in GZIP format.
  • InflaterInputStream — data decompression in deflate format.
  • Inflater — data decompression in ZLIB format.
  • ZipInputStream — a descendant of InflaterInputStream for data decompression in Zip format.
  • GZIPInputStream — a descendant of InflaterInputStream for data decompression in GZIP format.

back to table of contents

Is it possible to redirect standard input/output streams?

The System class allows you to redirect standard input, output, and error output streams using a simple call to a static method:

  • setIn(InputStream) — for input;
  • setOut(PrintStream) — for output;
  • setErr(PrintStream) — for error output.

back to table of contents

What character is used as a separator when specifying a path in the file system?

The separator character differs for different operating systems. For Windows it is \, for Linux it is /.

In Java, you can obtain the separator for the current operating system by accessing the static field File.separator.

back to table of contents

What is an "absolute path" and a "relative path"?

An absolute (full) path is a path that points to the same location in the file system regardless of the current working directory or other circumstances. A full path always starts from the root directory.

A relative path is a path relative to the current working directory of the user or the active application.

back to table of contents

What is a "symbolic link"?

A symbolic (symlink) (also "symlink", Symbolic link) is a special file in the file system that, instead of user data, contains a path to a file that should be opened when attempting to access this link (file). The target of a link can be any object: for example, another link, a file, a directory, or even a non-existent file (in the latter case, when attempting to open it, a message about the missing file should be displayed).

Symbolic links are used for more convenient organization of the file structure on a computer, because:

  • they allow a single file or directory to have multiple names and different attributes;
  • they are free from some limitations inherent to hard links (the latter work only within a single file system (one partition) and cannot point to directories).

back to table of contents

Interview Questions