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 - ASCII characters (with values from 0 to 127) are single-byte characters, so casting the byte to a char works fine in this case. If you're looking for a solution to handle different encodings, we will discuss that in our next article when we cover character-based streams. The java.io.FileOutputStream class is used for writing 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 ...
Discussions

file - How FileInputStream and FileOutputStream Works in Java? - Stack Overflow
They are not characters, they are bytes. Are you familiar with the Java API documentation? There is an explanation for every class and every method in the standard Java libraries, including those of FileInputStream and FileOutputStream. More on stackoverflow.com
๐ŸŒ stackoverflow.com
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
๐ŸŒ
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, ...
๐ŸŒ
W3Schools Blog
w3schools.blog โ€บ home โ€บ fileinputstream and fileoutputstream in java
FileInputStream and FileOutputStream in java - w3schools.blog
August 30, 2014 - Fileinputstream and Fileoutputstream in java: FileInputStream stream is used for reading data from the files.
๐ŸŒ
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.
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.

๐ŸŒ
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); } } }
Find elsewhere
๐ŸŒ
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.
๐ŸŒ
CodeJava
codejava.net โ€บ java-se โ€บ file-io โ€บ java-io-fileinputstream-and-fileoutputstream-examples
Java File IO FileInputStream and FileOutputStream Examples
[Master REST API Development and Java and Spring Boot] This Java File IO tutorial helps you understand and use the FileInputStream and FileOutputStream classes for manipulating binary files.In Java, FileInputStream and FileOutputStream are byte streams that read and write data in binary format, exactly 8-bit bytes.
๐ŸŒ
TutorialsPoint
tutorialspoint.com โ€บ what-is-the-use-of-fileinputstream-and-fileoutputstream-in-classes-in-java
Java - DataOutputStream Class
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.
๐ŸŒ
TutorialsPoint
tutorialspoint.com โ€บ difference-between-inputstream-and-outputstream-in-java
Difference Between InputStream and OutputStream in Java
InputStream and OutputStream both are the abstraction process which can be implemented to access the low level data sets as pointers . They are the signified APIs to specify a particular data sequence of an operation by following some individual step
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.
๐ŸŒ
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
๐ŸŒ
W3Schools
w3schools.com โ€บ java โ€บ java_io_streams.asp
Java I/O Streams (Input/Output Streams)
In Java, there is an important difference between working with the File class and working with I/O Streams (Input/Output Stream): The File class (from java.io) is used to get information about files and directories:
Top answer
1 of 2
1

The classes FSDataInputStream and FSDataOutputStream are classes in hadoop-common

FSDataInputStream

FSDataInputStream adds high performance APIs for reading data at specific offsets into byte arrays (PositionedReadable) or bytebuffers. these are used extensively in libraries reading files where the reads are not sequential, more random IO. parquet, orc etc. FileSystem implementations often provide highly efficient implementations of these. These apis are not relevant for simple file copy unless you really are trying for maximum performance, have opened the same source file to multiple streams and are fetching blocks in parallel across them. Distcp does things like this, which is why it can overload networks if you try hard.

full specification, including of PositionedReadable: fsdatainputstream

FSDataOutputStream

FSDataOutputStream doesn't add that much to the normal DataOutputStream; the most important interface is Syncable, whose hflush and hsync calls have specific guarantees about durability, as in "when they return, the data has been persisted to HDFS or the other filesystem, for hsync, all the way to disk". If you are implementing a database like HBase, you need these and those guarantees. If you aren't, you really don't. In recent hadoop releases, trying to use them when writing to S3 will simply log a warning message telling you to stop it. It's not a real file system, after all.

full specification, including of syncable: outputstream

copying files in spark at scale

IF you want to copy files efficiently in spark, open the source files and dest files with a buffer of a few MB, read into the buffer, then write it back. you can distribute this work across the cluster for better parallelism, as this example does: https://github.com/hortonworks-spark/cloud-integration/blob/master/spark-cloud-integration/src/main/scala/com/cloudera/spark/cloud/applications/CloudCp.scala

  1. If you just want to copy one or two files, just do it in a single process, maybe multithreaded.
  2. If you are really seeking performance against s3, take the list of files to copy, schedule the largest few files first so they don't hold you at the end, then randomize the rest of the list to avoid creating hotspots in the s3 bucket.
2 of 2
0

You can use either, it just depends on what you need.

They both are just stream implementations. Ultimately what you will be doing is taking and inputstream from one bucket and writing it to the outputstream of another.

The FileInputStream and FileOutputStream are concrete components that provide the functionality to read and write streams from a mapped file.

The FSDataInputStream and FSDataOutputStream are concrete decorators of an inputstream. Meaning the provide or decorate the inputstream with functionality, such as reading and writing primitives and providing buffered streams.

Which one to choose? Do you need a the decorations provided by FSDataOutputStream and FSDataInputStream? Is FileInputStream and FileOutputStream sufficient?

Personally, I would look to use Readers and Writers as demonstrated here:

How can I read an AWS S3 File with Java?

private final AmazonS3 amazonS3Client = AmazonS3ClientBuilder.standard().build();

private Collection<String> loadFileFromS3() {
    try (final S3Object s3Object = amazonS3Client.getObject(BUCKET_NAME,
                                                            FILE_NAME);
        final InputStreamReader streamReader = new InputStreamReader(s3Object.getObjectContent(), StandardCharsets.UTF_8);
        final BufferedReader reader = new BufferedReader(streamReader)) {
        return reader.lines().collect(Collectors.toSet());
    } catch (final IOException e) {
        log.error(e.getMessage(), e)
        return Collections.emptySet();
    }
}
๐ŸŒ
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.
๐ŸŒ
CloudBees
cloudbees.com โ€บ blog โ€บ fileinputstream-fileoutputstream-considered-harmful
FileInputStream / FileOutputStream Considered Harmful
March 24, 2017 - For example, Hadoop found "long GC pauses were devoted to process high number of final references" resulting from the creation of lots of FileInputStream instances. The solution (at least if you are using Java 7 or newer) is not too hard - apart from retraining your muscle memory - just switch to Files.newInputStream(...) and Files.newOutputStream(...)