1: Now I want to ask why writer use int c? even we are reading characters.

FileInputStream.read() returns one byte of data as an int. This works because a byte can be represented as an int without loss of precision. See this answer to understand why int is returned instead of byte.

2: The second why use -1 in while condition?

When the end of file is reached, -1 is returned.

3: How out.write(c); method convert int to again characters? that provide same output in outagain.txt file

FileOutputStream.write() takes a byte parameter as an int. Since an int spans over more values than a byte, the 24 high-order bits of the given int are ignored, making it a byte-compatible value: an int in Java is always 32 bits. By removing the 24 high-order bits, you're down to a 8 bits value, i.e. a byte.

I suggest you read carefully the Javadocs for each of those method. As reference, they answer all of your questions:

read:

Reads the next byte of data from the input stream. The value byte is returned as an int in the range 0 to 255. If no byte is available because the end of the stream has been reached, the value -1 is returned. This method blocks until input data is available, the end of the stream is detected, or an exception is thrown.

write:

Writes the specified byte to this output stream. The general contract for write is that one byte is written to the output stream. The byte to be written is the eight low-order bits of the argument b. The 24 high-order bits of b are ignored.

Answer from Tunaki on Stack Overflow
๐ŸŒ
Medium
medium.com โ€บ javarevisited โ€บ fileinputstream-and-fileoutputstream-in-java-a-guide-to-reading-and-writing-files-f46cb8a648a3
FileInputStream and FileOutputStream in Java: A Guide to Reading and Writing Files | by WhatInDev | Javarevisited | Medium
December 21, 2024 - ... Lack of Character Encoding Handling: When reading a text file, it is important to consider the fileโ€™s character encoding (e.g., UTF-8, ASCII, etc.). FileInputStream does not provide any built-in mechanism to handle different encodings.
๐ŸŒ
Codespindle
codespindle.com โ€บ Java โ€บ Java_fileInputStream_fileoutputstream.html
FileInputStream and FileOutputStream in Java
FileInputStream is used to read data from a file, one byte at a time.To create a FileInputStream object, you must pass the path to the file you want to read as a constructor argument. FileOutputStream is used to write data to a file, one byte at a time. It can be used to write any type of file, ...
Discussions

7. What are FileInputStream and FileOutputStream classes?
On Studocu you find all the lecture notes, summaries and study guides you need to pass your exams with better grades. More on studocu.com
๐ŸŒ studocu.com
1
June 4, 2024
Java FileInputStream FileOutputStream difference in the run - Stack Overflow
Could someone tell me why the 1. run is wrong? (The return code is 0, but the file written is only half of the original one. Thanks in advance! public class FileCopyFisFos { public static void... More on stackoverflow.com
๐ŸŒ stackoverflow.com
What is difference between FileOutputStream and ObjectOutputStream?
ObjectOutputStream is used to serialize objects . A FileOutputStream is a way to write to a file. In Java you often wrap streams with a specific purpose so basically assemble something that does what you want. You can also for example use a ObjectOutputStream to write objects to a network stream. This is called the decorator pattern. More on reddit.com
๐ŸŒ r/learnjava
6
1
May 28, 2021
java - What is InputStream & Output Stream? Why and when do we use them? - Stack Overflow
Someone explain to me what InputStream and OutputStream are? I am confused about the use cases for both InputStream and OutputStream. If you could also include a snippet of code to go along with ... More on stackoverflow.com
๐ŸŒ stackoverflow.com
Top answer
1 of 2
6

1: Now I want to ask why writer use int c? even we are reading characters.

FileInputStream.read() returns one byte of data as an int. This works because a byte can be represented as an int without loss of precision. See this answer to understand why int is returned instead of byte.

2: The second why use -1 in while condition?

When the end of file is reached, -1 is returned.

3: How out.write(c); method convert int to again characters? that provide same output in outagain.txt file

FileOutputStream.write() takes a byte parameter as an int. Since an int spans over more values than a byte, the 24 high-order bits of the given int are ignored, making it a byte-compatible value: an int in Java is always 32 bits. By removing the 24 high-order bits, you're down to a 8 bits value, i.e. a byte.

I suggest you read carefully the Javadocs for each of those method. As reference, they answer all of your questions:

read:

Reads the next byte of data from the input stream. The value byte is returned as an int in the range 0 to 255. If no byte is available because the end of the stream has been reached, the value -1 is returned. This method blocks until input data is available, the end of the stream is detected, or an exception is thrown.

write:

Writes the specified byte to this output stream. The general contract for write is that one byte is written to the output stream. The byte to be written is the eight low-order bits of the argument b. The 24 high-order bits of b are ignored.

2 of 2
1

Just read the docs.

here is the read method docs http://docs.oracle.com/javase/7/docs/api/java/io/FileInputStream.html#read()

public int read() throws IOException Reads a byte of data from this input stream. This method blocks if no input is yet available.

Specified by: read in class InputStream

Returns: the next byte of data, or -1 if the end of the file is reached.

That int is a your next set of bytes data. Now , here are the answers.

1) When you assign a char to an int, it denotes it's ascii number to the int.

If you are interested, here us the list of chars and their ascii codes https://www.cs.cmu.edu/~pattis/15-1XX/common/handouts/ascii.html

2)-1 if the end of the file is reached. So that's a check to data exists or not.

3)When you send an ascii code to print writer, it's prints that corresponding char to the file.

๐ŸŒ
Coding Shuttle
codingshuttle.com โ€บ home โ€บ handbooks โ€บ java programming handbook โ€บ fileinputstream and fileoutputstream
FileInputStream and FileOutputStream | Coding Shuttle
April 9, 2025 - These classes allow us to read from and write to files in Java. FileInputStream is used to read raw byte data from a file. FileOutputStream is used to write raw byte data to a file.
๐ŸŒ
CodeGym
codegym.cc โ€บ java blog โ€บ java io & nio โ€บ input/output in java. fileinputstream, fileoutputstream, ...
Input/output in Java. FileInputStream, FileOutputStream, and BufferedInputStream classes
October 11, 2023 - There was a time when I spent hours ... forget to use the close() method to free resources. The FileInputStream has the opposite purpose โ€” reading bytes from a file. Just as FileOutputStream inherits OutputStream, this class ...
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ java โ€บ difference-between-inputstream-and-outputstream-in-java
Difference Between InputStream and OutputStream in Java - GeeksforGeeks
January 28, 2021 - // Imported to use inbuilt methods import java.io.FileOutputStream; // Main class public class OutputStreamExample { public static void main(String args[]) { // Writing in file gfg.txt try { FileOutputStream fileOut = new FileOutputStream("gfg.txt"); String s = "GeeksforGeeks"; // converting string into byte array byte b[] = s.getBytes(); fileOut.write(b); fileOut.close(); System.out.println( "file is successfully updated!!"); } catch (Exception e) { System.out.println(e); } } }
๐ŸŒ
CodeJava
codejava.net โ€บ java-se โ€บ file-io โ€บ java-io-fileinputstream-and-fileoutputstream-examples
Java File IO FileInputStream and FileOutputStream Examples
void close(): Closes this file output stream and releases any system resources associated with the stream.Almost methods throw IOException so remember to handle or declare to throw it in your code.Now, letโ€™s see various code examples demonstrating the usages of the FileInputStream and FileOutputStream classes. ... import java.io.*; /** * This program demonstrates how to copy a file using the * FileInputStream and FileOutputStream classes with a * byte array as a buffer.
Find elsewhere
๐ŸŒ
W3Schools Blog
w3schools.blog โ€บ home โ€บ fileinputstream and fileoutputstream in java
FileInputStream and FileOutputStream in java - w3schools.blog
August 30, 2014 - FileInputStream fis = new ... = new IOTest(); //method call. obj.readFile(); } } Hello World. Download this example. FileOutputStream is used to create a file and write data into it....
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ java โ€บ java-io-input-output-in-java-with-examples
Input/Output in Java with Examples - GeeksforGeeks
import java.io.*; public class Geeks { public static void main( String[] args) throws IOException { FileInputStream sourceStream = null; FileOutputStream targetStream = null; try { sourceStream = new FileInputStream("sourcefile.txt"); targetStream = new FileOutputStream("targetfile.txt"); // Reading source file and writing content to target file byte by byte int temp; while (( temp = sourceStream.read()) != -1) targetStream.write((byte)temp); } finally { if (sourceStream != null) sourceStream.close(); if (targetStream != null) targetStream.close(); } } }
Published ย  December 10, 2025
๐ŸŒ
TutorialsPoint
tutorialspoint.com โ€บ what-is-the-use-of-fileinputstream-and-fileoutputstream-in-classes-in-java
Java - DataOutputStream Class
FileOutputStream creates a file (booleanData.dat). DataOutputStream.writeBoolean(true) writes 1 (one byte). DataOutputStream.writeBoolean(false) writes 0 (one byte). DataOutputStream.writeBoolean(true) writes 1 (one byte). The file now contains { 1, 0, 1 }. FileInputStream opens the file.
๐ŸŒ
Studocu
studocu.com โ€บ tribhuvan vishwavidalaya โ€บ java programming โ€บ question
[Solved] 7 What are FileInputStream and FileOutputStream classes - Java Programming (CSc 409) - Studocu
June 4, 2024 - The FileInputStream and FileOutputStream classes in Java are used for reading and writing data from and to files, respectively.
๐ŸŒ
TutorialsPoint
tutorialspoint.com โ€บ difference-between-inputstream-and-outputstream-in-java
Difference Between InputStream and OutputStream in Java
FileOutputStream fileOut = new FileOutputStream (" ARBRDD . txt " ) ; File is successfully updated today ! ! Using the FileInputStream and FileOutputStream Functions.
Top answer
1 of 2
3

FileInputStream 's read() method follows this logic:

Reads a byte of data from this input stream. This method blocks if no input is yet available.

So assigning the value of its return to a variable, such as:

while((len = fis.read())!= -1) 

Is avoiding the byte of data just read from the stream to be forgotten, as every read() call will be assigned to your len variable.


Instead, this code bypasses one of every two bytes from the stream, as the read() executed in the while condition is never assigned to a variable. So the stream advances without half of the bytes being read (assigned to len):

while (fis.read() != -1) {      // reads a byte of data (but not saved)
   int len = fis.read();        // next byte of data saved
   fos.write(len);              // possible -1 written here    
}
2 of 2
2

@aran and others already pointed out the solution to your problem.

However there are more sides to this, so I extended your example:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileCopyFisFos {

    public static void main(final String[] args) throws IOException {
        final File src = new File("d:/Test1/OrigFile.MP4");
        final File sink = new File("d:/Test2/DestFile.mp4");

        {
            final long startMS = System.currentTimeMillis();
            final long bytesCopied = copyFileSimple(src, sink);
            System.out.println("Simple copy transferred " + bytesCopied + " bytes in " + (System.currentTimeMillis() - startMS) + "ms");
        }
        {
            final long startMS = System.currentTimeMillis();
            final long bytesCopied = copyFileSimpleFaster(src, sink);
            System.out.println("Simple+Fast copy transferred " + bytesCopied + " bytes in " + (System.currentTimeMillis() - startMS) + "ms");
        }
        {
            final long startMS = System.currentTimeMillis();
            final long bytesCopied = copyFileFast(src, sink);
            System.out.println("Fast copy transferred " + bytesCopied + " bytes in " + (System.currentTimeMillis() - startMS) + "ms");
        }

        System.out.println("Test completed.");
    }

    static public long copyFileSimple(final File pSourceFile, final File pSinkFile) throws IOException {
        try (
                final FileInputStream fis = new FileInputStream(pSourceFile);
                final FileOutputStream fos = new FileOutputStream(pSinkFile);) {

            long totalBytesTransferred = 0;
            while (true) {
                final int readByte = fis.read();
                if (readByte < 0) break;

                fos.write(readByte);
                ++totalBytesTransferred;
            }
            return totalBytesTransferred;
        }
    }

    static public long copyFileSimpleFaster(final File pSourceFile, final File pSinkFile) throws IOException {
        try (
                final FileInputStream fis = new FileInputStream(pSourceFile);
                final FileOutputStream fos = new FileOutputStream(pSinkFile);
                BufferedInputStream bis = new BufferedInputStream(fis);
                BufferedOutputStream bos = new BufferedOutputStream(fos);) {

            long totalBytesTransferred = 0;
            while (true) {
                final int readByte = bis.read();
                if (readByte < 0) break;

                bos.write(readByte);
                ++totalBytesTransferred;
            }
            return totalBytesTransferred;
        }
    }

    static public long copyFileFast(final File pSourceFile, final File pSinkFile) throws IOException {
        try (
                final FileInputStream fis = new FileInputStream(pSourceFile);
                final FileOutputStream fos = new FileOutputStream(pSinkFile);) {

            long totalBytesTransferred = 0;
            final byte[] buffer = new byte[20 * 1024];
            while (true) {
                final int bytesRead = fis.read(buffer);
                if (bytesRead < 0) break;

                fos.write(buffer, 0, bytesRead);
                totalBytesTransferred += bytesRead;
            }
            return totalBytesTransferred;
        }
    }

}

The hints that come along with that code:

  • There is the java.nio package that usualy does those things a lot faster and in less code.
  • Copying single bytes is 1'000-40'000 times slower that bulk copy.
  • Using try/resource/catch is the best way to avoid problems with reserved/locked resources like files etc.
  • If you solve something that is quite commonplace, I suggest you put it in a utility class of your own or even your own library.
  • There are helper classes like BufferedInputStream and BufferedOutputStream that take care of efficiency greatly; see example copyFileSimpleFaster().
  • But as usual, it is the quality of the concept that has the most impact on the implementation; see example copyFileFast().
  • There are even more advanced concepts (similar to java.nio), that take into account concepts like OS caching behaviour etc, which will give performance another kick.

Check my outputs, or run it on your own, to see the differences in performance:

Simple copy transferred 1608799 bytes in 12709ms
Simple+Fast copy transferred 1608799 bytes in 51ms
Fast copy transferred 1608799 bytes in 4ms
Test completed.
๐ŸŒ
Tutorialspoint
tutorialspoint.com โ€บ java โ€บ java_files_io.htm
Java - Files and I/O
Though internally FileReader uses FileInputStream and FileWriter uses FileOutputStream but here the major difference is that FileReader reads two bytes at a time and FileWriter writes two bytes at a time.
Top answer
1 of 9
247

The goal of InputStream and OutputStream is to abstract different ways to input and output: whether the stream is a file, a web page, or the screen shouldn't matter. All that matters is that you receive information from the stream (or send information into that stream.)

InputStream is used for many things that you read from.

OutputStream is used for many things that you write to.

Here's some sample code. It assumes the InputStream instr and OutputStream osstr have already been created:

int i;

while ((i = instr.read()) != -1) {
    osstr.write(i);
}

instr.close();
osstr.close();
2 of 9
97

InputStream is used for reading, OutputStream for writing. They are connected as decorators to one another such that you can read/write all different types of data from all different types of sources.

For example, you can write primitive data to a file:

File file = new File("C:/text.bin");
file.createNewFile();
DataOutputStream stream = new DataOutputStream(new FileOutputStream(file));
stream.writeBoolean(true);
stream.writeInt(1234);
stream.close();

To read the written contents:

File file = new File("C:/text.bin");
DataInputStream stream = new DataInputStream(new FileInputStream(file));
boolean isTrue = stream.readBoolean();
int value = stream.readInt();
stream.close();
System.out.printlin(isTrue + " " + value);

You can use other types of streams to enhance the reading/writing. For example, you can introduce a buffer for efficiency:

DataInputStream stream = new DataInputStream(
    new BufferedInputStream(new FileInputStream(file)));

You can write other data such as objects:

MyClass myObject = new MyClass(); // MyClass have to implement Serializable
ObjectOutputStream stream = new ObjectOutputStream(
    new FileOutputStream("C:/text.obj"));
stream.writeObject(myObject);
stream.close();

You can read from other different input sources:

byte[] test = new byte[] {0, 0, 1, 0, 0, 0, 1, 1, 8, 9};
DataInputStream stream = new DataInputStream(new ByteArrayInputStream(test));
int value0 = stream.readInt();
int value1 = stream.readInt();
byte value2 = stream.readByte();
byte value3 = stream.readByte();
stream.close();
System.out.println(value0 + " " + value1 + " " + value2 + " " + value3);

For most input streams there is an output stream, also. You can define your own streams to reading/writing special things and there are complex streams for reading complex things (for example there are Streams for reading/writing ZIP format).

๐ŸŒ
Scaler
scaler.com โ€บ home โ€บ topics โ€บ fileoutputstream in java
FileOutputStream in Java| Scaler Topics
January 11, 2024 - FileInputstream class in Java is a subclass of outputstream and is used to write primitive values in a file. Know more about classes in java with Scaler Topics.
๐ŸŒ
W3Schools
w3schools.com โ€บ java โ€บ java_io_streams.asp
Java I/O Streams (Input/Output Streams)
Byte Streams Work with raw binary data (like images, audio, and PDF files). Examples: FileInputStream, FileOutputStream.
๐ŸŒ
Java By Kiran
thekiranacademy.com โ€บ home โ€บ java โ€บ what is i/o stream? โ€บ input output stream
JBK Tutorials | Input and Output Streams in Java
November 22, 2019 - Java uses OutputStream and InputStream for Writing data to destination and Reading data from source, respectively. OutputStream and InputStream are abstract classes. So we can't use them directly ยท Output Stream class: OutputStream class is an abstract class. It is the superclass of all classes representing an output stream of bytes. Like FileOutputStream, ObjectOutputStream, etc.