Java - 区分发送到 OutputStream 的两个字符串

Java - Differenciate between two Strings sent into OustputStream

我从逻辑上得到:usernamepassword 作为控制台输出。 我想做的是:

     String usr = new String(user);
     String pass = new String(password);

有没有比在输出流字符串中添加一些分隔符更好的方法?

您需要分隔两个字符串值,以便 reader 知道一个字符串在哪里结束以及下一个字符串从哪里开始。该分隔符实际包含的内容由您根据您的特定需要决定。

  1. 您可以在写出实际字节之前使用固定宽度的整数写出字符串的字节长度。然后 reader 可以先读取长度,然后再读取后面指定的字节数:

    DataOutputStream dos = new DataOutputStream(outputStream);
    byte[] bytes;
    int len;
    
    bytes = username.getText().getBytes(StandardCharsets.UTF_8);
    len = bytes.length;
    dos.writeInt(len);
    dos.write(bytes, 0, len);
    
    bytes = password.getText().getBytes(StandardCharsets.UTF_8);
    len = bytes.length;
    dos.writeInt(len);
    dos.write(bytes, 0, len);
    

    inputStream = s.getInputStream();
    DataInputStream dis = new DataInputStream(inputStream);
    byte[] bytes;
    int len;
    
    len = dis.readInt();
    bytes = new byte[len];
    dis.readFully(bytes);
    String username = new String(bytes, StandardCharsets.UTF_8);
    
    len = dis.readInt();
    bytes = new byte[len];
    dis.readFully(bytes);
    String password = new String(bytes, StandardCharsets.UTF_8);
    

    或者,DataOutputStreamDataInputStream 可以直接 write/read String 值,在内部为您处理上述逻辑(使用 short 而不是int 为长度值):

    DataOutputStream dos = new DataOutputStream(outputStream);
    dos.writeUTF(username.getText());
    dos.writeUTF(password.getText());
    

    inputStream = s.getInputStream();
    DataInputStream dis = new DataInputStream(inputStream);
    
    String username = dis.readUTF();
    String password = dis.readUTF();
    
  2. 您可以写出一个永远不会出现在字符串值本身中的唯一字符序列,例如换行符或控制字符(甚至是空终止符)。然后 reader 可以读取字节,直到遇到该序列:

    OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8); 
    String s;
    
    s = username.getText();
    writer.write(s, 0, s.length());
    writer.write(10);
    
    s = password.getText();
    writer.write(s, 0, s.length());
    writer.write(10);
    

    inputStream = s.getInputStream();
    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
    
    String username = reader.readLine();
    String password = reader.readLine();
    

    或者:

    OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8); 
    String s;
    
    s = username.getText();
    writer.write(s, 0, s.length());
    writer.write(0);
    
    s = password.getText();
    writer.write(s, 0, s.length());
    writer.write(0);
    

    inputStream = s.getInputStream();
    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
    StringBuilder sb = new StringBuilder();
    int ch;
    
    do
    {
        ch = reader.read();
        if (ch <= 0) break;
        sb.append((char)ch);
    }
    while (true);
    String username = sb.toString();
    
    sb.setLength(0);
    do
    {
        ch = reader.read();
        if (ch <= 0) break;
        sb.append((char)ch);
    }
    while (true);
    String password = sb.toString();
    

我会选择 DataOutputStream 写作和 DataInputStream 阅读。有了这些,你可以在每个字符串前写一个整数值来知道文本的长度,像这样:

DataOutputStream dos = new DataOutputStream(outputStream);
dos.writeInt(username.getText().length());
dos.write(username.getText().getBytes());
dos.writeInt(password.getText().length());
dos.write(password.getText().getBytes());

然后,在服务器端:

DataInputStream dis = new DataInputStream(inputStream);
int length = 0; // will be used to store the length of each text

length = bytesRead = dis.readInt(); // Read the length of the first text
byte[] usernameBuffer = new byte[length];
dis.read(usernameBuffer);
String username = new String(usernameBuffer);

// Now reading the other text
length = dis.readInt(); // Read the length of the second text
byte[] passwordBuffer = new byte[length];
dis.read(passwordBuffer);
String password = new String(passwordBuffer);