1

How can i write data into an image (create image by received data) .

(By socket)

My client read an image from system and send it to server and server should receive and save it in any other place in my computer.

Here is my code:

client:

public class Client_Image_Transfer {

Socket clientSocket = null;
OutputStream outputStream = null;
DataOutputStream dataOutputStream = null;
InputStream inputStream = null;

public Client_Image_Transfer() {
    try {
        clientSocket = new Socket("localhost", 6002);
        outputStream = clientSocket.getOutputStream();
        dataOutputStream = new DataOutputStream(outputStream);
        inputStream = clientSocket.getInputStream();

        BufferedReader br = new BufferedReader(new FileReader("HelloNewPic.jpg"));
        outputStream.write(br.read());

        System.out.println("Client: Image sent to server");
        dataOutputStream.close();
        clientSocket.close();

    } catch (Exception e) {
        e.printStackTrace();
    }
}

Server:

public class Server_Image_Transfer {
ServerSocket serverSocket = null;
Socket socket = null;
DataInputStream dataInputStream = null;

public Server_Image_Transfer() {
    try {
        serverSocket = new ServerSocket(6002);
        System.out.println("Server is Waiting for request...");
        socket = serverSocket.accept();
        System.out.println("Connected with: " + socket.getInetAddress());
        dataInputStream = new DataInputStream(socket.getInputStream());
        System.out.println("Server received image from client");

           // How write ? 

    } catch (Exception e) {
        e.printStackTrace();
    }
}

My server received image correctly, But now how write by an image without ImageIO?

This is not worked also:

    File outPutFile = new File("C:\\Users\\khoy\\Desktop\\a2.jpg");
    FileOutputStream fos = null;
    fos = new FileOutputStream(outPutFile,true);
    fos.write(socket.getInputStream());    // Compile Error
Sunrise
  • 131
  • 1
  • 1
  • 9

2 Answers2

2

There are some issues with this code:

  • You are using a FileReader. This is intended for character ("text") files. A JPG image is a binary file. You should use a stream for such a file.
  • Something like outputStream.write(bufferedReader.read()); will only read a single byte from the BufferedReader, and write this single byte to the OutputStream. In order to read the whole contents of the file, you have to use a loop, and should read multiple bytes at once to achieve an acceptable performance
  • Your usage of InputStream and OutputStream seems to be messed up in general. This is probably the reason for the question...

However, the pattern is the same on the server and the client side. In both cases you have to read from an InputStream and writing to an OutputStream :

  • On the client side, you are reading from a FileInputStream and writing to the OutputStream of the socket
  • On the server side, you are reading from the InputStream of the socket and writing to a FileOutputStream.

Considering this, and using some convenience methods, you can roughly apply this pattern (written from the tip of my head, so possibly not bug-free, but hopefully showing the idea) :

private static void clientWrite(Socket socket)
{
    OutputStream out = null; 
    InputStream in = null;
    try
    {
        in = new FileInputStream("HelloNewPic.jpg");
        out = socket.getOutputStream();
        pipe(in, out);
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
    finally
    {
        close(in);
        close(out);
    }
}

private static void serverRead(Socket socket)
{
    OutputStream out = null; 
    InputStream in = null;
    try
    {
        in = socket.getInputStream();
        out = new FileOutputStream("HelloNewPic_Server.jpg");
        pipe(in, out);
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
    finally
    {
        close(in);
        close(out);
    }
}



/**
 * Close the given Closeable if it is not <code>null</code>,
 * printing an error message if an IOException is caused
 * 
 * @param c The closeable
 */
private static void close(Closeable c)
{
    if (c != null)
    {
        try
        {
            c.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}


/**
 * Fully reads the given input stream and writes the result to the
 * given output stream. The caller is responsible for closing the
 * given streams.
 * 
 * @param in The input stream
 * @param out The output stream
 * @throws IOException If an IO error occurs
 */
private static void pipe(InputStream in, OutputStream out) throws IOException
{
    byte buffer[] = new byte[8192];
    while (true)
    {
        int read = in.read(buffer);
        if (read < 0)
        {
            break;
        }
        out.write(buffer, 0, read);
    }
}
Marco13
  • 53,703
  • 9
  • 80
  • 159
1

Just create an FileOutputStream and copy the data from input stream. There are a lot of ways for that, but using the appache commons library is the easiest one.

Artyomcool
  • 383
  • 2
  • 5