【问题标题】:What is the difference between the method writeChar and writeShort in java.io.DataOutputStream class?java.io.DataOutputStream 类中的 writeChar 和 writeShort 方法有什么区别?
【发布时间】:2014-02-13 14:57:56
【问题描述】:

我目前正在学习java的基本I/O。请看以下代码:

import java.io.DataOutputStream;
import java.io.IOException;
public class TestIO {

public static void main(String[] args) {

    try(DataOutputStream out=new 
    DataOutputStream(new FileOutputStream("e:\\ccc.txt"))){

        out.writeShort(67);
        out.writeChar(67);

    }catch(IOException ex){
        ex.printStackTrace();
    }

}

}

在输出的 ccc.txt 文件中,我得到以下输出:

 C C

我知道这两种方法都将两个字节写入输出流,而 67 的二进制字符串是 1000011,它表示 ASCII 或任何其他代码中的大写字母 C。 C 前面的空格是方法读取的字节 0000 0000。

但是,如果这两种方法都只是将两个字节写入输出流,那么这两种方法有什么区别?我期待 writeShort 可以将两个字节写入输出流,然后将其传输回整数。换句话说,如何直接将整数 67 写入文件,而不是将其转换为字符?


让我换个方式问这个问题,这两种方法在什么情况下会产生不同的结果?我需要一个真实的例子。谢谢!

【问题讨论】:

  • 请注意,有些编码不是C的编码形式。但在 Java 中,'C' 的值将始终为 67,因为它始终是 UTF-16。
  • @Ingo,实际上 writeShort(33333) 没有给出编译时错误?对此有什么想法吗?
  • @user3225698 这可能是因为参数被声明为 int。如果 writeChar 的参数也声明为 int,那么您将无法产生不同的结果。如果是char,那么试试writeChar(77777)。
  • @user3225698 实际上是int,但可以这样想:如果Java被更改为char使用3个字节,那么它会有所作为。不需要往后想:我想写 2 个字节,使用哪种方法?(在这种情况下使用 writeByte 两次)但是:我需要写一个 X,所以我使用writeX 方法。

标签: java io outputstream


【解决方案1】:

但是,如果这两种方法都只是将两个字节写入输出流,这两种方法有什么区别?

这听起来很陈词滥调,但是:一个使用char,另一个使用short。这些类型不能相互转换,并且您在不同的时间使用它们。尽管 char 只是一个 16 位无符号整数,但它的预期用途是用于 UTF-16 代码单元;您不会(或至少不应该)使用它来存储您认为为数字的值...而short 则相反。

因此,如果您想编写 char,请使用 writeChar。如果您有short,请使用writeShort。在这两种情况下,您都需要使用相应的方法来阅读。

【讨论】:

  • 已更正 writeHsort -> writeShort
【解决方案2】:

我怀疑这种混淆来自于尝试使用旨在编写二进制文件的类来编写文本。如果你想写/读文本使用 Writer/Reader 类。如果你想要二进制使用 OutputStream/InputStream。

PrintWriter pw = new PrintWriter("ccc.txt");
pw.println('C');
pw.println(67);
pw.close();

会生成一个看起来像这样的文件

C
67

但实际上您已经编写了一个包含字节 67、19、16、54、55、19、16 的文件,即它现在是 7 个字节长。

如果这两种方法都只是将两个字节写入输出流,这两种方法有什么区别?

在这种情况下,他们做的事情完全相同。区别只对 readChar / readShort 很重要。

public final void writeChar(int v) throws IOException {
    out.write((v >>> 8) & 0xFF);
    out.write((v >>> 0) & 0xFF);
    incCount(2);
}

public final void writeShort(int v) throws IOException {
    out.write((v >>> 8) & 0xFF);
    out.write((v >>> 0) & 0xFF);
    incCount(2);
}

你可以看到代码是一样的。

我期待 writeShort 可以将两个字节写入输出流,然后将其传输回整数。

一个文件只包含一个字节流。

也就是说,如何直接将整数 67 写入文件,而不是将其转换为字符?

这就是你正在做的事情。一个文件只包含字节。当您阅读文本时,您会将这些字节转换为 chars、shorts 或 ints,具体取决于您阅读它们的方式。

【讨论】:

  • 谢谢。我以前读过源代码。我的困惑是:在现实世界中,在什么情况下,这两种方法会产生不同的结果?如果它们完全相同,为什么还要有两种方法呢?
  • @user3225698 你会使用哪种方法,你会怎么称呼它,所以很明显你可以写shortchar?如果我有readShortreadChar 我会使用哪种写方法?
  • 感谢您的回答
  • @user3225698 很可能是为了保持文档和使用简单。如果您开始说只有一种方法,那么开发人员会开始问,为什么有一种写入和两种读取方法,以及当我将其写为短时我的 char 会发生什么等
【解决方案3】:
writeShort(int v) 

将两个字节写入输出流以表示参数的值。

writeChar(int v) 

将一个由两个字节组成的 char 值写入输出流。

您可以使用:

writeInt(int v) 

将一个由四个字节组成的 int 值写入输出流。

【讨论】:

    【解决方案4】:

    一般来说,您不希望使用writeChar() 将文本数据写入输出流。您需要使用具有正确编码的Writer

    如果您出于某种原因需要输出二进制 16 位有符号整数,可以使用 writeShort,但如果您确实需要这么多的控​​制,则可能需要使用 ByteBuffer

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-06
      • 1970-01-01
      • 2015-04-18
      • 2016-06-28
      • 1970-01-01
      • 2023-03-29
      • 2014-04-22
      • 1970-01-01
      相关资源
      最近更新 更多