File类
file操作文件
public static void main(String[] args) throws IOException {
//创建一个File类对象
//File f = new File("F:\java学习\常用类、集合和IO\test.txt");错误的 里面会误识别转义字符
//File f = new File("F:\\java学习\\常用类、集合和IO\\test.txt");可以
File f = new File("F:/java学习/常用类、集合和IO/test.txt");//可以
//File f = new File("F:"+ File.separator+"java学习"+File.separator+"常用类、集合和IO"+File.separator+"test.txt");// File.separator 系统的分隔符 在不同的系统上不一样 用这个扩展性好
//System.out.println(f.exists());
// if(f.exists()){//如果存在 就删除文件
// f.delete();
// }else{//如果不存在 就新建
// f.createNewFile();
// }
// System.out.println(f.isDirectory());//是否是目录(文件夹) false
// System.out.println(f.isFile());//是否是文件 true
// System.out.println(f.isHidden());//是否隐藏 false
// System.out.println(f.getName());//文件名 test.txt
// System.out.println(f.getParent());//在哪个目录下 F:\java学习\常用类、集合和IO
// System.out.println(f.canRead());//可读 true
// System.out.println(f.canWrite());//可写 true
System.out.println("-----------------");
File d=new File("aaa.txt");
if (d.exists()==false){
d.createNewFile();
}
System.out.println("绝对路径"+d.getAbsolutePath());//绝对路径F:\JAVAcode\test\aaa.txt
System.out.println("相对(当前路径)路径"+d.getPath());//相对(当前路径)路径aaa.txt
}
file操作目录
public static void main(String[] args) {
File f=new File("F:/java学习/常用类、集合和IO");
// if (f.exists()){
// f.delete();
// }else{
// //f.mkdir();创建一个目录
// f.mkdirs();//创建多层目录
// }
File[] listfiles=f.listFiles();//获取目录下的所有文件
for (File ff:listfiles){
System.out.println(ff.getName()+"--"+ff.length()+"--"+ff.isDirectory());
}
}
递归遍历目录
public static void main(String[] args) {
File f=new File("F:/java学习/常用类、集合和IO");
bianli(f,1);
}
public static void bianli(File f,int level){
File[] files=f.listFiles();
for (File file:files){//可能是文件 也可能是文件夹
for (int i = 0; i < level; i++) {
System.out.print("-");
}
System.out.println(file.getName());
if (file.isDirectory()){
bianli(file,level+1);
}
}
}
IO流
文件字节流–FileInputStream,FileOutputStream
文件---->程序
public static void main(String[] args) throws IOException {
//文件---->程序
//1、确定一个文件
File f=new File("F:/java学习/常用类、集合和IO/a.txt");
//2、将一个管怼到源文件中去
FileInputStream fis=new FileInputStream(f);
//3、开始读
int n = fis.read();
while (n!=-1){
System.out.println((char)n);
n=fis.read();
}
//4、关闭流
fis.close();
}
效率更高
public static void main(String[] args) throws IOException {
//文件---->程序
//1、确定一个文件
File f=new File("F:/java学习/常用类、集合和IO/a.txt");
//2、将一个管怼到源文件中去
FileInputStream fis=new FileInputStream(f);
//System.out.println(fis.available());//对文件大小进行预估
//3、开始读
byte[] b=new byte[8];
int n = fis.read(b);
while (n!=-1){
for (int i = 0; i < n; i++) {
System.out.println(b[i]);
}
n= fis.read(b);
}
//4、关闭流
fis.close();
}
程序----->文件
public static void main(String[] args) throws IOException {
//1、确定一个文件:目标文件
File f=new File("F:/java学习/常用类、集合和IO/b.txt");
//2、将一个管怼到目标文件
FileOutputStream fos=new FileOutputStream(f,true);
//如果用的是空构造器,那么文件被覆盖。如果用两个构造器,设置为true,那么是追加
//3、给一个字符串
String str="aaa";
//4、开始动作
byte[] bytes = str.getBytes();
for (byte b : bytes) {
fos.write(b);
}
//5、关闭流
fos.close();
}
效率更高
public static void main(String[] args) throws IOException {
//1、确定一个文件:目标文件
File f=new File("F:/java学习/常用类、集合和IO/b.txt");
//2、将一个管怼到目标文件
FileOutputStream fos=new FileOutputStream(f,true);
//如果用的是空构造器,那么文件被覆盖。如果用两个构造器,设置为true,那么是追加
//3、给一个字符串
String str="iii";
//4、开始动作
byte[] bytes = str.getBytes();
fos.write(bytes);
//5、关闭流
fos.close();
}
文件的复制
public static void main(String[] args) throws IOException {
//1.确定源文件
File f1=new File("F:/java学习/常用类、集合和IO/a.txt");
//2.确定目标文件
File f2=new File("F:/java学习/常用类、集合和IO/b.txt");
//3.将一根管怼到源文件
FileInputStream fis=new FileInputStream(f1);
//4.将一根管怼到目标文件
FileOutputStream fos=new FileOutputStream(f2);
//5.开始动作
int n = fis.read();
while (n!=-1){
fos.write(n);
n=fis.read();
}
//6.关闭流(倒着关)
fos.close();
fis.close();
}
效率更高
public static void main(String[] args) throws IOException {
//1.确定源文件
File f1=new File("F:/java学习/常用类、集合和IO/a.txt");
//2.确定目标文件
File f2=new File("F:/java学习/常用类、集合和IO/b.txt");
//3.将一根管怼到源文件
FileInputStream fis=new FileInputStream(f1);
//4.将一根管怼到目标文件
FileOutputStream fos=new FileOutputStream(f2);
//5.开始动作
byte[] b=new byte[5];
int len = fis.read(b);
while (len!=-1){
fos.write(b,0,len);//把长度为5的数组中 从下标[0,len)这个位置写出去
len = fis.read(b);
}
//6.关闭流(倒着关)
fos.close();
fis.close();
}
文件字符流–FileReader,FileWriter
文件的复制
public static void main(String[] args) throws IOException {
//1.确定源文件
File f1=new File("F:/java学习/常用类、集合和IO/a.txt");
//2.确定目标文件
File f2=new File("F:/java学习/常用类、集合和IO/b.txt");
//3.将一根管怼到源文件
FileReader fr = new FileReader(f1);
//4.将一根管怼到目标文件
FileWriter fw = new FileWriter(f2);
//5.开始动作
int n = fr.read();
while (n!=-1){
fw.write(n);
System.out.println((char)n);
n=fr.read();
}
//6.关闭流(倒着关) 字符流必须进行刷新 如果写的是关闭流 那么底层直接做了flush动作
//fw.flush();
fw.close();
fr.close();
}
效率更高(缓冲数组)
public static void main(String[] args) throws IOException {
//1.确定源文件
File f1=new File("F:/java学习/常用类、集合和IO/a.txt");
//2.确定目标文件
File f2=new File("F:/java学习/常用类、集合和IO/b.txt");
//3.将一根管怼到源文件
FileReader fr = new FileReader(f1);
//4.将一根管怼到目标文件
FileWriter fw = new FileWriter(f2);
//5.开始动作
char[] ch=new char[4];
int len = fr.read(ch);
while (len!=-1){
fw.write(ch,0,len );
len=fr.read(ch);
}
//6.关闭流(倒着关) 字符流必须进行刷新 如果写的是关闭流 那么底层直接做了flush动作
//fw.flush();
fw.close();
fr.close();
}
缓冲字节流–BufferedInputstream,BufferedOutputstream
在程序里建立的缓冲区,减少了对磁盘的访问,速度更快
public static void main(String[] args) throws IOException {
//确定源文件
File f1=new File("F:/java学习/常用类、集合和IO/a.txt");
//确定目标文件
File f2=new File("F:/java学习/常用类、集合和IO/b.txt");
//直接接触的是字节流,字节流站在工作第一线,直接跟源文件,目标文件接触
FileInputStream fis = new FileInputStream(f1);
FileOutputStream fos = new FileOutputStream(f2);
//字节流外面包着缓冲字节流
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
//开始动作
byte[] b=new byte[4];
int n = bis.read(b);
while (n!=-1){
bos.write(b,0,n);
n = bis.read(b);
}
//关闭流:只关闭高级流就可以了
bos.close();
bis.close();
fos.close();
fis.close();
}
缓冲字符流–BufferedReader,BufferedWriter
在程序里建立的缓冲区,减少了对磁盘的访问,速度更快
public static void main(String[] args) throws IOException {
//确定源文件
File f1=new File("F:/java学习/常用类、集合和IO/a.txt");
//确定目标文件
File f2=new File("F:/java学习/常用类、集合和IO/b.txt");
//字符流
FileReader fis = new FileReader(f1);
FileWriter fos = new FileWriter(f2);
//字符流外面包着缓冲字符流
BufferedReader bis = new BufferedReader(fis);
BufferedWriter bos = new BufferedWriter(fos);
//开始动作
char[] b=new char[4];
int n = bis.read(b);
while (n!=-1){
bos.write(b,0,n);
n = bis.read(b);
}
//关闭流:只关闭高级流就可以了
bos.close();
bis.close();
fos.close();
fis.close();
}
效率是上面几个中最高的
public static void main(String[] args) throws IOException {
//确定源文件
File f1=new File("F:/java学习/常用类、集合和IO/a.txt");
//确定目标文件
File f2=new File("F:/java学习/常用类、集合和IO/b.txt");
//z
FileReader fis = new FileReader(f1);
FileWriter fos = new FileWriter(f2);
//字符流外面包着缓冲字符流
BufferedReader bis = new BufferedReader(fis);
BufferedWriter bos = new BufferedWriter(fos);
//开始动作
String str = bis.readLine();//一行一行的读
while (str!=null){
bos.write(str);
bos.write("\r\n");//换行 等价于bos.newLine();
str=bis.readLine();
}
//关闭流:只关闭高级流就可以了
bos.close();
bis.close();
fos.close();
fis.close();
}
System类对IO流的支持
public static void main(String[] args) throws IOException {
// Scanner sc = new Scanner(System.in);
// System.out.println("请输入一个数");
// int num = sc.nextInt();
// System.out.println(num);
//键盘录入是字节流控制
// InputStream in = System.in;
// int n= in.read();//键盘录入 在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞
PrintStream ps = System.out;//PrintStream--打印流 出来的数据是失去原本的数据类型 都变成了String类型
ps.println("java");
ps.println("oracle");
ps.println("19");
ps.println(new Date());
}
//扫描硬盘上的文件
Scanner sc=new Scanner(new FileInputStream(new File("F:/java学习/常用类、集合和IO/a.txt")));
while (sc.hasNext()){
System.out.println(sc.next());
}
转换流
将字节流转换成字符流
public static void main(String[] args) throws IOException {
//将键盘录入的东西输出到硬盘上的文件中去 用效率最高的方式
//字符----缓冲-----一行一行的读
InputStream in = System.in;//这句返回的是字节流
//字节流转字符流(转换流) 只能单向转换
InputStreamReader isr = new InputStreamReader(in);
//转入字符流
BufferedReader br = new BufferedReader(isr);
BufferedWriter bw = new BufferedWriter(new FileWriter(new File("F:/java学习/常用类、集合和IO/c.txt")));
//开始动作
String str = br.readLine();
while (str!=null){
if (str.equals("over")){
break;
}
bw.write(str);
bw.newLine();//换行
str = br.readLine();
}
//关闭流
bw.close();
br.close();
isr.close();
in.close();
}
数据流–操纵基本数据类型
往文件里写数据流
public static void main(String[] args) throws IOException {
DataOutputStream dos = new DataOutputStream(new FileOutputStream(new File("F:/java学习/常用类、集合和IO/d.txt")));
dos.writeInt(90);
dos.writeBoolean(true);
dos.writeDouble(9.7);
dos.writeUTF("java");
dos.close();
}
从文件里读数据流
public static void main(String[] args) throws IOException {
DataInputStream dis = new DataInputStream(new FileInputStream("F:/java学习/常用类、集合和IO/d.txt"));
int readInt = dis.readInt();
System.out.println(readInt);
System.out.println(dis.readBoolean());
System.out.println(dis.readDouble());
System.out.println(dis.readUTF());
dis.close();
}
对象流–操纵引用数据类型
序列化:程序–》硬盘
public static void main(String[] args) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("F:/java学习/常用类、集合和IO/b.txt")));
oos.writeObject(new Student(18,"lili"));
oos.close();
}
反序列化:硬盘–》程序
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("F:/java学习/常用类、集合和IO/b.txt")));
Object o = ois.readObject();
System.out.println(o);
ois.close();
}
序列化版本号serialVersionUID
//Serializable查看源码,发现什么方法常量都没有。原因:这是一个标识
public class Student implements Serializable {
//序列化版本号serialVersionUID
private static final long serialVersionUID = 1001L;//版本号
private int age;
private String name;
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
public Student(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
使用了序列化版本号 可以在序列化后对该类进行修改,而不用修改了再序列化
idea的序列化版本号
idea使用序列化版本号,首先需要在file–setting–plugins里下载generateserialVersionUID
下载完后到这个界面检查是否勾上
然后art+insert里就会有序列化版本号
使变量不序列化的方法
transient
关键字的主要作用就是让某些被transient关键字修饰的成员属性变量不被序列化
静态变量 和 transient
修饰的变量不会参与到序列化中
//Serializable查看源码,发现什么方法常量都没有。原因:这是一个标识
public class Student implements Serializable {
//序列化版本号serialVersionUID
private static final long serialVersionUID = 1001L;//版本号
private int age;
private String name;
static String school;//学校
transient String password;//密码
public Student(int age, String name, String password) {
this.age = age;
this.name = name;
this.password = password;
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
", password='" + password + '\'' + ",school='" + school + '\'' +
'}';
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
文件夹的复制
使用缓冲字节流 字符流不能使用 因为字符流不能复制照片等特殊文件
public static void main(String[] args) throws IOException {
//复制文件夹 只能用字节流 不能用字符流 因为字符流不能复制照片等
File f1=new File("F:/java学习/常用类、集合和IO");
File f2=new File("F:/java学习/常用类、集合和IO2");
copyDir(f1,f2);
}
public static void copyDir(File srcFile,File targerFile) throws IOException {
//如果不存在这个目标文件夹,就要创建一个新的文件夹
if (!targerFile.exists()){
targerFile.mkdirs();
}
//开始对源文件进行遍历,然后复制
File[] lf=srcFile.listFiles();
for (File f:lf){
if (f.isFile()){//遍历的是文件,操作如下
copyfile(new File(srcFile+"/"+f.getName()),new File(targerFile+"/"+f.getName()));
}else{//遍历出来是一个目录,操作如下
copyDir(new File(srcFile+"/"+f.getName()),new File(targerFile+"/"+f.getName()));
}
}
}
public static void copyfile(File srcFile,File targerFile) throws IOException {
FileInputStream fis=new FileInputStream(srcFile);
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream(targerFile);
BufferedOutputStream bos = new BufferedOutputStream(fos);
//开始动作
byte[] b= new byte[1024];
int n = bis.read(b);
while (n!=-1){
bos.write(b,0,n);
n=bis.read(b);
}
//关闭流
bos.close();
bis.close();
fos.close();
fis.close();
}
设计模式
有23种设计模式
装饰模式
概念:指再不必改变原类文件和使用继承的情况下,动态地扩展一个对象地功能。动态地为一个对象增加一个新的功能。装饰模式是一种用于代替继承的技术,无需通过继承增加子类就能扩展对象的新功能。
public interface MakeCake {//制作蛋糕的接口
void make();//抽象方法 做蛋糕
}
//父类:蛋糕
abstract class Cake implements MakeCake{
@Override
public abstract void make();
}
//子类:巧克力蛋糕
class ChocoCake extends Cake{
@Override
public void make() {
System.out.println("制作巧克力蛋糕");
}
}
//子类:抹茶蛋糕
class MoChaCake extends Cake{
@Override
public void make() {
System.out.println("制作抹茶蛋糕");
}
}
//修饰的父类
class Decorater implements MakeCake{
//修饰谁?
private MakeCake mc;
public Decorater(MakeCake mc){
this.mc = mc;
}
@Override
public void make() {
mc.make();
}
}
//子类:加口红来修饰
class DecKouHong extends Decorater{
public DecKouHong(MakeCake mc) {
super(mc);
}
@Override
public void make() {
super.make();
add();
}
public void add(){
System.out.println("在蛋糕中塞入一个口红");
}
}
//子类:加钻戒修饰
class DecZuanJie extends Decorater {
public DecZuanJie(MakeCake mc) {
super(mc);
}
@Override
public void make() {
super.make();
add();
}
public void add(){
System.out.println("在蛋糕中加入一个钻戒");
}
}
//测试类
class Test{
public static void main(String[] args) {
//买一个巧克力蛋糕
ChocoCake cc=new ChocoCake();
cc.make();
System.out.println("-------");
//在巧克力蛋糕的基础上加一个口红
DecKouHong dkh = new DecKouHong(cc);
dkh.make();
System.out.println("-------");
//再加入一个钻戒
DecZuanJie dzj = new DecZuanJie(dkh);
dzj.make();
System.out.println("-------");
//定制一个带钻戒、口红的抹茶蛋糕
new DecKouHong(new DecZuanJie(new MoChaCake())).make();
}
}
适配器模式
优点:更好的复用性,更好的扩展性
缺点:过多的使用适配器,会让系统非常零乱,不易整体进行把握
类适配器
//被适配的类
public class Adaptee {
public void surf(){
System.out.println("提供上网的功能");
}
}
//客户的目的就是为了能上网
interface Target{
void toSurf();
}
class Client{
public void want(Target t){
t.toSurf();
}
}
//进行适配工作
class Adapter extends Adaptee implements Target{
@Override
public void toSurf() {
System.out.println("转换。。");
super.surf();
}
}
class Test{
public static void main(String[] args) {
new Client().want(new Adapter());
}
}
对象适配器
//被适配的类
public class Adaptee {
public void surf(){
System.out.println("提供上网的功能");
}
}
//客户的目的就是为了能上网
interface Target{
void toSurf();
}
class Client{
public void want(Target t){
t.toSurf();
}
}
//进行适配工作
class Adapter implements Target{
Adaptee ae;
public Adapter(Adaptee ae){
this.ae = ae;
}
@Override
public void toSurf() {
System.out.println("转换。。");
ae.surf();
}
}
class Test{
public static void main(String[] args) {
new Client().want(new Adapter(new Adaptee()));
}
}