Java拾贝第十一天——IO流之字节流
Java拾贝不建议作为0基础学习,都是本人想到什么写什么
在JavaIO中,流的操作主要有字节流和字符流两大类。
两类都有输入和输出操作。
字节流
字节流主要操作Byte(字节)数据类型。在字节流中:
输出流主要使用OutputStream类,输入流主要使用InputStream类。
OutputStream类定义如下:
public abstract class OutputStream implements Closeable, Flushable
可以发现OutputStream类是一个抽象类。如果想要操作文件,那么需要使用其子类FileOutputStream或FileInputStream。
字节输出流
通过向上转型的方式实例化OutputStream或实例化FileOutputStream自身。
FileOutputStream构造方法如下:
public FileOutputStream(File file) throws FileNotFoundException
传参为File对象,File有参构造方法需指明文件路径。
FileOutputStream类常用方法如下:
方法 | 类型 | 描述 |
---|---|---|
public void write(int b) throws IOException | 普通方法 | 将一个字节输出 |
public void write(byte b[]) throws IOException | 普通方法 | 将一个字节数组输出 |
public void write(byte b[], int off, int len) throws IOException | 普通方法 | 将一个指定范围的字节数组输出 |
public void close() throws IOException | 普通方法 | 关闭流 |
write(int b)
输出一个字节。
栗子:
public static void main(String[] args) {
File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
try {
FileOutputStream stream = new FileOutputStream(file);
stream.write(65);
} catch (Exception e) {//直接提高异常优先级,因为有多个异常
e.printStackTrace();
}
}
D:\IOtest\text.txt内:
A
//根据ASCII表得到的结果,在表中十进制的65代表A
write(byte b[])
输出一个字节数组。
栗子:
public static void main(String[] args) {
File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
byte[] bytes = "Hello World!".getBytes();//字符串转为字节数组
try {
FileOutputStream stream = new FileOutputStream(file);
stream.write(bytes);
} catch (Exception e) {
e.printStackTrace();
}
}
D:\IOtest\text.txt内:
Hello World!
write(byte b[], int off, int len)
输出一个指定范围的字节数组。
栗子:
public static void main(String[] args) {
File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
byte[] bytes = "Hello World!".getBytes();
try {
FileOutputStream stream = new FileOutputStream(file);
stream.write(bytes,0,7);下标 从0开始到7结束(不包含7)
} catch (Exception e) {
e.printStackTrace();
}
}
D:\IOtest\text.txt内:
Hello W
close()和末尾追加
关闭流,上述栗子都没有关闭流。
因为程序在main内就结束了,JVM会自动关闭流,但建议在合适的地方手动关闭流。
输出流默认是覆盖输出的,末尾追加内容需要使用被
FileOutputStream重载的有参构造,传参新增一个布尔值:
public FileOutputStream(String name, boolean append)throws FileNotFoundException
栗子:
public static void main(String[] args) {
File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
byte[] bytes = "Hello World!".getBytes();
try {
FileOutputStream stream = new FileOutputStream(file,true);
stream.write(bytes);
stream.write(bytes);//执行两次
stream.close();//手动关闭流
} catch (Exception e) {
e.printStackTrace();
}
}
D:\IOtest\text.txt内:
Hello WHello World!Hello World!
换行需要使用转义符
如果我们需要换行进行追加内容的化需要使用转义符\r\n
\r:回车,光标回到本行首位
\n:换行
为什么要两个?
:在某些系统中两个才能进行换行
至此,修改栗子如下:
public static void main(String[] args) {
File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
byte[] bytes = "\r\nHello World!".getBytes();//换行符
try {
FileOutputStream stream = new FileOutputStream(file,true);
stream.write(bytes);
stream.write(bytes);//执行两次
stream.close();//手动关闭流
} catch (Exception e) {
e.printStackTrace();
}
D:\IOtest\text.txt内:
Hello WHello World!Hello World!
Hello World!
Hello World!
循环输出
栗子:
public class Test11 {
public static void main(String[] args) {
File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
byte[] bytes = "\r\nHello World!".getBytes();
try {
FileOutputStream stream = new FileOutputStream(file,true);//追加的形式
for (int i = 0; i < bytes.length; i++) {
stream.write(bytes[i]);//调用的方法是write(int b)
}
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
通过IDEA-Debug的形式运行上述栗子。
在字符串转为字节数组时,其实数组内部已经存放与字符串对应的字节数值了。
所以循环内调用的都是write(int b)方法。
以前刚开始接触IO的时候我真的怎么看都看不懂只能死记硬背= =,不建议这种行为真的头大
字节输入流
相应的,有输出肯定有输出。
InputStream类定义如下:
public abstract class InputStream implements Closeable
它也是抽象类,想要操作文件需要使用其子类,FileInputStream构造方法如下:
public FileInputStream(File file) throws FileNotFoundException
FileInputStream常用方法如下:
方法 | 类型 | 描述 |
---|---|---|
public int read() throws IOException | 普通方法 | 返回读取的一个字节 |
public int read(byte b[]) throws IOException | 普通方法 | 将内容读取到字节数组,并返回读入的个数。 |
public int available() throws IOException | 普通方法 | 返回输入文件的大小 |
public void close() throws IOException | 普通方法 | 关闭流 |
read()
返回读取的一个字节。
D:\IOtest\text.txt内:
asdjhjfsdhiasdas123
栗子:
public static void main(String[] args) {
File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
try {
FileInputStream stream = new FileInputStream(file);
int read = stream.read();
System.out.println(read);
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
程序运行结果:
97
//查询ASCII表,97对应的a
如果D:\IOtest\text.txt内为空:
-1
读取内容为空返回-1。
read(byte b[])
将内容读取到字节数组,并返回读入的个数。
D:\IOtest\text.txt内:
asdjhjfsdh iasdas123 12312aa$!@#@
栗子:
public static void main(String[] args) {
File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
try {
FileInputStream stream = new FileInputStream(file);
byte[] bytes = new byte[1024];
int read = stream.read(bytes);
System.out.println("内容个数"+read);
String s = new String(bytes);
System.out.println(s);
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
程序运行结果:
内容个数33
asdjhjfsdh iasdas123 12312aa$!@#@
内容被正确读进字节数组了,但是发现后面好多空格哇!这是因为数组开辟了1024个空间,实际只有33个空间有效,多余了很多空白的空间,该如何避免呢。
available()
返回文件的大小,以字节为单位
至此,修改栗子如下:
public static void main(String[] args) {
File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
try {
FileInputStream stream = new FileInputStream(file);
byte[] bytes = new byte[stream.available()];
int read = stream.read(bytes);
System.out.println("内容个数"+read);
String s = new String(bytes);
System.out.println(s);
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
程序运行结果:
内容个数33
asdjhjfsdh iasdas123 12312aa$!@#@
成功啦!我们避免了空间的浪费!
循环读取
D:\IOtest\text.txt内:
我kjas lkjdlksajask大按实际哦段搜23sjafiijfisahdfo1231 !@#!%TFSDAS
阿斯顿发射点 给!@34125
暗收分撒到 6465465465465?
一次读取一个字节
利用read()读取一个字节为空会返回-1进行循环。
栗子:
public static void main(String[] args) {
File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
try {
FileInputStream stream = new FileInputStream(file);
byte[] bytes = new byte[stream.available()];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = ((byte) stream.read());
}
System.out.println(new String(bytes));
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
程序运行结果:
我kjas lkjdlksajask大按实际哦段搜23sjafiijfisahdfo1231 !@#!%TFSDAS
阿斯顿发射点 给!@34125
暗收分撒到 6465465465465?
一次读取多个字节
利用read(byte b[]),相同的它读取为空也会返回-1。
栗子:
public static void main(String[] args) {
File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
try {
FileInputStream stream = new FileInputStream(file);
byte[] bytes = new byte[1024];
int temp;
while ( (temp=stream.read(bytes))!=-1 ){
System.out.println(new String(bytes,0,temp));
}
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
程序运行结果:
我kjas lkjdlksajask大按实际哦段搜23sjafiijfisahdfo1231 !@#!%TFSDAS
阿斯顿发射点 给!@34125
暗收分撒到 6465465465465?
一次读取1024字节的内容,如果没读取完成继续读取。直至temp=-1。
如果text.txt内容很多就可以体现出这一点。