IO流的使用
IO流的使用
IO流的定义
流是一种抽象概念
,它代表了数据的无结构化
传递。按照流的方式进行输入输出,数据被当成无结构的字节序
或字符序列
。从流中取得数据的操作称为提取操作,而向流中添加数据的操作称为插入操作。用来进行输入
和输出
操作的流就称为IO流。换句话说,IO流就是以流的方式
进行输入
和输出
。
IO流的类型
类型 | 输入流 | 输出流 | 作用范围 |
---|---|---|---|
字节流 | InputStream | OutputStream | 主要用来处理字节或二进制对象 |
字符流 | Reader | Writer | 主要用来处理字符或字符串 |
IO流的具体使用
字节流
- 读
- 循环的方式读
- 写
- 用IO流实现拷贝图片(普通)
- 用IO流实现拷贝图片(升级版)
字符流
- 读
- 写
- 拷贝
- 按行读
字节流部分
读:
private static void demo1() throws IOException {
FileInputStream fils = new FileInputStream("/Users/dllo/IdeaProjects/JavaLesson12/src/lanou/test.txt");
int x = fils.read();
System.out.println("x="+x);
int y= fils.read();
System.out.println("y"+y);
fils.close();
}
目标文件
确保读取的目标文件的地址正确,每运行一次会读取一个字节,所以输出的结果为x=97,y=98.
有人会问为什么输出的不是x=a,y=b?详情请参阅下方
注意事项
- 一定确保读取的目标文件的地址正确,否则找不到目标文件无法读出
- 每运行一次会读取一个字节,就会向后走一个字节
- 当全部内容读完,没有内容时返回-1
- 使用完要关闭流:fils.close();
- 最后调用执行方法
public static void main(String[] args) throws IOException {
demo1();
}
循环的方式读:
private static void demo2() throws IOException {
FileInputStream fils = new FileInputStream("/Users/dllo/IdeaProjects/JavaLesson12/src/lanou/test.txt");
int x = 0;
while ((x = fils.read()) != -1) {
System.out.println(x);
}
fils.close();
}
这样会按字节循环输出文件的全部数据
写:
public static void demo3() throws IOException {
FileOutputStream fos = new FileOutputStream("/Users/dllo/IdeaProjects/JavaLesson12/src/lanou/new.txt", true);
fos.write(97);
fos.write(98);
fos.write(99);
fos.write(100);
fos.close();
}
结果会在对应文件中写入”abcd”
注意事项
- 若该地址下没有对应文件,则新建文件并写入
- 若该地址下有对应的文件,会覆盖掉原有内容写入
- 若不想抹掉原有内容,而是在尾部追加内容,需要在地址后添加第二个参数true
拷贝图片(普通版):
以图片为例,文本文件和多媒体文件等文件都可实现拷贝功能
public static void demo4() throws IOException {
FileInputStream fis = new FileInputStream("/Users/dllo/Desktop/girl.jpg");
FileOutputStream fos = new FileOutputStream("/Users/dllo/Desktop/girlNew.jpg");
int x = 0;
while ((x = fis.read()) != -1) {
fos.write(x);
}
fis.close();
fos.close();
}
根据第一条地址读取原有已存在的文件girl.jpg,第二条地址可以指向任何位置,执行操作后会在设定的位置中拷贝出新文件girlNew.jpg,实现拷贝的功能.
拷贝图片(升级版):
上面的普通版拷贝,当要拷贝的文件很大时,内存没有足够空间容下缓存数组,会有内存溢出的隐患
所以上代码:
public static void demo6() throws IOException {
FileInputStream fis = new FileInputStream("/Users/dllo/Desktop/whzg.mp3");
FileOutputStream fos = new FileOutputStream("/Users/dllo/Desktop/whzgNew.mp3");
//不阻塞情况下,能读取的最大长度
int len = fis.available();
//创建鸡蛋篮子
byte[] bytes = new byte[len];
//一次性读入内容,全部装进bytes数组
fis.read(bytes);
//一次性写出内容,将bytes数组全部写出
fos.write(bytes);
fis.close();
fos.close();
}
为了防止内存溢出,我们在要计算能够读取的最大长度,根据长度建立相应大小的数组,我们知道数组的大小是由自己设定的,而不像集合一样会随着存入的数据而变化,所以我们成这个数组为装鸡蛋的篮子,读取的字节为鸡蛋,这样更加形象,读取的时候把数组的数据全部读出就好了,最后记得关闭流.
字符流部分:
读:
public static void demo10() throws IOException {
FileReader fr = new FileReader("/Users/dllo/IdeaProjects/JavaLesson12/src/lanou/test.txt");
int x = 0;
while ((x = fr.read()) != -1) {
System.out.println((char) x);
}
fr.close();
}
字符流读取的结果是循环读取了文件中的所有字符”abcde”
写:
public static void demo11() throws IOException {
FileWriter fw = new FileWriter("/Users/dllo/IdeaProjects/JavaLesson12/src/lanou/test.txt");
fw.write("苍老师");
fw.close();
}
由于我没有在写的地址后添加参数true,默认为false,覆盖了之前的内容,所以目标文件被覆盖写入了”苍老师”.
拷贝:
public static void demo12() throws IOException {
//自带缓冲区的拷贝
FileReader fr = new FileReader("/Users/dllo/IdeaProjects/JavaLesson12/src/lanou/test.txt");
FileWriter fw = new FileWriter("/Users/dllo/IdeaProjects/JavaLesson12/src/lanou/test.txt");
//包装神器菜篮子
BufferedReader br = new BufferedReader(fr);
BufferedWriter bw = new BufferedWriter(fw);
int x = 0;
while ((x = br.read()) != -1) {
bw.write(x);
}
br.close();
bw.close();
}
我们采用系统自带的缓存,用菜篮子包装一下,装入缓存数组中,同样也是循环遍历一下,close()方法自带刷新功能,所以无需用flush()方法刷新数组再关闭流.
注意事项
- 字符流不能拷贝非纯文本的文件,因为会将不识别的字符读成乱码
- 不推荐使用字符流拷贝纯文本文件,因为读和写都要多出一步转码的过程
- 只有在直接读出字符内容,或单纯写入时才推荐使用
按行读:
public static void demo113() throws IOException {
FileReader fr = new FileReader("/Users/dllo/IdeaProjects/JavaLesson12/src/lanou/test.txt");
BufferedReader br = new BufferedReader(fr);
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
}
目标文件
可以看出目标文件中有三行文字,执行操作后会读出这三行数据,用到的方法就是readLine()
方法.
总结
以上就是JAVA中IO流的简单操作,写的较为详细,我觉得能够帮助刚接触JAVA和初学JAVA的人,同时本人也能复习一遍.