Java学习笔记_12

来源:互联网 发布:yii2 源码 编辑:程序博客网 时间:2024/05/15 05:23

一、File:

文件和目录(文件夹)路径名的抽象表示形式。 

File的构造方法:

  File(String pathname):把一个路径名称封装成File对象
  File(String parent, String child):把一个父路径和一个子路径封装成一个File对象
  File(File parent, String child):把一个父路径File对象和一个子路径封装成一个File对象

创建功能:

  A:创建文件
  public boolean createNewFile():如果文件不存在,就创建。否则,不创建。
需求:D盘下造一个文件a.txt
  B:创建目录
  public boolean mkdir():如果目录不存在,就创建。否则,不创建。
需求:D盘下造一个文件夹test
  public boolean mkdirs():如果目录不存在,就创建。否则,不创建。
  即时父目录不存在,也可以连父目录一起创建。
需求:D盘下造一个文件夹(D:/aaa/bbb/ccc)
需求:D盘下造一个文件夹("D:\\ddd\\eee\\f.txt");

public static void main(String[] args) {//public boolean mkdir():如果目录不存在,就创建。否则,不创建。//需求:D盘下造一个文件夹test//File file = new File("D://test");//System.out.println(file.mkdir());System.out.println("----------");//public boolean mkdirs():如果目录不存在,就创建。否则,不创建。//即时父目录不存在,也可以连父目录一起创建。File file = new File("D://aa//bb//a.txt");System.out.println(file.mkdirs());}
这里创建的a.txt是文件夹的名字,并非txt文件。

 
   注意事项:
  A:你要造什么东西,就应该用对应的方法。

  删除功能:
  public boolean delete():既可以删除文件,又可以删除目录。
 
  路径问题:
  A:绝对路径 就是以盘符开始的路径(d:\\test\\aaa\\b.txt)
  B:相对路径 就是不以盘符开始的路径(a.txt)
  一般都是相对应当前的项目而言的。
  
  注意事项:
  A:Java程序的删除不走回收站。
  B:如果目录内还有内容就不能删除。

  判断功能
  public boolean isDirectory():是否是目录
  public boolean isFile():是否是文件
  public boolean exists():是否存在
  public boolean canRead():是否可读
  public boolean canWrite():是否可写
  public boolean isHidden():是否隐藏


 
  获取功能
  public String getAbsolutePath():获取绝对路径
  public String getPath():获取相对路径
  public String getName():获取名称


 二:字节流及字节高效流

I/O流的分类:



注意:一般我们在讨论IO的分类时,默认是按照数据类型分的。

字节流:

字节输入流 InputStream(抽象类)

字节输出流 OutputStream(抽象类)

字符流:

字符输入流 Reader

字符输出流 Writer


 我们如何往一个文件写数据呢?
 或者说就是字节输出流的操作步骤是什么呢?
 A:创建字节输出流对象
  B:调用写数据的方法
  C:释放资源(不要忘记释放资源)

 

分析:

   写数据我们就应该知道是字节输出流
   所以最终选择了OutputStream
   而OutputStream是抽象类,所以我们应该找其子类FileOutputStream

两个构造方法:

  FileOutputStream(File file)
FileOutputStream(String name)

FileOutputStream写数据的方法:
write(byte[] b) 
write(int b) :一次写一个字节
write(byte[] b, int off, int len) :一次写一个字节数组的一部分

例子:用字节流在文本中写入“Helloworld”

public static void main(String[] args) throws IOException {FileOutputStream fos = new FileOutputStream("a.txt");byte[] byf = "helloworld".getBytes();fos.write(byf);//释放资源,关流操作fos.close();}

这里是创建了字节输出流对象fos 指向a.txt,并且创建了a.txt文本,再向a.txt这个文本写入了byf这个字节数组。


字节输入流:

具体操作步骤:
  A:创建字节输入流对象
 FileInputStream  fis = new FileInputStream("a.txt");
  B:调用方法读取数据
 一次读取一个字节:read() -- 测试读取不到内容的时候的返回值(并且用循环改进)

()字节输入流的read如果读取不到内容,返回的值是-1)
  C:释放资源
  fis.close


通过字节输入流和字节输出流,我们可以复制文件

事例:将a.txt文本的内容复制到b.txt中

public static void main(String[] args) throws IOException {//A:把a.txt的内容复制到b.txt中//封装数据源和目的地FileInputStream fis = new FileInputStream("a.txt");FileOutputStream fos = new FileOutputStream("b.txt");//2.读取数据源中的数据,将读取到的数据写入目的地中int by;while ((by=fis.read())!=-1) {//System.out.println(by);//将读取到的字节写入fos中fos.write(by);}//释放资源fos.close();fis.close();}

利用字符数组来提高复制效率:

public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("a.txt");FileOutputStream fos = new FileOutputStream("c.txt");byte[] bys = new byte[1024];int len;while ((len=fis.read(bys))!= -1) {fos.write(bys, 0, len);}fis.close();fos.close();}



字节缓冲区流(也叫高效流):

   BufferedInputStream(read() 一次读取一个字节, public int read(byte[] b):返回实际读取长度,数据被读取到数组中。)
   BufferedOutputStream(write(byte[] b))
  

利用高效流复制mp4文件,步骤与字节输入输出流复制的方法大致相同。

public static void main(String[] args) throws IOException {//一次读取一个字节数组的时候,复制一个mp4文件//疯转数据源和目的地BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D://b.mp4"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("j.mp4"));//1.一次读写一个字节/*int by;while ((by=bis.read())!=-1) {bos.write(by);}*///2.一次读写一个字节数组byte[] byf = new byte[1024];int len;while ((len = bis.read(byf))!=-1) {bos.write(byf, 0, len);}//3.关流bos.close();bis.close();}



 流:
   低级流: 基本的流,可以直接操作文件。
  高级流:是操作基本流的流。


 三:编码问题

 String中的编码和解码问题。
  
 编码:
   把我们能够看懂的字符转换为看不懂的数据
 解码:
   把我们看不懂的数据转换为看得懂的字符

 public byte[] getBytes(String charsetName)  按照给定的编码方式,编码字节数组(gbk,utf-8)
 String(byte[] bytes, String charsetName) 按照给定的编码方式解码字符数组

使用gbk去进行编码的时候,我们是将一个汉字编码成两个负数的字节。
当我们解码的时候,如果字节数组中遇见负数的话,会将前面和后面的负数进行拼接,去gbk码表中找到相应的明文

当使用uft-8进行编码的时候,一个汉字会被编码成3个负数的字节
解码的时候,一旦遇见负数,三个拼接,去码表中进行解码

结论:用什么编码,就必须用什么解码,否则会出现乱码。


 四:字符流

Reader
Writer

 IO流中的编码和解码问题:
 OutputStreamWriter:把字节输出流转换为字符输出流

 InputStreamReader:把字节输入流转换为字符输入流

创建字节输入流,并指定码表:

public static void main(String[] args) throws IOException {//不指定码表的情况下,创建字符输入转换流//InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));//创建一个字符输入转换流,并指定码表InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"),"gbk");//使用循环改进int ch;while ((ch=isr.read())!=-1) {System.out.println((char)ch);}//关流isr.close();}
字符输出流OutputStreamWriter的用法与此也是大致相同


总结:我们一般创建字符输入或者输出流一般情况下使用系统默认的码表就可以,
     如果来来回回需要指定码表的话,就显得非常的麻烦了

为了使用方便,java将上述字符输入输出流进行了简化,提供了他们的子类

FileReader

FileWriter
 它们的默认编码是采用系统编码。
 构造方法:
FileWriter(File file) 
FileWriter(String fileName) 
FileReader(File file) 
FileReader(String fileName)

创建字符输出流步骤:

1.创建字符输出流对象,并指向一个文件;

2.调用字符输出流写数据的方法里面的数据;

3.刷新缓冲区;

4.关流;

  写数据方法:
   一次写一个字符  write(int c) 
   一次写一个字符数组write(char[] cbuf)
一次写一个字符数组的一部分write(char[] cbuf, int off,int len)
一次写一个字符串write(String str)
一次写一个字符串的一部分write(String str,int off,int len)

public static void main(String[] args) throws IOException {FileWriter fw = new FileWriter("c.txt");fw.write("helloworld");//刷新缓冲区fw.flush();//关流fw.close();}
这里与字节输出流的区别在于刷新缓冲区。



 flush()和close()的区别? 

 A:flush 刷新缓冲区,流对象可以继续
 B:close 先刷新缓冲区,再关闭流对象。流对象不可以继续使用了。

字符输入流操作步骤:

A:创建字符输入流对象
B:读取数据并显示在控制台
a:一次读取一个字符
b:一次读取一个字符数组  
C:释放资源
fr.close();

public static void main(String[] args) throws Exception {//1.创建字符输入流对象,指向c.txt这个文件FileReader fr = new FileReader("c.txt");int ch;while ((ch=fr.read())!=-1) {System.out.println((char)ch);}
//定义一个字符数组char[] chs = new char[1024];int len;while ((len=fr.read(chs))!=-1) {System.out.println(new String(chs, 0, len));}//3.关流fr.close();}
注意:

字符流输入输出流复制的文件是有要求的,简单来说只要是记事本打开文件的内容你能够看得懂,
就可以用字符流来进行复制,否则不行。
具体原因:

像复制MP3或者一些视频文件的时候,如果他的字节个数不是偶数的话,就会造成文件的缺损,
因为一个字符等于两个字节。

 高效流:

 给文件中写入十个"helloworld",每写一个换一行,每写一行必须写入一个换行符“/r/n”
这样写的弊端,windows系统下的换行符是“\r\n”,Linux是"\n",Mac是"\r",这样会造成代码的通用性不强

BufferedReader:字符缓冲输入流
构造:BufferedReader(Reader in) 
特殊方法:public String readLine():包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null 
BufferedWriter:字符缓冲输出流
构造:BufferedWriter(Writer out) 
特殊方法:public void newLine():会根据系统来确定写入不同的换行符

利用高效流向文件中写入10个中国好,并换行:

步骤:

1.创建字符缓冲输出流,并且指向ff.txt文件;

2.写入数据、并用newLine()换行;

3、刷新缓冲区;

4、关流;

public static void main(String[] args) throws IOException {BufferedWriter bw = new BufferedWriter(new FileWriter("ff.txt"));//写入数据for (int i = 0; i < 10; i++) {bw.write("中国好");bw.newLine();bw.flush();}//释放资源bw.close();}
利用高效流复制java文件:

public static void main(String[] args) throws IOException {//封装数据源和目的地BufferedReader br = new BufferedReader(new FileReader("InputStreamReaderDemo.java"));BufferedWriter bw = new BufferedWriter(new FileWriter("copy.java"));//读取一行写一行String line;while ((line = br.readLine())!=null) {//System.out.println();bw.write(line);bw.newLine();bw.flush();}//释放资源bw.close();br.close();}

注意:这里while的执行条件是line!=null,因为readLine的返回值是String类型,当读取不到数据时,返回null。


五:设计模式

A:设计模式概述
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。
使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性以及代码的结构更加清晰.

B:设计模式分类
创建型模式(创建对象的): 单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。
行为型模式(对象的功能): 适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
结构型模式(对象的组成): 模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、
解释器模式、状态模式、策略模式、职责链模式、访问者模式。

单例设计模式:

A:单例设计思想
保证类在内存中只有一个对象
B:如何实现类在内存中只有一个对象呢?
构造私有
本身提供一个对象
通过公共的方法让外界访问
C:案例演示: 饿汉式、懒汉式

饿汉式:

 当这个类一被加载,就在内存中创建了一个对象
 
  1.保证内存中只有一个对象(构造私有)
  2.在本类中创建一个该类的对象
  3.创建一个公共的访问方式给外界获取该对象
 

public class SingleInstanceDemo {private SingleInstanceDemo(){}//静态的随着类的加载而加载private static SingleInstanceDemo instance = new SingleInstanceDemo();//给外界提供公共的访问方式,返回该对象public static SingleInstanceDemo getInstance(){return instance;}


懒汉式:

需要的时候才去创建对象,不需要的时候不创建

private SingleInstanceDemo2(){}private static SingleInstanceDemo2 instance = null;public static SingleInstanceDemo2 getInstance(){if (instance==null) {instance = new SingleInstanceDemo2();}return instance;

工厂设计模式:

A:简单工厂模式概述:又叫静态工厂方法模式,它定义一个具体的工厂类负责创建一些类的实例
B:优点: 使用静态工厂模式的优点是实现责任的分割,该模式的核心是工厂类,工厂类含有必要的选择逻辑,可以决定什么时候创建哪一个产品的实例,
而客户端则免去直接创建产品的责任,而仅仅是消费产品。也就是说静态工厂模式在不改变客户端代码的情况可以动态的增加产品。
明确了类的职责
C:缺点
这个静态工厂类负责所有对象的创建,如果有新的对象增加,或者某些对象的创建方式不同,
就需要不断的修改工厂类,不利于后期的维护
案例演示:

1.先创建一个动物抽象类Animal,再创建Cat 、Dog类继承Animal,并实现抽象方法eat();这里不赘述

2.创建简单工厂模式,产生对象;

3.创建text类测试;

public class AnimalFactory {//专门用来生产对象public static Animal getAnimal(String type){if ("dog".equals(type)) {return new Dog();}else if ("cat".equals(type)) {return new Cat();}return null;}}
text类中,通过调用getAnimal方法,可以创建Dog类和Cat类。但是工厂中需要生产其他类时,必须改代码。

抽象工厂模式的概述和使用:
A:工厂方法模式概述
工厂方法模式中抽象工厂类负责定义创建对象的接口,具体对象的创建工作由继承抽象工厂的具体类实现。
B:优点
客户端不需要在负责对象的创建,从而明确了各个类的职责,如果有新的对象增加,
只需要增加一个具体的类和具体的工厂类即可,不影响已有的代码,后期维护容易,增强了系统的扩展性
C:缺点: 需要额外的编写代码,增加了工作量

案例演示:

1.先创建动物抽象类Animal;

2.创建动物功能类(抽象类)AnimalFactory;

3.创建Dog类、Cat类继承Animals;

4.创建DogFactory类、CatFactory类继承AnimalFactory

5.创建text类测试

AnimalFactory类

public abstract class AnimalFactory {//创建动物的功能public abstract Animal getAnimal();}
DogFactory类

public class DogFactory extends AnimalFactory{@Overridepublic Animal getAnimal() {// TODO Auto-generated method stubreturn new Dog();}}

测试类:

public class Test {public static void main(String[] args) {//需要一个狗对象AnimalFactory af = new DogFactory();Animal a = af.getAnimal();a.eat();//需要一个猫对象af = new CatFactory();a = af.getAnimal();a.eat();}}
如果需要添加其他动物对象,只需要添加该动物类和该动物的Factory类。









0 0