IO流概述
之前的程序,数据都是在内存中,一旦程序运行结束,数据就没有了。IO流的出现就是把运算完的数据都保存下来,下次运行程序时还能使用。把数据持久化的存储,就是把内存中的数据存储到内存以外的其他持久化的设备(光盘、硬盘、U盘等)上。
当需要把内存中的数据存储到持久化设备上这个动作称为输出(写)Output操作。
当把持久设备上的数据读取到内存中的这个动作称为输入(读)Input操作。
因此我们把这种输入和输出动作称为IO操作。
File类
File类有两个静态成员变量和三个构造方法
1、pathSeparator 与系统有关的路径分隔符 ;
2、separator 与系统有关的默认名称分隔符 \
构造方法:1、File(String pathname)
2、File(File parent,String child)
3、File(String parent,String child)
package com.oracle.demo1;
import java.io.File;
public class FileDemo {
public static void main(String[] args) {
// 与系统有关的路径分隔符 ;
String pathseparator = File.pathSeparator;
System.out.println(pathseparator);
// 与系统有关的默认名称分隔符 \
String separator = File.separator;
System.out.println(separator);
// 构造方法一 File(String pathname)
File f = new File("d:\\eclipsework1");
System.out.println(f);
// 构造方法二 File(File parent,String child)
File parent = new File("d:");
File f2 = new File(parent, "eclipsework1");
System.out.println(f2);
// 构造方法三 File(String parent, String child)
File f3 = new File("d:", "eclipsework1");
System.out.println(f3);
}
}
File类常用的方法
1、创建文件
boolean | createNewFile() |
2、创建文件夹
boolean | mkdir() 单级目录 |
boolean | mkdirs() 多级目录 |
3、删除
boolean | delete() |
4、判断此文件是否存在
boolean | exists() |
5、判断此文件是否是文件夹
boolean | isDirectory() |
6、获取绝对路径
String | getAbsolutePath() |
7、获取文件名
String | getName() |
8、获取路径
String | getPath() |
9、长度
long | length() |
package com.oracle.demo1;
import java.io.File;
import java.io.IOException;
public class FileDemo2 {
public static void main(String[] args) throws IOException {
// 创建文件
// File f = new File("d:\\eclipse\\demo.java");
// boolean b = f.createNewFile();
// System.out.println(b);
// 创建文件夹用mkdir()(多级目录用mkdirs())
// File f2 = new File("d:\\eclipse\\test\\test2");
// boolean b = f2.mkdirs();
// System.out.println(b);
// 删除(删除的文件不走回收站,直接从硬盘上删除)
// File f2 = new File("d:\\eclipse\\test\\test2");
// boolean b = f2.delete();
// System.out.println(b);
// 判断路径是否存在
// File f = new File("d:\\eclipse");
// boolean b = f.exists();
// System.out.println(b);
// 文件File、目录(文件夹)directory、路径path
// boolean isDirectory() 判断这个文件对象是否是文件夹
//System.out.println(f.isDirectory());
//文件的获取
//绝对路径
File f=new File("d:\\eclipsework1");
//相对路径
File f1=new File("src");
System.out.println(f.getAbsolutePath());
System.out.println(f.getName());
System.out.println(f.getPath());
System.out.println(f.length());
}
}
listFiles()方法
listFiles()方法用来获取一个目录中所有的文件和文件夹,得到的结果是一个数组或者集合
package com.oracle.demo1;
import java.io.File;
public class ListFileDemo {
public static void main(String[] args) {
// 创建你要获取的路径对象
File f = new File("D:\\java\\jdk");
// 获取此路径下文件的文件数组
File[] f2 = f.listFiles();
// 遍历数组得到文件
for (File file : f2) {
System.out.println(file);
}
System.out.println(f2.length);
}
}
注:在获取指定目录下的文件或者文件夹时必须满足下面两个条件
1,指定的目录必须是存在的,
2,指定的必须是目录。否则容易引发返回数组为null,出现NullPointerException
文件过滤器
当我们需要文件中某个指定的文件时,就需要用到文件过滤器。在File类中重载了listFiles方法,并接受指定的过滤器
package com.oracle.demo1;
import java.io.File;
import java.io.FileFilter;
public class MyFilter implements FileFilter{
public boolean accept(File pathname) {
String p=pathname.getName();
return p.endsWith(".exe");
}
}
package com.oracle.demo1;
import java.io.File;
public class FileDemo3 {
public static void main(String[] args) {
File f = new File("d:\\java\\jdk\\bin");
File[] f2 = f.listFiles(new MyFilter());
for (File f3 : f2) {
System.out.println(f3);
}
}
}
递归调用
递归:就是在当前的方法内调用自己的现象
package com.oracle.demo2;
public class demo1 {
public static void main(String[] args) {
// 求1......n的值
int sum = getsum(100);
System.out.println(sum);
System.out.println(get(5));
}
// 递归调用
public static int getsum(int a) {
if(a==1){
return 1;
}
return a + getsum(a - 1);
}
//递归求阶乘
public static int get(int b){
if(b==1){
return 1;
}
return b*get(b-1);
}
}
注:递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。
在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。
练习:1、递归打印指定目录及子目录下的所有文件
2、递归调用打印d:\java\jdk下所有的.exe文件
3、使用文件名称过滤器筛选将指定文件夹下的小于200K的小文件获取并打印
package com.oracle.demo2;
import java.io.File;
public class demo4 {
public static void main(String[] args) {
File file = new File("d:\\java\\jdk");
getFileAll(file);
}
//获取指定目录以及子目录中的所有的文件
public static void getFileAll(File file) {
File[] files = file.listFiles();
//遍历当前目录下的所有文件和文件夹
for (File f : files) {
//判断当前遍历到的是否为目录
if(f.isDirectory()){
//是目录,继续获取这个目录下的所有文件和文件夹
getFileAll(f);
}else{
//不是目录,说明当前f就是文件,那么就打印出来
System.out.println(f);
}
}
}
}
package com.oracle.demo2;
import java.io.File;
public class LianXi {
public static void main(String[] args) {
File file=new File("d:\\java\\jdk");
get(file);
}
public static void get(File f){
//获取文件数组
File[] file2=f.listFiles(new MyFileFilterDemo());
//遍历当前文件下所有的文件
for(File f2:file2){
if(f2.isDirectory()){
get(f2);
}else{
System.out.println(f2);
}
}
}
}
package com.oracle.demo2;
import java.io.File;
import java.io.FileFilter;
public class MyFileFilterDemo implements FileFilter{
public boolean accept(File pathname) {
if(pathname.isDirectory()){
return true;
}
String p=pathname.getName();
return p.endsWith(".exe");
}
}
package com.oracle.demo2;
import java.io.File;
public class Demo01 {
public static void main(String[] args) {
// 1.使用文件名称过滤器筛选将指定文件夹下的小于200K的小文件获取并打印。
File file = new File("d:\\java\\jdk");
get(file);
}
public static void get(File f){
//获取指定路径文件数组
File[] file2=f.listFiles(new MyFileDemo());
//遍历得到所有文件
for(File f2:file2){
//如果是文件夹,就继续遍历里面的文件
if(f2.isDirectory()){
get(f2);
}else{
System.out.println(f2);
}
}
}
}
package com.oracle.demo2;
import java.io.File;
import java.io.FileFilter;
public class MyFileDemo implements FileFilter {
public boolean accept(File pathname) {
if(pathname.isDirectory()){
return true;
}
if(pathname.length()/1024<200){
return true;
}
return false;
}
}
字节流
前面学的File类的一些方法操作的都是空的文件或者文件夹,没有往里面去写任何数据,现在就通过字节流去往文件中写入数据
字节输出流OutputStream
OutputStream是一个抽象类,表示所有输出字节流的所有类的祖宗类,操作的数据都是字节
常用的方法:3个write()和1个close()方法
OutputStream类之FileOutputStream子类
FileOutputStream用于写入数据到文件
构造方法:
FileOutputStream(File
FileOutputStream(String
FileOutputStream(String name,boolean append)
注:若appand是true,则表示可以续写文件
若append是false,则表示覆盖文件
package com.oracle.demo3;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class OutputStreamDemo {
/*
* FileOutputStream创建对象,调用构造方法时 如果你这个文件对象中的文件存在,那么就给你覆盖 如果不存在,给你创建 new
* FileOutputStream(f); 如果构造方法传一个值的时候等价于new FileOutputStream(f,false);会给你覆盖
* 如果new FileOutputStream(f,true);那么可以文件续写,不给你覆盖 加“\r\n”
*
* 字节流操作的单位是字节 write()方法,一次只能写入一个字节 100代表SACII值里面的d
* 流对象的使用步骤
* 1、创建流子类的对象,绑定数据
* 2、调用write()方法
* 3、关闭流对象,调用close()方法,释放资源
*/
public static void main(String[] args) throws IOException {
// File f = new File("d:\\eclipse\\demo.txt");
// FileOutputStream fos = new FileOutputStream(f, true);
// fos.write(49);
// fos.write(48);
// fos.write(48);
// 如果你传入的是负数,那么就走汉字
// 一个汉字占两个字节,一个数字占一个字节
// byte[] b={-12,-23,-30,-45};
// 传字节数组的write方法
// fos.write(b);
// void write(byte[] b,int off,int len);
// fos.write(b, 1, 2);
// 需求:传入Hello getBytes()返回一个字节数组
// fos.write("\r\njava".getBytes());
// fos.close();
// 创建一个java.txt
File f = new File("e:\\test\\java.txt");
FileOutputStream fos = new FileOutputStream(f, true);
fos.write("Java是世界上最好的语言".getBytes());
fos.close();
}
}
输出流的操作步骤:
- 创建流对象
- 调用write()方法:每次只写入一个字节
- 关闭colse
IO异常处理
package com.oracle.demo3;
import java.io.FileOutputStream;
import java.io.IOException;
public class ThrowsDemo {
/*IOException处理细节
* 1、保证流对象的作用域足够(在块外面声明,在块里面赋值)
* 2、catch里面怎么处理异常
* IO异常一旦出现,一般不能处理
* 第一:输出异常信息;第二:throw new RuntimeException
* 3、流对象建立失败,还需要关闭资源么?
* 加一个判断,if(fos!=null)
* */
public static void main(String[] args) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream("e:\\test\\java.txt");
fos.write("Java是世界上最好的语言".getBytes());
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("文件写入失败,请重试");
} finally {
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
字节输入流InputStream
InputStream此抽象类,是表示字节输入流的所有类的祖宗类。,定义了字节输入流的基本共性功能方法。
int read():读取一个字节并返回,没有字节返回-1.
读取一定量的字节数,并存储到字节数组中,返回读取到的字节数
InputStream类之FileInputStream子类
构造方法:
输入流操作步骤:
- 创建流对象
- Read()
- close()
package com.oracle.demo3;
import java.io.FileInputStream;
import java.io.IOException;
public class InputStreamDemo {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("e:\\test\\java.txt");
// read()方法一次只能读取一个字节 如果到达流的末尾,则返回 -1。
// int b = fis.read();
// byte[] b = new byte[100];
// int c = fis.read(b);
// for (byte b1 : b) {
// System.out.println(b1);
// }
// System.out.println(c);
// 1、read
int len = 0;
while ((len = fis.read()) != -1) {
System.out.print((char) len);
}
// 2、read(byte[] b)
byte[] b = new byte[1024];
int l = 0;
while((l=fis.read())!=-1)
System.out.println(new String(b, 0, l));
} catch (IOException ex) {
ex.printStackTrace();
throw new RuntimeException("文件读取失败,请重试");
} finally {
try {
fis.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}