写在前面的话
前面学习了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);
看一下打印结果:
读操作
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流