本章File内容知识主要来自B站孙探老师的讲解外加一点点个人的理解,传送门-biu
IO流
概述
- 流是一种抽象概念,它代表了数据的无结构化传递。按照流的方式进行输入输出,数据被当成无结构的字节序或字符序列。从流中取得数据的操作称为提取操作,而向流中添加数据的操作称为插入操作。用来进行输入输出操作的流就称为IO流。换句话说,
IO流就是以流的方式进行输入输出
------百度百科 - 图1:
IO流是什么?
仔细看过上图中的朋友们一定对Io流有了略微的一点认知!
IO:Input输入流和Output输出流
- 那么输入输出流又是什么意思?
- 就是Java程序进行数据传输的管道
- 流 就是管道的意思!
从图一可知,Io流主要是用来传输
文件
的(也就是文件的上传下载 可能不太恰当)
文件(类 File)又是什么呢?
概述:
- 在计算机中所有数据都是以文件的格式存储的
- 在Java中认为文件是一个对象
- Java认为所有的东西都是对象
构造方法:
- File (String Pathname) :根据一个路径得到File对象
- File (String parent,String child):根据一个目录和一个子文件/目录得到File对象
- File(File parent,String child):根据一个父File对象和一个子文件/目录得到File对象
- 实例:
public class FileTest { //File类的构造方法: public static void main(String[] args) { //第一种 File file1 = new File("D:\\123\\123.text"); //第二种 File file2 = new File("D:\\123","123.text"); //第三种 File file = new File("D:\\123"); File file3 = new File(file,"123.txt"); } }
成员方法:
创建功能,删除功能,重命名功能,判断功能,获取功能
创建功能
- public boolean createNewFile():创建文件,如果存在这样的文件,就不创建了
- public boolean mkdir ( ):创建文件夹,如果存在这样的文件夹,就不创建了(make dirctory)
- public boolean mkdirs () :创建文件夹,如果父文件夹不存在,会帮你创建出来
- 实例:
public class FileTest2 { //File类的构造方法: public static void main(String[] args) throws Exception { /** * public boolean createNewFile():创建文件,如果存在这样的文件,就不创建了 */ File file = new File("D:\\123\\b.txt"); boolean b = file.createNewFile(); System.out.println(b); //如果没有指明创建路径,那么该文件是在项目路径下创建的! File file2 = new File("b.txt"); file2.createNewFile(); /** * public boolean mkdir ( ):创建文件夹,如果存在这样的文件夹,就不创建了(make dirctory) * 该方法不能创建多层文件夹 */ File file3 = new File("D:\\123\\123456"); boolean mkdir = file3.mkdir(); System.out.println(mkdir); /** * public boolean mkdirs () :创建文件夹,如果父文件夹不存在,会帮你创建出来 * 该方法可以创建多层文件夹 */ File file4 = new File("D:\\123\\123\\123"); boolean mkdirs = file4.mkdirs(); System.out.println(mkdirs); } }
删除功能
- public boolean delete():可以用来删除文件和文件夹
- delete删除的文件夹下面不能有文件或文件夹!!!
实例:public class FileTest3 { public static void main(String[] args) throws Exception { //注意:delete删除的文件夹下面不能有文件或文件夹 File file = new File("D:\\123"); File file2 = new File("D:\\123.txt"); file.delete(); file2.delete(); } }
重命名功能
- public boolean renameTo(File dest):可以给文件或者文件夹改名字
- 如果File改名的路径是在同一路径下,就是重命名
- 如果File改名的路径不是在同一路径下,就是重命名并移动!
实例:public class FileTest4 { public static void main(String[] args) throws Exception { //把"D:\123"文件夹的名字改为"D:\12345" File file = new File("D:\\123"); File file2 = new File("D:\\12345"); file.renameTo(file2); //把"D:\123.txt"的的名字改为"12345.txt" File file3 = new File("D:\\123.txt"); file3.renameTo(new File("D:\\12345.txt")); //改名并移动 File file5 = new File("D:\\12345.txt"); file5.renameTo(new File("D:\\12345\\123456.txt")); } }
判断功能
- public boolean isDirectory():判断是否是目录
- public boolean isFile():判断是否是文件
- public boolean exists ()∶判断是否存在
- public boolean canRead():判断是否可读
- public boolean canwrite():判断是否可写
- public boolean isHidden ():判断是否隐藏
实例:public class FileTest5 { public static void main(String[] args) throws Exception { //判断是否是文件 File file1 = new File("D:\\12345"); boolean file = file1.isFile(); System.out.println(file); //判断是否是文件夹 File file2 = new File("D:\\12345\\123456.txt"); boolean directory = file2.isDirectory(); System.out.println(directory); //判断为文件是否存在 boolean exists = file2.exists(); System.out.println(exists); //判断是否可读 boolean b = file2.canRead(); System.out.println(b); //判断是否可写 boolean b1 = file2.canWrite(); System.out.println(b1); //判断是否隐藏 boolean hidden = file2.isHidden(); System.out.println(hidden); } }
获取功能
- public string getAbsolutePath ():获取绝对路径
- public string getPath():获取相对路径
- public string getName () :获取名称
- public long length ():获取长度。字节数
- public long lastModified():获取最后一次的修改时间,毫秒值
相对路径:从当前文件/文件夹所在的位置开始,一直到你想去的某个文件/文件夹下就叫做相对路径。
绝对路径:文件在系统磁盘上的路径,从盘符开始,一直到文件/文件夹的名称就叫做绝对路径。
- public string[] list():获取指定目录下的所有文件或者文件夹的名称数组
- public File[] listFiles():获取指定目录下的所有文件或者文件夹的File数组
实例:
public class FileTest6 {
public static void main(String[] args) throws Exception {
File file = new File("D:\\12345\\123456.txt");
//获取绝对路径
String absolutePath = file.getAbsolutePath();
System.out.println(absolutePath);
//获取相对路径
String path = file.getPath();
System.out.println(path);
//获取名称
String name = file.getName();
System.out.println(name);
//获取长度。字节数
long length = file.length();
System.out.println(length);
//获取最后一次的修改时间 精确到毫秒
long l = file.lastModified();
Date date = new Date(l);
System.out.println(date.toLocaleString());
//获取指定目录下的所有文件或者文件夹的名称数组
File files = new File("D:\\12345");
String[] list = files.list();
for (String s : list) {
System.out.println(s);
}
//获取指定目录下的所有文件或者文件夹的File数组
File[] files1 = files.listFiles();
for (File fil2:files1) {
System.out.println(fil2.getAbsolutePath());
}
}
}
File说完了再回到IO流
IO流的分类:
根据流向可以分为:(不管是输入流还是输出流都是根据你当前的程序而言的)
- 输入流:(读read) input
- 输出流:(写write) output
根据传输的内容分为:
-
字节数据: 图片,视频,音频
- 字节输入流:InputStream
- 字节输出流:OutputStream
-
字符数据:abcd
- 字符输入流:Reader
- 字符输出流:Writer
-
不管是字符流还是字节流,底层流动的都是字节!
图解:
这里主要来看InputStream和OutputStream
字节流InputStream
概念
- InputStream是所有字节输入流的顶层父类,是一个抽象类。
如果要用,需要使用子类。(FileInputStream)
- FileInputStream流被称为文件字节输入流,意思指对文件数据以字节的形式进行读取操作如读取图片视频等
换句话说呢就是不用管 InputStream 是干嘛的,只需要知道他的子类FileInputStream很有用就行,而他的子类怎么用呢,看下面 :
FileInputStream构造方法:
- FileInputStream(File file): 传递一个File类型的文件
- FileInputStream(String name): 传递一个String类型的文件路径
推荐使用下面这种方法:
FileInputStream inputStream = new FileInputStream(“a.txt”);
- public FileOutputStream(File file, boolean append)
- public FileOutputStream(String name, boolean append)
创建一个FileinputStream对象,并绑定一个数据源文件
如果文件不存在,则会抛出异常(File Not Found Exception)
构造方法实例:
-
public class FileInputStreamTest1 { public static void main(String[] args) throws FileNotFoundException { //使用file对象创建流对象 File file = new File("D:\\12345\\123.mp4"); FileInputStream fileInputStream = new FileInputStream(file); //使用文件名称创建流对象 FileInputStream fileInputStreams = new FileInputStream("D:\\12345\\123.mp4"); } }
FileInputStream读取字节数据:
- 1.读取字节:read()方法,每次可以读取一个字节的数据,提升为int类型,读取到文件末尾,返回-1
- 实例:
public class FileInputStreamTest2 { public static void main(String[] args) throws IOException { //使用read()方法,读取一个字节的数据 //使用文件名称创建流对象 FileInputStream fileInputStream = new FileInputStream("D:\\12345\\123456.txt"); int read = fileInputStream.read(); System.out.println((char)read); read = fileInputStream.read(); System.out.println((char)read); read = fileInputStream.read(); System.out.println((char)read); read = fileInputStream.read(); System.out.println((char)read);//已经读不到数据了 System.out.println(read);//读取到最后没有信息了会返回-1 fileInputStream.close();//关闭资源 } }
- 实例:
- 2.使用字节数组读取:***read(byte[] b)***,每次读取b的长度个字节到数组中,返回读取到的有效字节个数,读取到末尾时,返回-1
- 实例:
public class FileInputStreamTest3 { public static void main(String[] args) throws IOException { //使用read(byte[] b)方法,读取数据 //使用文件名称创建流对象 FileInputStream fileInputStream = new FileInputStream("D:\\12345\\123456.txt"); int len; byte[] b = new byte[2]; while ((len=fileInputStream.read(b))!=-1){ System.out.println(new String(b)); } fileInputStream.close();//关闭资源 } }
- 实例:
字节流OutputStream
概念
- OutputStream是所有字节输出流的顶层父类,是一个抽象类,如果要用,需要使用子类。 常用的子类
FileOutputStream 文件输出流
- 字节输出流的基本共性功能方法:
- public void close() :关闭此输出流并释放与此流相关联的任何系统资源。
- public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。
- public void write(byte[] b):将 b.length个字节从指定的字节数组写入此输出流。
- public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。 也就是说从off个字节数开始读取一直到len个字节结束
- public abstract void write(int b) :将指定的字节输出流。
以上五个方法则是字节输出流都具有的方法,由父类OutputStream定义提供,子类都会共享以上方法
FileOutputStream构造方法
- FileOutputStream(File file): 传递File类型的文件。
- FileOutputStream(String name): 传递一个字符串类型的文件路径。
推荐下面这种写法
FileOutputStream outputStream = new FileOutputStream(“abc.txt”);
注意:创建输出流对象的时候,系统会自动去对应位置创建对应文件,而创建输出流对象的时候,文件不存在则会报FileNotFoundException异常,也就是系统找不到指定的文件异常。
- 当你创建一个流对象时,必须直接或者间接传入一个文件路径。在该路径下,如果没有这个文件,会创建该文件。如果有这个文件,会清空这个文件的数据。
实例:public class FileOutputStreamTest1 { public static void main(String[] args) throws FileNotFoundException { //使用FIle对象创建流对象 File file = new File("D:\\12345\\123456.txt"); FileOutputStream fileOutputStream = new FileOutputStream(file); //使用文件名创建流对象 FileOutputStream fileOutputStream2 = new FileOutputStream("D:\\12345\\123456.txt"); } }
FileOutputStream导出字节数据
使用FileOutputStream写出字节数据主要通过Write方法,而write方法分如下三种:
- public void write(int b)
- public void write(byte[] b)
- public void write(byte[] b,int off,int len) //从
off
索引开始,len
个字节
1.写出字节,write(int b) 方法,每次可以写出一个字节数据
实例:
class FileOutputStreamTest2 {
public static void main(String[] args) throws IOException {
//使用FIle对象创建流对象
FileOutputStream fos = new FileOutputStream("D:\\12345\\123456.txt");
//写出数据
fos.write(97);
fos.write(98);
fos.write(99);
fos.close();
}
}
虽然参数为int类型四个字节,但是只会保留一个字节的信息写出。
流操作完毕后,必须释放系统资源,调用close方法,千万记得。
2.写出字节数组 ,write(byte[] b),每次可以写出数组中的数据
实例:
class FileOutputStreamTest3 {
public static void main(String[] args) throws IOException {
//使用FIle对象创建流对象
FileOutputStream fos = new FileOutputStream("D:\\12345\\123456.txt");
//字符串转换为数组
byte[] b = "一给我里GIAO".getBytes();
//写出字节组数据
fos.write(b);
//关闭资源
fos.close();
}
}
3.写出指定长度字节数组:write(byte[] b, int off, int len) ,每次写出从off索引开始,len个字节
实例:
class FileOutputStreamTest4 {
public static void main(String[] args) throws IOException {
//使用FIle对象创建流对象
FileOutputStream fos = new FileOutputStream("D:\\12345\\123456.txt");
//字符串转换为数组
byte[] b = "qwertyuiop".getBytes();
//写出字节组数据
fos.write(b,2,2);
//关闭资源
fos.close();
}
}
字节流在这就告一段落了,更深一点的方法也不说了(我也不会,还在学 hhhh~),再说一说字符流:
什么时候用字符流,什么时候用字节流呢?
答案很简单:
如果处理纯文本数据的情况,优先考虑字符流!而处理图片,音频,视频...使用字节流比较好
字符流(Reader,Writer)
Reader字符输入流
- java.io.Reader抽象类是字符输入流的所有类的超类(父类),可以读取字符信息到内存中。它定义了字符输入流的基本共性功能方法。
FileReader类
- java.io.FileReader类是读取字符文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。
构造方法
- FileReader(File file): 创建一个新的 FileReader ,给定要读取的File对象。
- FileReader(String fileName): 创建一个新的 FileReader ,给定要读取的文件的字符串名称。
实例:
public class ReaderTest1 {
public static void main(String[] args) throws FileNotFoundException {
//使用file对象创建流对象
File file = new File("D:\\12345\\123456.txt");
FileReader fileReader = new FileReader(file);
//使用文件名称创建流对象
FileReader fileReader1 = new FileReader("D:\\12345\\123456.txt");
}
}
FileReader读取字符数据
- 读取字符:read方法,每次可以读取一个字符的数据,提升为int类型,读取到文件末尾,返回-1,循环读取
实例:
public class ReaderTest2 {
public static void main(String[] args) throws IOException {
//使用文件名称创建流对象
FileReader file = new FileReader("D:\\12345\\123456.txt");
// 定义变量,保存数据
int b;
// 循环读取
while ((b = file.read())!=-1) {
System.out.println((char)b);
}
// 关闭资源
file.close();
}
}
Writer字符输出流
- java.io.Writer抽象类是字符输出流的所有类的超类(父类),将指定的字符信息写出到目的地。它同样定义了字符输出流的基本共性功能方法。
字符输出流的基本共性功能方法:
- void write(int c) 写入单个字符。
- void write(char[] cbuf)写入字符数组。
- abstract void write(char[] cbuf, int off, int len)写入字符数组的某一部分,off数组的开始索引,len写的字符个数。
- void write(String str)写入字符串。
- void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数。
- void flush()刷新该流的缓冲。
- void close() 关闭此流,但要先刷新它。
FileWriter类
- java.io.FileWriter类是写出字符到文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。
构造方法
- FileWriter(File file): 创建一个新的 FileWriter,给定要读取的File对象。
- FileWriter(String fileName): 创建一个新的 FileWriter,给定要读取的文件的名称。
实例:
public class WriterTest1 {
public static void main(String[] args) throws IOException {
//使用file对象创建流对象
File file = new File("D:\\12345\\123456.txt");
FileWriter fileWriter = new FileWriter(file);
//使用文件名称创建流对象
FileWriter fileWriter2 = new FileWriter("D:\\12345\\123456.txt");
}
}
写出数据
- 写出字符:write(int b) 方法,每次可以写出一个字符数据
public class WriterTest2 { public static void main(String[] args) throws IOException { //使用文件名称创建流对象 FileWriter fw = new FileWriter("D:\\12345\\123456.txt"); //写出数据 fw.write(97); //写出第一个字符 fw.write('b');//写出第二个字符 fw.write('c');//写出第三个字符 //关闭资源时,与FileOutputStream不同。 如果不关闭,数据只是保存到缓冲区,并未保存到文件 fw.close(); } }
关闭资源时,与FileOutputStream不同。 如果不关闭,数据只是保存到缓冲区,并未保存到文件
关闭close和刷新flush
- 因为内置缓冲区的原因,如果不关闭输出流,无法写出字符到文件中。但是关闭的流对象,是无法继续写出数据的。如果我们既想写出数据,又想继续使用流,就需要flush 方法了。
- flush :刷新缓冲区,流对象可以继续使用。
- close:先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。
实例:public class WriterTest3 { public static void main(String[] args) throws IOException { //源 也就是输入流【读取流】 读取a.txt文件 FileReader fr=new FileReader("D:\\12345\\123456.txt"); //必须要存在123456.txt文件,否则报FileNotFoundException异常 //目的地 也就是输出流 FileWriter fw=new FileWriter("D:\\12345\\123.txt"); //系统会自动创建123.txt,因为它是输出流! int len; while((len=fr.read())!=-1){ fw.write(len); } fr.close(); fw.flush(); fw.close(); } }
IO流中的压缩
- 压缩压缩,肯定是将数据压缩成压缩包,这就是输出流.因为不确定数据是什么类型,纯文本啊,还是音视频之类的.所以建议直接就写成字节流
- 实例:
public class ZipTest1 { public static void main(String[] args) throws Exception { //使用文件名称创建流对象 FileOutputStream fos = new FileOutputStream("D:\\12345\\123456789.zip") ; ZipOutputStream zos= new ZipOutputStream(fos) ; //写入一个条目,我们需要给这个条目起个名字,相当于起一个文件名称 zos.putNextEntry(new ZipEntry("qwe")); //往这个条目中写入一定的数据 zos.write("QQQ".getBytes()); //关闭条目 zos.closeEntry(); zos.putNextEntry(new ZipEntry("asd")); zos.write("WWW".getBytes()); zos.closeEntry(); zos.putNextEntry(new ZipEntry("zxc")); zos.write("EEE".getBytes()); zos.closeEntry(); zos.close(); } }
- 解压!
public class UnZipTest { public static void main(String[] args) throws Exception { FileInputStream fis = new FileInputStream("D:\\12345\\123456789.zip"); ZipInputStream zis = new ZipInputStream(fis); ZipEntry entry = null ; byte[] buf = new byte[1024] ; int len = 0 ; //此处我们需要判断是否zis流中存在条目,你可以理解为是否存在文件内容 while((entry = zis.getNextEntry()) != null){ //此处我们获取条目名称 String name = entry.getName(); System.out.println(name); //我们将每一个条目进行解压,我们需要指定一个输出路径 FileOutputStream fos = new FileOutputStream("D:\\12345\\"+ name) ; while((len = zis.read(buf)) != -1){ fos.write(buf , 0 , len); } fos.close(); } zis.close(); fis.close(); } }
IO流的转换
编码
- InputStreamReader 继承于Reader,是字节流通向字符流的桥梁,可以把字节流按照指定编码 解码 成字符流。
实例:
public class InputStreamReaderTest {
public static void main(String[] args) throws IOException {
File file = new File("D:\\12345\\123456.txt");
String haha="i like you too";
//1.创建通道
FileOutputStream fileOutputStream=new FileOutputStream(file);
//2.创建转换流
OutputStreamWriter writer=new OutputStreamWriter(fileOutputStream,"UTF-8");
//3.写入数据
writer.write(haha);
//4.刷新缓冲区
writer.flush();
//5.关闭通道
writer.close();
//6.关闭转换流
fileOutputStream.close();
}
}
解码
- InputStreamReader 继承于Reader,是字节流通向字符流的桥梁,可以把字节流按照指定编码 解码 成字符流。
实例:
public class InputStreamWriter {
public static void main(String[] args) throws IOException {
File file = new File("D:\\12345\\123456.txt");
FileInputStream fileInputStream = new FileInputStream(file);
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"UTF-8");
char[] cbuf=new char[2];
int len;
StringBuilder sb=new StringBuilder();
while((len=inputStreamReader.read(cbuf))!=-1){
sb.append(cbuf, 0, len);
}
System.out.println(sb.toString());
}
}
本节完
文中借鉴内容摘抄自:
https://www.cnblogs.com/yichunguo/p/11775270.html
https://www.cnblogs.com/luojack/p/10823365.html