java中对数据的操作都是通过流进行操作。
种类分类:
字节流: InputSteam,OutputStream
字符流:Reader,Writer
方向分类
输入 InputStream Reader 输入流一定要有源
输出 OutputStream Writer 输出流一定要有目的地
另外这四个类都是抽象类,而且java中所有的流都是这四个流的子类。
File(文件流)
File类是计算机中文件的抽象。这里既然涉及到了文件,那就以我桌面上的一个png图片为例子。
下面我打开编译器写上如下代码,我现在用的编译器是Eclipse,可能有很多的人选用IDEA吧,我也用过一段时间IDEA确实很好用,而且我大天朝网上一搜就破解码满天飞,但是目前刚开始学习,我还是建议大家用Eclipse,等比较熟练了再用IDEA,具体为什么我以后会单独发一篇博文。
import java.io.File;
/**
* @author Hercules
* @version 创建时间:2020年2月1日 下午1:59:26
* 类说明
*/
public class Files {
public static void main(String[] args) {
//定义一个文件这里的双斜线是为了转译用的,有关java的转译请自行百度这里不再做详细解释
File file = new File("C:\\Users\\张帅\\Desktop\\power.png");
//判断是否为文件这里返回一个布尔型
boolean isFile = file.isFile();
//判断是否为目录:
boolean isDirectrory = file.isDirectory()
//输出相关结果
System.out.println(isFile+" "+ isDirectrory);
}
}
因为这里是第一次写这个部分的代码,我们来看一下输出结果:
这里的布尔值表明这个file是文件而不是目录有关其他相关功能的东西我就先写上就不再运行演示了请大家自行编写运行。请注意我所书写的代码我都会自己在编译器中运行成功再写在博客上面,加上新的需要包含的包等我也会写在博客上,所以当你运行出错的时候先找自己的原因。这里请大家仔细阅读注释
String path = file.getPath();//获取路径
path = file.getAbsolutePath();//返回绝对路径
boolean excute = file.canExecute();//是否为可执行文件
boolean read = file.canRead();//是否可读
boolean write = file.canWrite();//是否可写
try {
//创建一个空的新文件,这里一般用作判断比如你new了一个File但是却没有这个文件名,再执行file.createNewFile()
//就会在指定目录下创建一个同名文件。但是这里会抛出一个异常这个东西我们先记住,以后我会给大家解释
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
file.delete();//删除
file.deleteOnExit();//程序退出的时候删除
file.equals(new File(""));//判断文件是否相同
file.exists();//判断是否存在
file.getFreeSpace();//获取空余的磁盘空间大小
file.getName();//获取文件名字
file.getParent();//获取文件所在目录的路径
file.getTotalSpace();//磁盘总的大小
file.isHidden();//是否为隐藏文件
file.lastModified();//最后一次修改的时间
file.length();//文件大小
file.list();//文件夹里面的文件名
file.listFiles();//文件夹里面的文件的file对象
file.mkdir();//创建单级目录 /DeskTop/a
file.mkdirs();//创建多级目录 /DeskTop/a/b
file.renameTo(new File(""));//重命名
//File.separator;//分隔符
File.listRoots();//盘符
文件字节流
FileInputStream FileOutputStream
选择是输入还是输出角度是从内存的角度看
这里的理解就是从硬盘读取到内存中就是输入,从内存写到硬盘中就是输出
这里我读了一个自己的文件大家可以读一个自己定义的文件试试看
InputStream inputStream = null;
OutputStream outputStream = null;
try {
File file = new File("C:\\Users\\HASEE\\Desktop\\22.jpg");
inputStream = new FileInputStream(file);
outputStream = new FileOutputStream("C:\\Users\\HASEE\\Desktop\\33.jpg");
// int s = inputStream.read();//调用一次读取一个字节 读取完成以后返回-1
byte [] bytes = new byte[1024];//顶一个byte的数组
int len = 0;
// int s = inputStream.read(bytes);//会将读取的数据放入数组,读取完成以后返回-1这里就是每次读取1024个字节
while((len = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);//输出
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
上面代码还有一个问题就是
int s = inputStream.read();//调用一次读取一个字节 读取完成以后返回-1
大家先看这行代码调用一次读取一个字节,然后这个字节的数据就在s里面。不过这里的问题就是一次读一个字节,不过现在来说数据量特别庞大的今天,我们一般都是读几个G,如果一次一个字节,那么效率就很低下了,所以我们一般不会用这个东西的。
那我们用什么呢?我们一般用如下代码:
byte [] bytes = new byte[1024];//顶一个byte的数组
int s = inputStream.read(bytes);//会将读取的数据放入数组,读取完成以后返回-1这里就是每次读取1024个字节
这里先定义了一个byte型的数组,我们一次就读1024个字节,那相比上面就快了1023倍(这里是大概的数量,还请不要计较)
不过这里还会有一个问题就是能不能再写的大一点?那效率不就更高了吗?
肯定是数组里面那个数组越大读取数据就越快,这句话是肯定没有问题的。不过大家想过没有
比如说这个文件有8个G,我们可能有些大佬的机器可以有16个G甚至32个G的内存,但是像我这种内存只有4个G的小霸王,一次读8个G,那我的内存不就崩了吗,那还怎么完成这个操作?
所以我们这里选择大小要根据实际情况,既要考虑机器配置,又要保证效率,这就是所谓的平衡点。
这里知识点很多一定要仔细看下面
while((len = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);//输出
}
首先outputStream和inputStream是一样的你操作一次只是读或者写了一次你所规定的数组的数量而不是全部的整个文件,当然了这里这个循环是把"22.jpg"里面的东西复制到"33.jpg",所以这里用一个len变量来操作读完整个文件,但是这里又有一个问题了,就是如果我们读取到最后而那么一次不够1024个,比方说我们这次只剩余了500字节,那么如果我们硬要把500以后的524个字节写入33.jpg那么肯可能造成文件损坏
这里的len当没有读完这个文件的时候,返回的就是读取的长度。
所以outputStream.write(bytes, 0, len)这个该方法里面前面一个参数是我们自己定义的数组,有效的是从0到len的元素。
异常问题
在这里涉及到了大量的try catch语句,这里是捕获异常用的就像我在前面好几篇博客说的,我后面会单开板块系统的介绍下异常。
关流问题
注意“流”用完了一定要记得关;
finally {
if(outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
对于关闭流来说先开的流后关,后开的流先关切记
下面还有最后一个知识点请大家耐心些看完
如果在创建输出流的时候,带了一个boolean类型参数,如果为false时,就在原文件的基础上追加,如果为false或者不带这个参数则为覆盖
outputStream = new FileOutputStream("C:\\Users\\HASEE\\Desktop\\33.jpg",true);