IO流,即用来操作文件内容的技术。所以再讲IO流之前,要先认识一下File类。
一、File文件类
1、File类介绍
File是Java用来表示文件/文件夹(目录),可以通过File类在程序中操作硬盘上的文件/文件夹。
File类只是用来表示文件/文件夹的信息(大小、名称)等,而不能用来对文件的读写。
注意:
new File():创建出来的文件/文件夹只在内存中,而不在硬盘里。
file.createNewFile():根据file的路径,在硬盘中创建文件。
file.mkdir():根据file的路径,在硬盘中创建文件夹。
file.exsts():判断file对应的路径里是否有指定的文件/文件夹存在。
2、创建文件以及对文件的操作
(1)在指定路径上创建文件(3中方式):
public class Test {
public static void main(String[] args) throws IOException {
//1、默认路径,也就是当前项目下
File file1 = new File("test01.txt");
file1.createNewFile();
//2、包中的文件路径
File file2 = new File("src/test02/test.txt");
file2.createNewFile();
//3、绝对路径
File file3 = new File("D:/test/test.txt");
file3.createNewFile();
//File file3 = new File("D:\\test\\test.txt");
}
}
PS:
使用2、3创建文件对象,路径写错时会报错不存在。
(2)对文件对象的操作
public class Test {
public static void main(String[] args) throws IOException {
//默认路径,也就是当前项目下
File file = new File("test01.txt");
boolean ok = file.createNewFile();
System.out.println(ok);
//1、获取文件名
String fileName = file.getName();
//2、获取该文件的绝对路径
String filePath = file.getAbsolutePath();
//3、获取该文件的相对路径
String path = file.getPath();
//4、获取文件的父目录(在哪个目录下)
String parentPath = file.getParent();
//5、获取文件是否被隐藏
boolean flag = file.isHidden();
//6、获取该文件中的字节数
long len = file.length();
//7、获取该文件最后的修改时间
long tempTime = file.lastModified();
//8、删除文件
boolean flag2 = file.delete();
//9、查看文件是否存在
boolean flag1 = file.exists();
System.out.println("===================");
//固定操作
if(!file.exists()) {//文件不存在
System.out.println("未在指定目录下找到文件名为“test”的文本文件,正在创建");
try {
file.createNewFile();
}catch(IOException e) {
e.printStackTrace();
}
System.out.println("文件创建成功");
}else {//文件存在
System.out.println("找到文件名为“test”的文本文件");
//可以继续继续对文件的操作
}
}
}
3、创建文件夹以及对文件夹的操作
(1)创建文件夹
与创建文件基本类似。
public class Test {
public static void main(String[] args) {
//1、创建单个文件夹
File dir1 = new File("dir");
boolean flag1 = dir1.mkdir();
//2、创建多个文件夹
File dir2 = new File("dir1/dir2/dir3/dir4");
boolean flag2 = dir2.mkdirs();
}
}
(2)对文件夹的操作
public class Test {
public static void main(String[] args) throws IOException {
File dir = new File("dir1/dir2/dir3/dir4");
boolean flag = dir.mkdirs();
//删除文件路径的最后一个文件夹
boolean del =dir.delete();
}
}
在文件夹下创建文件
public class Test {
public static void main(String[] args) throws IOException {
File dir = new File("dir");
dir.mkdir();
File file = new File(dir,"demo.txt");
file.createNewFile();
}
}
(3)遍历文件夹内的内容
public class Test {
public static void main(String[] args) throws IOException {
File dir = new File("E:/");
//获取E盘下所有的文件和文件夹,返回文件数组
File[] fs = dir.listFiles();
//遍历
for(File f:fs) {
if(f.isFile()) {//判断是否为文件
System.out.println(f.getName()+"是文件");
}
if(f.isDirectory()) {//判断是否为文件夹
System.out.println(f.getName()+"是文件夹");
}
}
}
}
二、IO流(水管)
1、IO流概况
(1)定义:
IO流是用来操作文件内容的技术,输入输出都是针对程序来说的。
I(in)输入:向程序中输入数据,一般是从文件中读取内容到程序中。
O(out)输出:程序向外输送数据,一般是将数据写入到文件中。
(2)用途:
读写文件
乱码问题
框架的底层技术使用
文件的上传下载
(3)分类:
按照数据类型:字节流、字符流。
字节流:二进制0101(最小单位),以字节为单位进行。是通用的,任何文件都可以操作。
字符流:操作中文字符方便(用记事本打开没有乱码,可以使用字符流)
按照数据的流向:输入流、输出流。
<1>输入流
字节流:Stream(每次读取一个字节)
InputStream:抽象的类
FileInputStream:文件输入流(是InputStream的子类)
BufferedInputStream:字节缓冲输入流
——————————————————————–
字符流:Reader(每次读取一个字符)
InputStreamReader(可以直接创建对象,子类是 FileReader)
BufferedReader:字符缓冲输入流(每次读取一行)
<2>输出流
字节流:Stream
OutputStream:抽象的类
FileOutputStream:文件输出流(是OutputStream的子类)
BufferedOutputStream:字节缓冲输出流
———————————————————————
字符流:Writer(每次写入一个字符)
OutputStreamWriter(可以直接创建对象,子类是 FileWriter)
BufferedWriter:字符缓冲输出流(每次写入一行)
PrintWriter
注意:
1、字节缓冲流要比字节流效率高。
2、字节缓冲流不能直接操作文件,必须包装字节流,通过字节流访问。(观察字节缓冲流的构造方法)
2、字节输入流与字节输出流
InputStream与OutputStream
OutputStream(程序->外界)
(1)基本框架
package test02;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class Test {
public static void main(String[] args){
File file = new File("test.txt");
OutputStream out = null;
try {
//OutputStream为抽象类,
//所以需要通过其子类FileOutputStream来创建对象
out = new FileOutputStream(file);//相当于打开水管
//是以字节形式去写入文件
out.write('b');//b
out.write(98);//b
System.out.println("写入成功!");//作为提示
} catch (IOException e) {
e.printStackTrace();
}finally {
//如果输出流不为空
if(out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
注意:
1、IOException是IO流中所有异常的父类。
2、FileOutputStream中的文件如果不存在,会自动在对应路径下创建文件。
3、OutputStream是以字节形式写入文件,所以
‘b’->b;48->0;98->b(根据相应的编码规则)
英文占一个字节,中文占2/3个字节(取决于编码方式)。
举例子,感受一个字节一个字节写入:
public class Demo7 {
public static void main(String[] args) {
byte[] bs = "98".getBytes();
System.out.println(Arrays.toString(bs));//[57, 56]
byte[] bs1 = "b".getBytes();//[98]
System.out.println(Arrays.toString(bs1));
}
}
4、操作文件后,一定要关闭流,否则会消耗系统资源。在关闭流之前,可以先判断其是否为空,为空则没有关的必要。
(2)追加or覆盖?
OutputStream out = new FileOutputStream(file,true);
如果第二个参数的位置上是true,则会追加;如果为false,则会覆盖。加入没有写上第二个参数,则默认为false。
(3)String类型要如何写入?
String str = "1234567";
byte[] bs = str.getBytes();//利用getBytes()得到字节数组
out.write(bs);//参数的类型为字节数组
out.write("\n".getBytes());//输出一个空格
小结:
(1)如果想利用字节输出流往文件中写入“1234”、“大王”或者是进行回车,可以利用 str.getBytes() 将它们解析为字节数组,再写入到文件中即可。(参数为byte[ ] bs)
(2)假如直接写入97、98等数字,你们则会根据ASCII码对照表,将对应的字符写入。(参数为int i)
(3)加入以字符的形式写入到文件中,即‘b’,那么在文件中出现的也是b。
InputStream(外界->程序)
(1)基本框架
test.txt文件内的内容:
package test02;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class Test {
public static void main(String[] args){
File file = new File("test.txt");
InputStream in = null;
try {
in = new FileInputStream(file);
System.out.println(in.read());//98
System.out.println(in.read());//98
System.out.println(in.read());//180
System.out.println(in.read());//243
System.out.println(in.read());//205
System.out.println(in.read());//245
System.out.println(in.read());//13
System.out.println(in.read());//10
System.out.println(in.read());//54
System.out.println(in.read());//-1
} catch (IOException e) {
e.printStackTrace();
}finally {
if(in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
注意:
1、在utf-8编码方式下,中文占3个字节数;GBK编码方式下,中文占2个字节数。此处的编码方式为GBK编码方式。
2、文件一旦读取完,就会输出-1(byte类型)作为标志。
3、文件的内容也是一次输出一个字节,根据对应的编码规则进行输出。
4、可以将重复读取的代码替换为:
int b = -1;//定义b是有意义的
while((b = in.read()) != -1) {
System.out.println(b);
}
(2)每次读取一个字节数组
public class Test {
public static void main(String[] args){
File file = new File("test.txt");
InputStream in = null;
try {
in = new FileInputStream(file);
//定义一个字节数组
byte[] bs = new byte[3];
//定义length表示读取到的有效数据的长度
int length = 0;
//in.read(byte[] byte)返回值为读取的有效字节个数,
//一个都没有时,没有就返回-1
while((length = in.read(bs)) != -1) {
//第一种方式:直接输出字节数组
System.out.println(Arrays.toString(bs));
//第二种方式:字节数组转为String,并且输出String类型的数据
String str = new String(bs);
// String str1 = new String(bs,0,length);
System.out.println(str);
// System.out.println(str1);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if(in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
说明:
(1)第二次出现的-48其实是第一次出现的那个-48顺延下来的,因为到-46时,就已经没有内容可以读取了,所以-48就没有被覆盖。
(2)in.read(byte[] byte)返回值为读取的有效字节个数,一个都没有时,没有就返回-1。
(3)在以String类型输出时,如果将代码换为:
in = new FileInputStream(file);
//定义一个字节数组
byte[] bs = new byte[3];
//定义length表示读取到的有效数据的长度
int length = 0;
while((length = in.read(bs)) != -1) {
// String str = new String(bs);
String str1 = new String(bs,0,length);
//主要看最后一行的?不再出现了
// System.out.println(str);
System.out.println(str1);
}
(3)根据文件总的字节长度整体读取
file.length():获取文件的字节长度
in = new FileInputStream(file);
byte[] bs = new byte[(int)file.length()];
in.read(bs);//从文件中读取信息,并将信息存入到字节数组bs中
//将字节数组转换成字符串
String str = new String(bs);
System.out.println(str);
available():可以一次性获取文件的剩余的字节数。
in = new FileInputStream(file);
int num = in.available();
byte[] bs = new byte[num];
in.read(bs);//从文件中读取信息,并将信息存入到字节数组bs中
//将字节数组转换成字符串
String str = new String(bs);
System.out.println(str);
综合:复制粘贴图片
一边读,一边写。
1、一个一个字节的去读写。
2、以字节数组的形式去读写。
如果指定字节数组的长度,可以取1024的整数倍。
注意:
在关流时,遵循原则——先开的后关。
package day20200614;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Homework_1 {
public static void main(String[] args) {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("src/day20200614/timg.jpg");
out = new FileOutputStream("src/day20200614/timg1.jpg");
//定义一个字节数组
byte[] bs = new byte[1024];
//定义每次读取的有效字节长度
int length = 0;
while((length = in.read(bs))!= -1) {
//写入
out.write(bs,0,length);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {//注意关流,应该还要判断out\in是否为空
out.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
总结:
1、InputStream
read(int b);
read(byte[] bs);
read(b, off, len);
2、OutputStream
创建对象,构造方法里面第二个参数用于判断文件是否要追加。
write(int b);
write(byte[] bs);
write(b, off, len);
一般读文件:
write(byte[] bs,0,length);
3、String<—>字节数组
String—>字节数组
str.getBytes();
字节数组—>String
new String(byte[] bs);
3、字节缓冲输入、输出流
BufferedInputStream和BufferedOutpotStream
基本上与字节输入、输出流相似,创建对象有所不同。
(相当于自己再复习了一遍操作)
BufferedInputStream
举例:
文件内容:
public class Demo01 {
public static void main(String[] args) {
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream
(new FileInputStream("test.txt"));
//以字节数组进行读取
byte[] bs = new byte[bis.available()];
int length = -1;
//开始整体读取
length = bis.read(bs);
//将字节数组转为字符串输出
String str = new String(bs);
System.out.println(str);
} catch (IOException e) {
e.printStackTrace();
}finally {
if(bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
控制台显示:
对比另外一种方式:
BufferedInputStream bis = new BufferedInputStream
(new FileInputStream("test.txt"));
//以字节数组进行读取(随便定义的长度)
byte[] bs = new byte[8];
int length = -1;
//开始读取
while((length = bis.read(bs))!=-1) {
//将字节数组转为字符串输出
String str = new String(bs);
System.out.println(str);
}
控制台显示:
PS: 这种方式就会产生顺延的现象。
BufferedOutpotStream
public class Demo01 {
public static void main(String[] args) throws IOException {
BufferedOutputStream bos = new BufferedOutputStream
(new FileOutputStream("test.txt"));
//写入内容
String str = "时间有泪";
byte[] bs = str.getBytes();
bos.write(bs);
System.out.println("写入成功");
bos.close();
//这里如果没有写的话,在test文件中是没有显示"时间有泪"
}
}
综合:复制粘贴文件
package day2020061401;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Homework_1 {
public static void main(String[] args) {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
long time1 = 0;
long time2 = 0;
try {
bis = new BufferedInputStream
(new FileInputStream("src/day2020061401/xiaoshuo.txt"));
bos = new BufferedOutputStream
(new FileOutputStream("src/day2020061401/xiaoshuo1.txt"));
time1 = System.currentTimeMillis();
//开始读取
byte[] bs = new byte[1024];
int length = -1;
while((length = bis.read(bs)) != -1) {//读到的内容放在了bs中
bos.write(bs,0,length);
}
time2 = System.currentTimeMillis();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {//应该判断bos\bis是否为空
bos.close();
bis.close();
System.out.println((time2-time1));//测试时间
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
以上就是字节输入输出流的全部内容。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/16899.html