javaprintingjava-print

java - "ps: stack underflow" when sending postscript directly to network printer


I wrote a piece of Java code to send PDF-turned postscript scripts to a network printer via Socket.

The files were printed in perfect shape but every job comes with one or 2 extra pages with texts like ps: stack underflow or error undefined offending command.

At beginning I thought something is wrong with the PDF2PS process so I tried 2 PS files from this PS Files. But the problem is still there.

I also verified the ps files with GhostView. Now I think there may be something wrong with the code. The code does not throw any exception.

The printer, Toshiba e-studion 5005AC, supports PS3 and PCL6.

    File file = new File("/path/to/my.ps");

    Socket socket = null;
    DataOutputStream out = null;
    FileInputStream inputStream = null;
    try {
        socket = new Socket(printerIP, printerPort);
        out = new DataOutputStream(socket.getOutputStream());
        DataInputStream input = new DataInputStream(socket.getInputStream());
        inputStream = new FileInputStream(file);
        byte[] buffer = new byte[8000];

        while (inputStream.read(buffer) != -1) {
            out.write(buffer);

        }

        out.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }

Solution

  • You are writing the whole buffer to the output stream regardless of how much actual content there is. That means that when you write the buffer the last time it will most probably have a bunch of content from the previous iteration at the end of the buffer.

    Example

    e.g. imagine you have the following file and you use a buffer of size 10:

     1234567890ABCDEF
    

    After first inputStream.read() call it will return 10 and in the buffer you will have:

     1234567890
    

    After second inputStream.read() call it will return 6 and in the buffer you will have:

     ABCDEF7890
    

    After third inputStream.read() call it will return -1 and you will stop reading.

    A printer socket will receive these data in the end:

    1234567890ABCDEF7890
    

    Here the last 7890 is an extra bit that the printer does not understand, but it can successfully interpret the first 1234567890ABCDEF.

    Fix

    You should consider the length returned by inputStream.read():

            byte[] buffer = new byte[8000];
            for (int length; (length = inputStream.read(buffer)) != -1; ){
                out.write(buffer, 0, length);
            }
    

    Also consider using try-with-resources to avoid problems with unclosed streams.