Java - 区分发送到 OutputStream 的两个字符串
Java - Differenciate between two Strings sent into OustputStream
我将 2 个字符串值从 Client.java 发送到 OutputStream,如下所示:
outputStream.write(username.getText().getBytes());
outputStream.write(password.getText().getBytes());
在 Server.java 中,当我读取 inputStream 时,我试图将每个值分开:
inputStream = s.getInputStream();
byte[]username = new byte[20];
inputStream.read(username);
String user = new String(username);
System.out.println("username = "+user);
我从逻辑上得到:usernamepassword
作为控制台输出。
我想做的是:
String usr = new String(user);
String pass = new String(password);
有没有比在输出流字符串中添加一些分隔符更好的方法?
您需要分隔两个字符串值,以便 reader 知道一个字符串在哪里结束以及下一个字符串从哪里开始。该分隔符实际包含的内容由您根据您的特定需要决定。
您可以在写出实际字节之前使用固定宽度的整数写出字符串的字节长度。然后 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);
或者,DataOutputStream
和 DataInputStream
可以直接 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();
您可以写出一个永远不会出现在字符串值本身中的唯一字符序列,例如换行符或控制字符(甚至是空终止符)。然后 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);
我将 2 个字符串值从 Client.java 发送到 OutputStream,如下所示:
outputStream.write(username.getText().getBytes()); outputStream.write(password.getText().getBytes());
在 Server.java 中,当我读取 inputStream 时,我试图将每个值分开:
inputStream = s.getInputStream(); byte[]username = new byte[20]; inputStream.read(username); String user = new String(username); System.out.println("username = "+user);
我从逻辑上得到:usernamepassword
作为控制台输出。
我想做的是:
String usr = new String(user);
String pass = new String(password);
有没有比在输出流字符串中添加一些分隔符更好的方法?
您需要分隔两个字符串值,以便 reader 知道一个字符串在哪里结束以及下一个字符串从哪里开始。该分隔符实际包含的内容由您根据您的特定需要决定。
您可以在写出实际字节之前使用固定宽度的整数写出字符串的字节长度。然后 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);
或者,
DataOutputStream
和DataInputStream
可以直接 write/readString
值,在内部为您处理上述逻辑(使用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();
您可以写出一个永远不会出现在字符串值本身中的唯一字符序列,例如换行符或控制字符(甚至是空终止符)。然后 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);