Yes because you are writing bytes

out.write(((byte)temp[j]))

you need to write int which is 4 bytes. Not truncate the int to byte

out.write(temp[j])

Eventually this is not the way to write the image - this will reproduce the file so its ok for this application (just copy a file nothing more). But if you want to change the pixels and rewrite a new image you will need imageio (or some other mechanism) to write images.

--

OutputStreamWriter writes characters; why dont you use the equivalent:

FileOutputStream: you can write the bytes as you read them.

Answer from gpasch on Stack Overflow
🌐
Oracle
docs.oracle.com › javase › 7 › docs › api › java › io › FileInputStream.html
FileInputStream (Java Platform SE 7 )
FileInputStream is meant for reading streams of raw bytes such as image data. For reading streams of characters, consider using FileReader. ... File, FileDescriptor, FileOutputStream, Files.newInputStream(java.nio.file.Path, java.nio.file.OpenOption...)
🌐
Atechdaily
atechdaily.com › posts › Reading-and-Writing-Images-in-Java-using-File-streams
Reading and Writing Images in Java using File streams
March 20, 2020 - In this article, we will learn how to read and write image objects using Java. To read an image, first create a java.io.File object. Create a byte array. This array will store image data, byte by byte. The size of this byte array will be the length of input file. i.e, file.length(); Create a FileInputStream object which will take file as a parameter.
🌐
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 - The java.io.FileInputStream class is used for reading the contents of a file in Java. It provides methods to read byte data from a file, making it suitable for reading binary files such as images, audio files, and other non-textual data.
Top answer
1 of 3
3

The problem, as I can see it, is the mixing of the readers and streams..

Now, I tried using...

try (OutputStream output = new FileOutputStream(filepath);
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output))) {
    
    writer.write("Number: 176");
    writer.newLine();
    writer.write("Title: Elephant");
    writer.newLine();
    writer.write("Text: This image shows a cute elephant.");
    writer.newLine();

    writer.flush();

    ImageIO.write(image, "png", output);

    output.flush();
} catch (Exception exp) {
    exp.printStackTrace();
}

To write the file. The hope was that the input stream position would be updated and the content would be written to the end of the file...

And

String filepath = "myfile.txt";
BufferedImage image = null;
try (InputStream is = new FileInputStream(new File(filepath));
                BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
    
    String number = br.readLine();
    String title = br.readLine();
    String text = br.readLine();
    
    System.out.println(number);
    System.out.println(title);
    System.out.println(text);

    ImageInputStream iis = ImageIO.createImageInputStream(is);
    image = ImageIO.read(iis);
    ImageIO.write(image, "png", new File("test.png"));
} catch (Exception exp) {
    exp.printStackTrace();
}

To read it.

But this didn't seem to work. What "might" be happening is the file position isn't being updated to the correct position that we need it to read the image properly.

What I did instead was this...

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageInputStream;

public class ReadWriteImage {

    public static void main(String[] args) {
        try {
            writeTest();
            readTest();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public static void readTest() throws IOException {
        String filepath = "myfile.txt";
        BufferedImage image = null;
        try (InputStream is = new FileInputStream(new File(filepath))) {
        
            int lineCount = 0;
            StringBuilder sb = new StringBuilder(128);
        
            String number = null;
            String title = null;
            String text = null;
        
            int b = -1;
            while (lineCount < 3 && (b = is.read()) != -1) {
                if ((char)b == '\n') {
                    switch (lineCount) {
                        case 0:
                            number = sb.toString();
                            break;
                        case 1:
                            title = sb.toString();
                            break;
                        case 2:
                            text = sb.toString();
                            break;
                    }
                    sb.delete(0, sb.length());
                    lineCount++;
                } else {
                    sb.append((char)b);
                }
            }
        
            System.out.println(number);
            System.out.println(title);
            System.out.println(text);

            ImageInputStream iis = ImageIO.createImageInputStream(is);
            image = ImageIO.read(iis);
            ImageIO.write(image, "png", new File("test.png"));
        } catch (Exception exp) {
            exp.printStackTrace();
        }
    }

    public static void writeTest() throws IOException {
        String filepath = "myfile.txt";
        BufferedImage image = ImageIO.read(new File("/Users/swhitehead/Dropbox/MegaTokyo/thumnails/2005-09-29-3957_400.jpg"));

        try (FileOutputStream output = new FileOutputStream(filepath)) {
        
            output.write("Number: 176\n".getBytes());
            output.write("Title: Elephant\n".getBytes());
            output.write("Text: This image shows a cute elephant.\n".getBytes());

            ImageIO.write(image, "png", output);

            output.flush();
        } catch (Exception exp) {
            exp.printStackTrace();
        }

    }
}

Basically, I just used the OutputStream and InputStream directly...

Updated

The file contents starts with...

Number: 176
Title: Elephant
Text: This image shows a cute elephant.
âPNG

Welcome to 2021

So, the ordinal answer was made some time ago, the world has moved on. Unless you have a very specific need not to (ie transport speed/bandwidth restrictions), I would highly recommend making use of things like JSON and Base64 to send binary and text mixed together.

The main reason, it's actually much simpler to encode/decode and maintain. The original solution is rather difficult to add new content to, as both ends need to be able to support the changes, where as something like JSON can (if done properly) get away with adding and removing content. It's also easier to build much more complex parsing workflows, as you're not reliant on the "read/write" position of the stream.

This example makes use of the org.json library, but you can use what ever library you want.

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import org.json.JSONObject;

public class Main {

    public static void main(String[] args) throws IOException {
        new Main();
    }

    public Main() throws IOException {
        read(write());
    }

    public String write() throws IOException {
        BufferedImage image = ImageIO.read(getClass().getResource("/images/Background.png"));

        JSONObject jobj = new JSONObject();
        jobj.put("number", 176);
        jobj.put("title", "Elephant");
        jobj.put("text", "This image shows a cute elepant");

        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            ImageIO.write(image, "png", baos);
            baos.flush();
            byte[] encode = Base64.getEncoder().encode(baos.toByteArray());
            String text = new String(encode, StandardCharsets.UTF_8);
            jobj.put("image", text);
        }

        String text = jobj.toString();

        return text;
    }

    public void read(String jsonText) throws IOException {
        JSONObject jobj = new JSONObject(jsonText);
        System.out.println("Number = " + jobj.getInt("number"));
        System.out.println("Title = " + jobj.getString("title"));
        System.out.println("Text = " + jobj.getString("text"));

        String encodedImage = jobj.getString("image");
        byte[] imageBytes = Base64.getDecoder().decode(encodedImage.getBytes(StandardCharsets.UTF_8));
        try (ByteArrayInputStream bais = new ByteArrayInputStream(imageBytes)) {
            BufferedImage image = ImageIO.read(bais);

            JLabel label = new JLabel(new ImageIcon(image));
            label.setText("<html>Number = " + jobj.getInt("number") + "<br>Title = " + jobj.getString("title") + "<br>Text = " + jobj.getString("text"));

            JOptionPane.showMessageDialog(null, label);
        }
    }

}

What if I want to send 2 files?

Then use a JSONArray. org.json is reasonably powerful, see Introduction to JSON-Java for more details. The Google implementation (GSON?) also provides a lot of functionality which can be used to encode/decode json from/to POJOs, if that's your thing

2 of 3
0

Approach given your example:

This simple, if you only have 3 lines of text as listed in your example, then you can just read each line of Text when you detect the \n, when you get to the third one you know the image data is next and then just read from that offset into your image.

A better way to do it is to write a simple index header first with the offset of the binary data and then you don't have to do the parsing of the \n you can just read up to the offset and treat all that as text and then read from the offset on and treat the rest as your image.

There is no reason you need to encode anything to Base64 or anything like that, that will just bloat your file format and cause more complication than good.

🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › io › FileInputStream.html
FileInputStream (Java Platform SE 8 )
April 21, 2026 - FileInputStream is meant for reading streams of raw bytes such as image data. For reading streams of characters, consider using FileReader. ... File, FileDescriptor, FileOutputStream, Files.newInputStream(java.nio.file.Path, java.nio.file.OpenOption...)
🌐
Mkyong
mkyong.com › home › java › how to read file in java – fileinputstream
How to read file in Java - FileInputStream - Mkyong.com
January 1, 2021 - In Java, we use FileInputStream to read bytes from a file, such as an image file or binary file.
🌐
Javatpoint
javatpoint.com › java-fileinputstream-class
Java FileInputStream Class
Unlike FileOutputStream class, you don't need to convert string into byte array because it provides method to write string directly. Java ... ... Java Class Java is an output stream used for writing data to a file. If you have to write primitive values into a file, use class. You can write byte-oriented as well as character-oriented data through class.
Find elsewhere
🌐
GeeksforGeeks
geeksforgeeks.org › java › java-io-fileinputstream-class-java
Java FileInputStream Class - GeeksforGeeks
November 3, 2025 - The FileInputStream class in Java is used to read data from a file in the form of bytes. It’s ideal for reading binary data such as images or audio files.
🌐
Oracle
docs.oracle.com › javase › 7 › docs › technotes › guides › imageio › spec › apps.fm3.html
Java Image I/O API Guide: 3 - Writing Image I/O Applications
Once a reader has been obtained, it must be supplied with an input source. Most readers are able to read from an ImageInputStream, which is a special input source that is defined by the Image I/O API. A special input source is used in order to make it simple for reader and writers to work with ...
Top answer
1 of 4
52

XXXInputStream and XXXOutputStream (where XXX varies, there's a lot of options) deal with 8-bit bytes. For example, OutputStream.write(byte[] c);

XXXWriter or XXXReader deal with 16-bit chars. For example, Reader.read(char[] cbuf).

OutputStreamWriter converts an OutputStream to a Writer. As you may have guessed, InputStreamReader converts from an InputStream to a Reader. I am unaware of any classes that do the reverse, i.e. convert a Reader to an InputStream.

FileWriter is a Writer that talks to files. Since a Java String internally uses chars (16 bit so they can handle Unicode), FileWriter is the natural class for use with Unicode Strings.

FileOutputStream is an OutputStream for writing bytes to a file. OutputStreams do not accept chars (or Strings). By wrapping it in an OutputStreamWriter you now have a Writer, which does accept Strings.

Now, the real question, is when do you use a Reader/Writer and when a Stream? I've used Java for years and sometimes I get confused too. I believe the following to be correct:

Handy Guide - How to Decide Which to use:

  1. If you are dealing with binary data (e.g. an image) use Streams.
  2. If you are using non-ASCII Unicode characters, e.g. Chinese, use Readers/Writers.
  3. If you are using ordinary ASCII text (the traditional 0-127 characters) you can (usually) use either.

Some other links:

inputstream and reader in Java IO

InputStream vs InputStreamReader

2 of 4
14

There is actually no difference per se, FileWriter is just a convenience class. It extends OutputStreamWriter and creates the needed FileOutputStream itself.

Regarding write(int): that method writes a single character with the specified codepoint to the stream, it does not write a textual representation of the numeric value.

As for the empty file, note that you should always flush the buffer when you want the things you've written flushed to the underlying store (be it a file or a network stream or whatever you can think of). Simply call os.flush() after writing, that should do it.
EDIT: As Thilo has correctly mentioned, closing the stream should already flush it (and all underlying streams).

And last but not least, you should nearly always explicitly specify the charset/encoding you want your Writer to write in. Writers write characters, while OutputStreams write bytes, so you have to specify how those characters should be encoded into bytes. If you don't specify an encoding, the system default gets used, which may not be what you want.

🌐
GeeksforGeeks
geeksforgeeks.org › java › java-fileinputstream-read-method-with-examples
Java FileInputStream read() Method with Examples - GeeksforGeeks
November 20, 2021 - For displaying the data, we can use System.out.print. ... // Java program to demonstrate the working // of the FileInputStream read() method import java.io.File; import java.io.FileInputStream; public class abc { public static void main(String[] args) { // Creating file object and specifying path File file = new File("file.txt"); try { FileInputStream input= new FileInputStream(file); int character; // read character by character by default // read() function return int between 0 and 255.
🌐
Coding Shuttle
codingshuttle.com › home › handbooks › java programming handbook › fileinputstream and fileoutputstream
FileInputStream and FileOutputStream | Coding Shuttle
April 9, 2025 - Use FileOutputStream when you need to write raw bytes to a file, like saving an image or a binary file. If working with text files, consider using FileReader and FileWriter instead, as they handle character encoding properly.
🌐
Programiz
programiz.com › java-programming › fileinputstream
Java FileInputStream (With Examples)
In this tutorial, we will learn about Java FileInputStream and its methods with the help of examples. The FileInputStream class of the java.io package can be used to read data (in bytes) from files
🌐
TutorialsPoint
tutorialspoint.com › how-to-read-data-from-a-file-using-fileinputstream
How to read data from a file using FileInputStream?
August 1, 2019 - import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class FileInputStreamExample { public static void main(String args[]) throws IOException { //Creating a File object File file = new File("D:/images/javafx.jpg"); //Creating a FileInputStream object FileInputStream inputStream = new FileInputStream(file); //Creating a byte array byte bytes[] = new byte[(int) file.length()]; //Reading data into the byte array int numOfBytes = inputStream.read(bytes); System.out.println("Data copied successfully..."); } }
🌐
Shu
teaching.shu.ac.uk › aces › pc › LEC_NOTE › CSSD › JavaWorkshops › Workshop1 › Java I-O Streams.htm
Java I/O Streams
The names of the methods in both sets of classes are almost identical except for the suffix, that is, character-stream classes end with the suffix Reader or Writer and byte-stream classes end with the suffix InputStream and OutputStream. For example, to read files using character streams, you would use the java.io.FileReader class; for reading it using byte streams you would use java.io.FileInputStream.
Top answer
1 of 2
1

to help illustrate I create a project with a source directory

src

below source I had a package starthere with a class Main

I create another source directory xxx and put in a file a.txt

I also created under xxx a directory called text and put in a file named b.txt

Also I created under src a directory called other and put in a file called c.txt

My code is

    URL url = Main.class.getResource("/a.txt");
    System.out.println(url);
    URL url2 = Main.class.getResource("/text/b.txt");
    System.out.println(url2);
    URL url3 = Main.class.getResource("/other/c.txt");
    System.out.println(url3);

and my output is

D:\temp>java -cp ab.jar starthere.Main

jar:file:/D:/temp/ab.jar!/a.txt

jar:file:/D:/temp/ab.jar!/text/b.txt

jar:file:/D:/temp/ab.jar!/other/c.txt

edit

As you are not wanting to use a File, but simply the InputStream, you can use

InputStream fis = Main.class.getResourceAsStream("/a.txt");

and then set using ps.setBinaryStream(1, fis);

2 of 2
0

Consider following package structure

/
/testing_package
/testing_package/Main.java
/testing_package/Image.png

Now Here is a program to get Image.png and put it in database

public class Main {
    public static void main(String...args) {
        System.out.println(Main.class.getResource("image.jpg"));
        //PreparedStatement as ps
        ps.setBinaryStream(1, Main.class.getResourceAsStream("image.jpg")));
    }
}

Thing to keep in mind
When using getResource(...) or getResourceAsStream(...) use relative location to the class instance whose function you are invoking.

Have a look at this answer too

🌐
Realjavaonline
realjavaonline.com › Files › streams.php
Files-Learn Java Really
FileOutputStream (File fileObject) ... or by FileDescriptor object. As FileInputStream class provides implementation for read() methods from InputStream class, similarly, the FileOutputStream class provides an implementation of write() methods....