Java | 学习字节流DataInputStream and DataOutputStream

写在前面的话

前面学习了InputStream、FileInputStream,但在实际项目中,很少直接用到,另外,通过上一节写的复制工具类,也发现读取很麻烦,速度也很慢。

比如,在Socket的时候,我们通常会通过Socket拿到DataInputStream(DataOutputStream),那么这是什么呢?这一节我们就来学习一下。

字节流

DataInputStream

  • 结构
java.lang.Object 
  java.io.InputStream 
    java.io.FilterInputStream 
      java.io.DataInputStream 
  • 构造方法
DataInputStream(InputStream in) 
创建使用指定的底层InputStream的DataInputStream。
  • API
int read(byte[] b) 
从包含的输入流中读取一些字节数,并将它们存储到缓冲区数组 b 。 

int read(byte[] b, int off, int len) 
从包含的输入流读取最多 len个字节的数据为字节数组。  

boolean readBoolean()   

byte readByte()  

char readChar()   

double readDouble() 
 
float readFloat()   

void readFully(byte[] b) 
  
void readFully(byte[] b, int off, int len) 
  
int readInt()  

String readLine() 
已弃用 
此方法无法将字节正确转换为字符。 从JDK 1.1开始,读取文本行的BufferedReader.readLine()方法是通过BufferedReader.readLine()方法。 使用DataInputStream类读取行的程序可以转换为使用BufferedReader类替换以下形式的代码: 
     DataInputStream d = new DataInputStream(in);
 与: 
     BufferedReader d
          = new BufferedReader(new InputStreamReader(in));
  
long readLong()  

short readShort()   

int readUnsignedByte() 
  
int readUnsignedShort() 

String readUTF()  

static String readUTF(DataInput in) 
从流in读取以modified UTF-8格式编码的Unicode字符串的表示; 这个字符串然后作为String返回。 
  • 说明:

为什么没有对方法做解释呢?这是因为,在API中,也是让我们参考 DataInput 。其实,他的作用,看方法名称也大概也是知道的,这里我要说明的是,我们可以去看看他的代码的实现,例如 readInt() 方法

    public final int readInt() throws IOException {
        int ch1 = in.read();
        int ch2 = in.read();
        int ch3 = in.read();
        int ch4 = in.read();
        if ((ch1 | ch2 | ch3 | ch4) < 0)
            throw new EOFException();
        return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
    }

我们知道 int 是4个字节,所以他读了4次,他这样的封装为我们带来了极大的便利,这大概也是我们要学习的原因吧,你理解了吗?后面的DataOutputStream,我们不就详细说明了,原理大概一样,如果你去看 writeInt() 源码,你可能会惊奇的发现,我们在前面已经写过了。哈哈~

DataOutputStream

  • 构造方法
DataOutputStream(OutputStream out) 
创建一个新的数据输出流,以将数据写入指定的底层输出流。
  • API
void flush() 
刷新此数据输出流。  

int size() 
返回计数器的当前值 written ,到目前为止写入此数据输出流的字节数。 
 
void write(byte[] b, int off, int len) 
写入 len从指定的字节数组起始于偏移 off基础输出流。  

void write(int b) 
将指定的字节(参数 b的低8位)写入底层输出流。  

void writeBoolean(boolean v) 
将 boolean写入底层输出流作为1字节值。  

void writeByte(int v) 
将 byte作为1字节值写入底层输出流。  

void writeBytes(String s) 
将字符串作为字节序列写入基础输出流。  

void writeChar(int v) 
将 char写入底层输出流作为2字节值,高字节优先。
  
void writeChars(String s) 
将字符串写入底层输出流作为一系列字符。  

void writeDouble(double v) 
双参数传递给转换 long使用 doubleToLongBits方法在类 Double ,然后写入该 long值基础输出流作为8字节的数量,高字节。  

void writeFloat(float v) 
浮子参数的转换 int使用 floatToIntBits方法在类 Float ,然后写入该 int值基础输出流作为一个4字节的数量,高字节。  

void writeInt(int v) 
将底层输出流写入 int作为四字节,高位字节。  

void writeLong(long v) 
将 long写入底层输出流,为8字节,高字节为首。
  
void writeShort(int v) 
将 short写入底层输出流作为两个字节,高字节优先。 
 
void writeUTF(String str) 
使用 modified UTF-8编码以机器无关的方式将字符串写入基础输出流。  

再学点东西

在写之前,我们再来学点东西

先看FileInputStream

public class FileInputStream extends InputStream

再看InputStream

public abstract class InputStream implements Closeable

读写操作

写入操作

String filePath = "E:\\Workspace\\IdeaStudio\\io-demo\\i-o\\demo\\data.dat";

// 参见【再学点东西】部分
DataOutputStream dos = new DataOutputStream(new FileOutputStream(new File(filePath)));

dos.write('A');
dos.writeInt(10);
dos.writeBoolean(true);
dos.writeByte(-1);
dos.writeChar('B');
// 采用UTF-16BE
dos.writeChars("中国");
dos.writeUTF("中国");
dos.writeDouble(20.10);
dos.writeFloat(10.20f);
dos.writeLong(100000000L);

dos.close();

IOUtil.printHex(filePath);

看一下打印结果:

采用16进制输出,代表我们写进去了

读操作

String filePath = "E:\\Workspace\\IdeaStudio\\io-demo\\i-o\\demo\\data.dat";

DataInputStream dis = new DataInputStream(new FileInputStream(new File(filePath)));

System.out.println(dis.read());
System.out.println(dis.readInt());
System.out.println(dis.readBoolean());
System.out.println(dis.readByte());
System.out.println(dis.readChar());

// chars
System.out.println(dis.readChar());
System.out.println(dis.readChar());

System.out.println(dis.readUTF());
System.out.println(dis.readDouble());
System.out.println(dis.readFloat());
System.out.println(dis.readLong());

dis.close();

看一下打印结果:

资料

1、本节测试代码:i-o

2、学习视频:文件传输基础——Java IO流

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容