首先,来说一说File 文件类,顾名思义,这个类的作用,就是将 系统中存在的文件,变成Java的对象。
注:所有的输出流初始化时,后边可以追加,true和false 意思为是否追加,默认false 就会覆盖源文件,
例:FileOutputStream fos=new FileOutputStream(filename,true);
代码中说吧:
package day0817;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
public class Demo1 {
public static void main(String[] args) throws IOException {
//File的三种初始化方式
// 1.
// File f=new File("/Users/songqi/Desktop/day15.txt");
//2.
// File f=new File("/Users/songqi/Desktop/", "day15.txt");
//3.
File f1=new File("..");
File f=new File(f1, "day15.txt");
//判断文件或者文件夹是否存在
System.out.println(f.exists());
//新建一个文件
f.createNewFile();
//获得文件的名称
System.out.println(f.getName());
//相对路径,如果是相对路径就是相对路径,如果是绝对路径,就是绝对路径
//相对于项目或是文件夹 文件
System.out.println(f.getPath());
//绝对路径 完整的路径
System.out.println(f.getAbsolutePath());
//父目录
System.out.println(f.getParent());
//文件是否可读
System.out.println(f.canRead());
//文件是否可写
System.out.println(f.canWrite());
//是否是文件
System.out.println(f.isFile());
//是否是目录
System.out.println(f.isDirectory());
//最后一次修改的时间
System.out.println(f.lastModified());
Date date=new Date(f.lastModified());
System.out.println(date);
//文件字节大小
System.out.println(f.length());
// System.out.println(f.delete());
}
}
File提供的过滤方法 ,可以简单处理输入的File
package day0817;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
public class Demo2 {
public static void main(String[] args) {
File f=new File("/Users/songqi/Desktop/day15");
//是否存在
System.out.println(f.exists());
//是否是目录
System.out.println(f.isDirectory());
//获得当前目录下的子目录和文件的字符串形式
// String [] all=f.list();
//过滤
// String []all=f.list(new FilenameFilter() {
//
// @Override
// public boolean accept(File dir, String name) {
// // TODO Auto-generated method stub
//
// return name.endsWith(".docx");
// }
// });
String []all=f.list((d,name)->name.endsWith(".java"));
for(String s:all)
{
System.out.println(s);
}
//获得的目录下的子目录和文件的File形式
// File[] files=f.listFiles();
//过滤
// File[] files=f.listFiles(new FileFilter() {
//
// @Override
// public boolean accept(File pathname) {
// // TODO Auto-generated method stub
// return pathname.getName().endsWith(".java");
// }
// });
File [] files=f.listFiles(file->file.getName().endsWith(".java"));
for(File file:files) {
if(file.isDirectory()) {
System.out.println(file.getPath());
}else {
System.out.println(file.getName());
}
}
}
}
对于文件夹呢,也是File来作为对象,其实 File 也就是一个路径,不管你是文件,还是文件夹。
对于文件夹,除了之上的操作,还有以下使用:
package day0817;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
public class Demo2 {
public static void main(String[] args) {
File f=new File("/Users/songqi/Desktop/day15");
//是否存在
System.out.println(f.exists());
//是否是目录
System.out.println(f.isDirectory());
//获得当前目录下的子目录和文件的字符串形式
// String [] all=f.list();
//过滤
// String []all=f.list(new FilenameFilter() {
//
// @Override
// public boolean accept(File dir, String name) {
// // TODO Auto-generated method stub
//
// return name.endsWith(".docx");
// }
// });
String []all=f.list((d,name)->name.endsWith(".java"));
for(String s:all)
{
System.out.println(s);
}
//获得的目录下的子目录和文件的File形式
// File[] files=f.listFiles();
//过滤
// File[] files=f.listFiles(new FileFilter() {
//
// @Override
// public boolean accept(File pathname) {
// // TODO Auto-generated method stub
// return pathname.getName().endsWith(".java");
// }
// });
File [] files=f.listFiles(file->file.getName().endsWith(".java"));
for(File file:files) {
if(file.isDirectory()) {
System.out.println(file.getPath());
}else {
System.out.println(file.getName());
}
}
}
}
下面试试,打印输出某个文件夹下所有文件的路径
思考一下,很有意思的题
文件和文件夹到此结束,下面开始正题,IO流:
字节流和字符流的区别就是 :字节流是一次读一个字节,而字符流是一次读一个字符也就是一个char ,所以呢,读文本文件的话,当然是用字符流快了,而读二进制文件之类的字节流效率高,这点有选择性的。
那什么是输入流,什么是输出流呢?输入流,就是往内存中读取,就是输入流,从内存往文件中输出,就是输出流。
节点流意思就是和文件直接操作的流就叫节点流,处理流也可以叫包装流,举个栗子就是,平常的输入输出流是水管,那么包装流就是加了个水龙头,这个水龙头就是处理流,也就是包装流。
图中,即为节点流及其子类,Input即为输入流,Output即为输出流,FileinputStream 是文件输入流,用这个读文件,FileOutputStream是文件输出流,用这个流对文件进行写入。
FilterInputStream及其子类 FilterOutputStream及其子类都是包装类,ObjectInputStream和ObjectInputStream是对对象进行序列化和反序列化用到的流-对象输入输出流。
按照惯例,代码中说:
package day0817;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class Demo5 {
//文件流,节点流
public static void main(String[] args) throws IOException {
//1创建流对象
// FileInputStream fis=new FileInputStream("/Users/songqi/Desktop/15.txt") ;
//2.创建流对象
File f=new File("/Users/songqi/Desktop/day15.txt");
FileInputStream fis=new FileInputStream(f);
//读 每次读一个字节 到尾返回的是-1 如果读汉字 读两次的值才是汉字
System.out.println((char)fis.read());
// System.out.println((char)fis.read());
// System.out.println((char)fis.read());
// System.out.println((char)fis.read());
// System.out.println((char)fis.read());
int temp=0;
while((temp=fis.read())!=-1) {
System.out.println((char)(temp));
}
//关闭流,如果不关闭有些流有时候会写不进去
fis.close();
}
}
其中的路径问题呢,我这的环境是mac,不区分大小写,但是如果创建两个文件夹只是大小写有区别的话,是不让创建的。
Windows 不知道行不行,但是养成好习惯,最好是区分大小写的写法。
包装流的Demo
package day0817;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Demo6 {
public static void main(String[] args) throws IOException {
//1创建流对象
// FileInputStream fis=new FileInputStream("/Users/songqi/Desktop/15.txt") ;
//2.创建流对象
File f=new File("/Users/songqi/Desktop/day15.txt");
FileInputStream fis=new FileInputStream(f);
//转换字符流
InputStreamReader ir=new InputStreamReader(fis);
int temp=0;
while((temp=ir.read())!=-1) {
System.out.print((char)(temp));
}
//关闭流
fis.close();
ir.close();
}
}
花式读方法
package day0817;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class Demo7 {
public static void main(String[] args) throws IOException {
//1创建流对象
// FileInputStream fis=new FileInputStream("/Users/songqi/Desktop/15.txt") ;
//2.创建流对象
File f=new File("/Users/songqi/Desktop/day15.txt");
FileInputStream fis=new FileInputStream(f);
// byte[] b=new byte[(int) f.length()];
//流的大小 要在没读之前调用 否则不准确的 流有指针
byte[] b=new byte[fis.available()];
//把 独到的字节数组存到字节数组b中,返回读到的字节总数
// fis.read(b);
//(字节数组 ,字节数组的起始位置,存几个) mac 好像区别,很奇怪,Windows上会显示空格,而mac却不显示空格
fis.read(b, 100, 2);
String s=new String(b, "gbk");
System.out.println(s);
//关闭流
fis.close();
}
}
花式写方法
package day0817;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo8 {
public static void main(String[] args) throws IOException {
File f2=new File("/Users/songqi/Desktop/1.txt");
//没有文件会在自动创建 但是没有父目录 会抛异常 ,如果是 false 或者默认 会覆盖 ,true 则追加
FileOutputStream fos=new FileOutputStream(f2,true);
String all="Hello你好啊";
byte [] b=all.getBytes();
// fos.write(b);
//字节数组,起始位置,长度
fos.write(b, 2, 2);
fos.close();
}
}
再来一个Demo
package day0817;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo9 {
public static void main(String[] args) {
File f2=new File("/Users/songqi/Desktop/1.txt");
FileOutputStream fos=null;
//没有文件会在自动创建 但是没有父目录 会抛异常 ,如果是 false 或者默认 会覆盖 ,true 则追加
try {
fos=new FileOutputStream(f2);
byte []b="hello".getBytes();
fos.write(b);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(fos!=null) {
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
包装流之缓冲输入流,包装后效率会比较高
package day0820;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo1 {
public static void main(String[] args) throws IOException {
// File f=new File("/Users/songqi/Desktop/1.PNG");
FileInputStream fis=new FileInputStream("/Users/songqi/Desktop/1.PNG");
FileOutputStream fos=new FileOutputStream("/Users/songqi/Desktop/2.PNG");
//缓冲区大小 8192字节
BufferedOutputStream bos=new BufferedOutputStream(fos);
int temp=0;
while((temp=fis.read())!=-1) {
bos.write(temp);
// System.out.print((char)temp);
}
//是读之前就能available 还是读之后呢?有没有这个问题?
// byte[] b=new byte[fis.available()];
// fis.read(b);
// fos.write(b);
bos.flush();
fis.close();
fos.close();
}
}
package day0820;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;
public class Demo3 {
public static void main(String[] args) throws IOException {
Scanner sc=new Scanner(System.in);
//判断是否。.
// if(sc.hasNextInt()) {
// int num=sc.nextInt();
// }else {
// System.out.println("不是数字");
// }
FileInputStream fis=new FileInputStream("/Users/songqi/Desktop/1.txt");
Scanner sc2=new Scanner(fis);
String s=sc2.next();
System.out.println(s);
//这是比较有趣的一个地方,如果是next()会发现永远不会读进去,只有nextLine 可以,因为nextLine 它会在读到分隔符的时候,读取分隔符前边的并返回后边的字符串
Scanner sc3=new Scanner("aa bb cc");
System.out.println(sc3.next());
s=sc3.nextLine();
System.out.println(s);
}
}
数据流:这也是包装流的一种,挺神奇的,看一下,有点类似类的序列化和反序列化
package day0820;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo4 {
public static void main(String[] args) throws IOException {
//数据流
// DataOutputStream dos=new DataOutputStream(new FileOutputStream("/Users/songqi/Desktop/1.txt"));
File f=new File("/Users/songqi/Desktop/1.txt");
FileOutputStream fos=new FileOutputStream(f);
DataOutputStream dos=new DataOutputStream(fos);
int [] no= {11,22,33};
String [] name= {"ww","qwew","qweqwe"};
for(int i=0;i<no.length;i++) {
dos.writeInt(i);
dos.writeUTF(name[i]);
}
dos.close();
fos.close();
FileInputStream fis=new FileInputStream(f);
DataInputStream dis=new DataInputStream(fis);
for(int i=0;i<no.length;i++) {
//这个读写顺序是必须一样的
System.out.println(dis.readInt());
System.out.println(dis.readUTF());
}
dis.close();
fis.close();
}
}
下面比较重要的,序列化和反序列化:
这个是做什么呢,就是序列化对象,将之存到文件中,反序列化,将之从文件中读出来。
废话少说,上demo:
package day0820;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;
//序列化与反序列化
//要实现 Serializable 接口,进去你会发现是个 接口,而且任何抽象方法都没有,其实作用就是标记,这个类可以序列化
class Student implements Serializable{
/**
* 版本号,这个UID是什么呢,就是如果你先序列化一个对象到本地,如果你更改这个类,比如加了个属性,那么再读取就会出错,因为系统会自动生成UID 因为 类变化了就不一样了,所以就会报错,而你这样定义呢,就不会
*/
private static final long serialVersionUID = 1L;
private int no;
private String name;
int age;
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Demo5 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//序列化,把对象转换成字节序列
Student stu=new Student();
File f=new File("/Users/songqi/Desktop/1.txt");
stu.setName("sq");
stu.setNo(1);
//1.创建流对象
FileOutputStream fos=new FileOutputStream(f);
//包装流
ObjectOutputStream oos=new ObjectOutputStream(fos);
//2.写
oos.writeObject(stu);
oos.close();
//反序列化
// FileInputStream fis=new FileInputStream(f);
// ObjectInputStream ois=new ObjectInputStream(fis);
// Student stua=(Student)ois.readObject();
// System.out.println(stua.getName()+","+stua.getNo());
// System.out.println(stua.age);
// ois.close();
//
}
}
PrintStream:这个类就是输出比较方便
package day0820;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
public class Demo6 {
public static void main(String[] args) throws IOException {
//把一个文件内容读出来,在控制台显示
//读
File f=new File("/Users/songqi/Desktop/1.txt");
FileInputStream fis=new FileInputStream(f);
byte []b =new byte[fis.available()];
fis.read(b);
fis.close();
//写控制台
PrintStream ps=new PrintStream(System.out);
ps.println(new String(b));
ps.close();
}
}
下面说说字符流:
其实字符流跟字节流在名字上很相像,初学者不好区分,凡是什么什么Stream这就是 字节流 而结尾是Reader和Writer的是字符流。
不多说,上Demo
读:
package day0820;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
//字符流
public class Demo7 {
public static void main(String[] args) throws IOException {
//读
//1.
FileReader fr=new FileReader("/Users/songqi/Desktop/1.txt");
//2.读
int temp=0;
while((temp=fr.read())!=-1) {
System.out.println((char)temp);
}
fr.close();
}
}
写:
package day0820;
import java.io.FileWriter;
import java.io.IOException;
public class Demo8 {
public static void main(String[] args) throws IOException {
//写
String s="eqweqwe大大所多";
FileWriter fw=new FileWriter("/Users/songqi/Desktop/1.txt");
fw.write(s);
fw.close();
}
}
综合的来一个:
package day0820;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Demo9 {
public static void main(String[] args) throws IOException {
FileReader fr=new FileReader("/Users/songqi/Desktop/1.txt");
int temp=0;
StringBuffer s=new StringBuffer();
while((temp=fr.read())!=-1) {
s.append((char)temp);
}
System.out.println(s);
s.reverse();
FileWriter fw=new FileWriter("/Users/songqi/Desktop/1.txt");
System.out.println(s);
fw.write(s.toString());
fw.close();
fr.close();
}
}
字符缓冲流:
package day0820;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Demo11 {
//缓冲流
public static void main(String[] args) throws IOException {
File f=new File("/Users/songqi/Desktop/1.txt");
FileReader fr=new FileReader(f);
BufferedReader br=new BufferedReader(fr);
String s1=br.readLine();
System.out.println(s1);
String s2=br.readLine();
System.out.println(s2);
String s3=br.readLine();
System.out.println(s3);
String s4=br.readLine();
System.out.println(s4);
}
}
PrintWriter:
package day0820;
import java.io.FileNotFoundException;
import java.io.FilterWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class Demo12 {
public static void main(String[] args) throws IOException {
//这点的true,flase 是刷新缓冲区 而不是是否追加
PrintWriter pw=new PrintWriter("/Users/songqi/Desktop/1.txt");
for(int i=1;i<=5;i++) {
pw.println("第"+i+"个数字");
}
pw.close();
}
}
最后再说一个 try(流)catch{异常处理} 这点是可以默认关流的,如果你不这样写,而且还不关流的话,文件不会有任何信息,试试:
package day0820;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Scanner;
public class Demo13 {
public static void main(String[] args){
try (PrintWriter pw = new PrintWriter("/Users/songqi/Desktop/1.txt")){
Scanner sc=new Scanner(System.in);
//BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
for(;;) {
String s=sc.next();
if(s.equals("q")) {
break;
}
pw.println(s);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}