1

I want to write a class to be used in comunicaion between Java and C++

There are a lot of discussion about Java and C++ communication. Here I'm not requesting how to communicate, I konw an i know how.

I create a

 OutputStream os = socketChannel.socket().getOutputStream();
 OutputStreamWriter osw = new OutputStreamWriter( os);
 BufferedWriter wr = new BufferedWriter( osw );

then I write

 String data= dataArea.getText();

 wr.write( dataArea.getText() );
 wr.write('\0');//here is the wire with C++
 wr.flush(); // flushes the stream

I send some text:

Hi this is a test
i send also 
character as dollar $ ...
or other stange é*"£$%&/(()=?'^ìì[]@!<>#òùèé+*
and so on

So reading raw text send between two system i see:

00000000  48 69 20 74 68 69 73 20  69 73 20 61 20 74 65 73   Hi this  is a tes 
00000010  74 0A 69 20 73 65 6E 64  20 61 6C 73 6F 20 0A 63   t.i send  also .c 
00000020  68 61 72 61 63 74 65 72  20 61 73 20 64 6F 6C 6C   haracter  as doll 
00000030  61 72 20 24 20 2E 2E 2E  0A 6F 72 20 6F 74 68 65   ar $ ... .or othe 
00000040  72 20 73 74 61 6E 67 65  20 C3 A9 2A 22 C2 A3 24   r stange  ..*"..$ 
00000050  25 26 2F 28 28 29 3D 3F  27 5E C3 AC C3 AC 5B 5D   %&/(()=? '^....[] 
00000060  40 21 3C 3E 23 C3 B2 C3  B9 C3 A8 C3 A9 2B 2A 0A   @!<>#... .....+*. 
00000070  61 6E 64 20 73 6F 20 6F  6E 00                     and so o n.

This is near the solution.

changing CHARSET "US-ASCII" I obtain

Hi this is a test
    i send also 
    character as dollar $ ...
    or other stange é*"£$%&/(()=?'^ìì[]@!<>#òùèé+*
    and so on


00000000  48 69 20 74 68 69 73 20  69 73 20 61 20 74 65 73   Hi this  is a tes 
00000010  74 0A 20 20 20 20 69 20  73 65 6E 64 20 61 6C 73   t.    i  send als 
00000020  6F 20 0A 20 20 20 20 63  68 61 72 61 63 74 65 72   o .    c haracter 
00000030  20 61 73 20 64 6F 6C 6C  61 72 20 24 20 2E 2E 2E    as doll ar $ ... 
00000040  0A 20 20 20 20 6F 72 20  6F 74 68 65 72 20 73 74   .    or  other st 
00000050  61 6E 67 65 20 3F 2A 22  3F 24 25 26 2F 28 28 29   ange ?*" ?$%&/(() 
00000060  3D 3F 27 5E 3F 3F 5B 5D  40 21 3C 3E 23 3F 3F 3F   =?'^??[] @!<>#??? 
00000070  3F 2B 2A 0A 20 20 20 20  61 6E 64 20 73 6F 20 6F   ?+*.     and so o 
00000080  6E 00 

This is near my purpose.


I need to transfer only ASCII with extended characters "è"-->E8

Then I need to put '\0' at the end of the string.

'\0' is message terminator.

Now the question: using Java i like to create a Writer or stream writer to output the specific binary data format.

At what level is correct to work with OutputStreamWriter or BufferedWriter and should I rewrite from scratch extend or use some library? Are some example all around about what I like to do? I'll do the same for input

I like to write it in this form because tomorrow when I rewrite C++ server in Java I use on the both side DataOutputStream.

Using a while is not a nice solution I prefer a more Java integrated solution.

4

2 回答 2

1

此流已启用自动刷新和 US-ASCII,如您所愿。

OutputStream os = socketChannel.socket().getOutputStream();
PrintStream ps = new PrintStream( os, true, "US-ASCII" );
ps.print( "tange é*"£$%&/(()=?'^ìì[]@!<>#òùèé+*" );
os.write( (byte)0 ); // end-of-message
于 2013-02-14T17:39:42.470 回答
1

我已经做了一个基于 BufferedWriter 和 BufferedReader 的可能解决方案,我使用了正确的 ASCII 扩展字符编码的 ISO-8859-1。


OutputStream os = socketChannel.socket().getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os, "ISO-8859-1");
TBufferedWriter bw = new TBufferedWriter (osw);
bw.writeTMessageFlushing( dataArea.getText() );


InputStream is = socketChannel.socket().getInputStream();
InputStreamReader isr= new InputStreamReader(is, "ISO-8859-1") ;
TBufferedReader br= new TBufferedReader(isr);
// wait for response
String responseLine = br.readTMessage();

我只是简单地打开了 BufferedWriter 和 BufferedReader 的源代码,看看如何获​​得我的交互。

BufferedReader 不能简单地扩展,因为使用了一些函数。(它应该是从 java Boys 重写的)。它扩展了缓冲阅读器,但没用


import java.io.BufferedWriter;
import java.io.IOException;
import java.io.Writer;


public class TBufferedWriter extends BufferedWriter {


    public TBufferedWriter(Writer out){
        super( out );
    }
    public TBufferedWriter(Writer out, int sz){
        super( out, sz );
    }

    public void writeTMessage(String message) throws IOException {
         synchronized (lock) {
              super.write( message );
              super.write('\0');
         }
    }
     public void writeTMessageFlushing(String message) throws IOException {
         synchronized (lock) {
              super.write( message );
              super.write('\0');
              super.flush();
         }
    }

}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;


public class TBufferedReader extends BufferedReader {
    private Reader in;
    private char cb[];
    private int nChars, nextChar;
    private static final int INVALIDATED = -2;
    private static final int UNMARKED = -1;
    private int markedChar = UNMARKED;
    private int readAheadLimit = 0; /* Valid only when markedChar > 0 */

    /** If the next character is a line feed, skip it */
    private boolean skipNUL = false;
    /** The skipLF flag when the mark was set */
    private boolean markedSkipLF = false;
    private static int defaultCharBufferSize = 8192;
    private static int defaultExpectedLineLength = 80;


    /**
     * Creates a buffering character-input stream that uses an input buffer of
     * the specified size.
     *
     * @param  in   A Reader
     * @param  sz   Input-buffer size
     *
     * @exception  IllegalArgumentException  If sz is <= 0
     */
    public TBufferedReader( Reader in, int sz ) {
        super( in );
        if (sz <= 0) {
            throw new IllegalArgumentException( "Buffer size <= 0" );
        }
        this.in = in;
        cb = new char[ sz ];
        nextChar = nChars = 0;
    }


    /**
     * Creates a buffering character-input stream that uses a default-sized
     * input buffer.
     *
     * @param  in   A Reader
     */
    public TBufferedReader( Reader in ) {
        this( in, defaultCharBufferSize );
    }


    /** Checks to make sure that the stream has not been closed */
    private void ensureOpen() throws IOException {
        if (in == null) {
            throw new IOException( "Stream closed" );
        }
    }


    /**
     * Fills the input buffer, taking the mark into account if it is valid.
     */
    private void fill() throws IOException {
        int dst;
        if (markedChar <= UNMARKED) {
            /* No mark */
            dst = 0;
        } else {
            /* Marked */
            int delta = nextChar - markedChar;
            if (delta >= readAheadLimit) {
                /* Gone past read-ahead limit: Invalidate mark */
                markedChar = INVALIDATED;
                readAheadLimit = 0;
                dst = 0;
            } else {
                if (readAheadLimit <= cb.length) {
                    /* Shuffle in the current buffer */
                    System.arraycopy( cb, markedChar, cb, 0, delta );
                    markedChar = 0;
                    dst = delta;
                } else {
                    /* Reallocate buffer to accommodate read-ahead limit */
                    char ncb[] = new char[ readAheadLimit ];
                    System.arraycopy( cb, markedChar, ncb, 0, delta );
                    cb = ncb;
                    markedChar = 0;
                    dst = delta;
                }
                nextChar = nChars = delta;
            }
        }

        int n;
        do {
            n = in.read( cb, dst, cb.length - dst );
        } while (n == 0);
        if (n > 0) {
            nChars = dst + n;
            nextChar = dst;
        }
    }


    /**
     * Reads a line of text.  A line is considered to be terminated by any one
     * of a line feed ('\0')
     *
     * @param      ignoreNUL  If true, the next '\0' will be skipped
     *
     * @return     A String containing the contents of the line, not including
     *             any line-termination characters, or null if the end of the
     *             stream has been reached
     *
     * @see        java.io.LineNumberReader#readLine()
     *
     * @exception  IOException  If an I/O error occurs
     */
    String readTMessage( boolean ignoreNUL ) throws IOException {
        StringBuffer s = null;
        int startChar;

        synchronized (lock) {
            ensureOpen();
            boolean omitNUL = ignoreNUL || skipNUL;
bufferLoop:     for (;;) {
                    if (nextChar >= nChars) {
                        fill();
                    }
                    if (nextChar >= nChars) { /* EOF */
                        if (s != null && s.length() > 0) {
                            return s.toString();
                        } else {
                            return null;
                        }
                    }
                    boolean eol = false;
                    char c = 0;
                    int i;

                    /* Skip a leftover '\0', if necessary */
                    if (omitNUL && (cb[nextChar] == '\0')) {
                        nextChar++;
                    }
                    skipNUL = false;
                    omitNUL = false;

charLoop:               for (i = nextChar; i < nChars; i++) {
                            c = cb[i];
                            if ((c == '\0')) {
                                eol = true;
                                break charLoop;
                            }
                        }

                    startChar = nextChar;
                    nextChar = i;

                    if (eol) {
                        String str;
                        if (s == null) {
                            str = new String( cb, startChar, i - startChar );
                        } else {
                            s.append( cb, startChar, i - startChar );
                            str = s.toString();
                        }
                        nextChar++;
                        if (c == '\0') {
                            skipNUL = true;
                        }
                        return str;
                    }

                    if (s == null) {
                        s = new StringBuffer( defaultExpectedLineLength );
                    }
                    s.append( cb, startChar, i - startChar );
                }
        }
    }


    /**
     * Reads a line of text.  A line is considered to be terminated by any one
     * of a line feed ('\n'), a carriage return ('\r'), or a carriage return
     * followed immediately by a linefeed.
     *
     * @return     A String containing the contents of the line, not including
     *             any line-termination characters, or null if the end of the
     *             stream has been reached
     *
     * @exception  IOException  If an I/O error occurs
     *
     * @see java.nio.file.Files#readAllLines
     */
    public String readTMessage() throws IOException {
        return readTMessage( false );
    }
}

其他有趣的课程是

http://www.ibm.com/developerworks/java/zos/javadoc/jzos/index.html?com/ibm/jzos/TranscodingPrintStream.html

org.apache.james.util.CharTerminatedInputStream


我添加了一些关于 CharTerminatedInputStream 的消息。使用 thtat 类是危险的,因为您需要管理使用中的正确字符集。outputStream 更高级,您可以设置 InputStreamReader。

于 2013-02-15T14:33:22.597 回答