JavaIO流-字节输入流与字符输入流
Posted bingfeng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaIO流-字节输入流与字符输入流相关的知识,希望对你有一定的参考价值。
IO流详解
一、输入流
字节输入流
FileInputSteam
1、构造方法:
public FileInputStream(File file) {}
public FileInputStream(FileDescriptor fdObj){}
public FileInputStream(String name){}
2、read方法:
// 每次读取一个字节
public int read(){}
// 读取b.length个字节到byte数组中
public int read(byte b[]){}
// 从输入流中读取len个字节到字节数组中
public int read(byte b[], int off, int len){}
3、文件读取:
1、read()
每次读取一个字节数据,返回字节数,如果到达文件末尾,返回-1。
文本
abc
public static void method_01(String filePath) throws IOException {
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(filePath);
// 每次读取一个字节
for (int i = 0; i < 4; i++) {
int read = inputStream.read();
System.out.println(read);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (null != inputStream) {
// 关闭IO流
inputStream.close();
}
}
}
执行结果:
97
98
99
-1
从执行结果可以看出,前三次读取到了数据,返回了对应的ASCII码,当读取到文件末尾的时候,则返回-1。
2、read(byte[] b)
读入缓冲区的字节总数,如果到达文件末尾,则返回-1。
文本:
abcdefg
声明一个大于真实数据的byte数组读取数据。
public static void method_02(String filePath) throws IOException {
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(filePath);
// 声明的长度大于真实数据长度
byte[] bytes = new byte[20];
int length = inputStream.read(bytes);
System.out.println("字节数组长度:" + bytes.length + " 读取到的数据字节长度:" + length);
for (byte b : bytes) {
System.out.print(b + " | ");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (null != inputStream) {
inputStream.close();
}
}
}
执行结果:
字节数组长度:20 读取到的数据字节长度:7
97 | 98 | 99 | 100 | 101 | 102 | 103 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
可以看出,当我们byte数组的长度大于字节数组的真实长度之后,那么后面的空间全部使用0做补位,这也恰恰反映了另外一个问题,我们在使用byte[]数组读取文件的时候,千万不要说我设置足够大的长度,就可以高枕无忧提高读取效率,如果遇到小文件,那么也是很容易造成效率低下的。
3、read(byte b[], int off, int len)
读入缓冲区的字节总数,如果读取到文件末尾,则返回-1;
文本:
abcdefg
声明一个固定大小的byte数组,循环读取数据
我们的文本有七个字节,声明了一个2个长度的数组,应该循环四次,第五次读取的时候返回-1。
public static void method_03(String filePath) throws IOException {
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(filePath);
// 声明2个长度
byte[] bytes = new byte[2];
int i = 0;
while (i < 5) {
int length = inputStream.read(bytes, 0, bytes.length);
System.out.println("第" + (i + 1) + "次读取,length: " + length);
System.out.println("开始输出:");
for (int j = 0; j < length; j++) {
System.out.print(bytes[j] + " | ");
}
System.out.println();
i++;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (null != inputStream) {
inputStream.close();
}
}
}
执行结果:
第1次读取,length: 2
开始输出:
97 | 98 |
第2次读取,length: 2
开始输出:
99 | 100 |
第3次读取,length: 2
开始输出:
101 | 102 |
第4次读取,length: 1
开始输出:
103 |
第5次读取,length: -1
开始输出:
注意:
可能有的朋友会遇到我之前遇到的问题,他的文本里面写了汉字或者标点符号,会出现乱码,我们给文本最后再追加一个中文,并且把每次读取到的byte数组转换成String进行输出,看会出现什么情况。
public static void method_03(String filePath) throws IOException {
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(filePath);
byte[] bytes = new byte[2];
int i = 0;
while (i < 5) {
inputStream.read(bytes, 0, bytes.length);
// 将byte[]转换成string
String s = new String(bytes, StandardCharsets.UTF_8);
System.out.println(s);
i++;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (null != inputStream) {
inputStream.close();
}
}
}
结果:
ab
cd
ef
g�
��
刚开始脑子抽了,感觉这是什么问题,怎么会乱码呢,如果稍微上点心的都会发现,中文占3个byte字节,你用2个存储那铁定乱码呀。那么你肯定想过那我把数组声明大一点不就好了,如果你这么想过,那你可能还不知道社会的险恶。
那么到底怎么办呢?真的就没办法了吗?接下来我们用一个例子来学习如何解决这种问题。
一个
以上是关于JavaIO流-字节输入流与字符输入流的主要内容,如果未能解决你的问题,请参考以下文章
JavaIO流--转换流--InpuStreamReaderOutputStreamWriter