Java基础回顾(二)

23)不可变对象:创建后对象的(状态/值)不能被更改。其内在的成员变量也不能修改。包括八个基本类别的包装类、String、BigInteger和BigDecimal等。

24)不可变对象也是传指针。由于不可变(值对象不再修改,或者说是指针指向的值不能修改),临时变量指向新内存(因为值对象不可修改,所以要申请新的空间,把指针指向它)。

25)不可变对象的要求:

  • 1.所有熟悉final和private。
  • 2.不提供setter方法。
  • 3.类是final的,或者所有的方法都是final。
  • 4.类中包含mutable对象,那么返回拷贝需要深度clone。

26)不可变对象优点:线程安全,提高性能,可重用。缺点:浪费空间。(每次对不可变对象进行修改都会开辟新空间,旧对象搁置直到垃圾回收)

27)用StringBuffer(同步/线程安全/修改快速)和StringBuilder(不同步/线程不安全/修改更快速)类的append方法修改String,不产生空间浪费。

28)java.io包:

节点类字节{InputStream,OutputStream} 字符{Reader,Writer}

转换类: {InputSteamReader} 文件读取时字节,转化为java能理解的字符 {OutputSteamWriter} Java将字符转化为字节输入到文件中

装饰类:{DataInputSteam、DataOutputStream}封装数据流

{BufferedInputStream、BufferOutputStream}缓存字节流

{BufferedReader、BufferedWriter}缓存字符流

文本文件读写

//写文件1:BufferedWriter(OutputStreamWriter(FileOutputStream))
public static void WriteFile(){
  FileOutputStream fos = null;
  OutputStreamWriter osw = null;
  BufferedWriter bw = null;
  try{   
    fos = new FileOutputStream("c:/a.txt");//节点类
    osw = new OutputStreamWriter(fos,"UTF-8");//转化类
    bw = new BufferedWriter(osw);//装饰类
    //或者可以 br = new BufferedWriter(new OutputStreamWriter(new 
    //FileOutputStream("c:/a.txt")));
    bw.write("内容");  //关闭时只需要关闭bw.close,因为bw在最外层
    bw.newLine();
    }catch(Exception ex){
    ex.printStackTrace();
    }finally{
      try{
      bw.close();
      }catch (Exception ex){
      ex.printStackTrace();
      }
    }
}
//写文件2:使用try-resource
public static void WriteFile(){
  try(BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("c:/a.txt")))){
    bw.write("内容");
    bw.newLine();
  }catch (Exception ex){
    ex.printStackTrace();
  }
}
//读文件1:BufferedReader(InputStreamReader(FileInputStream))
public static void ReadFile(){
  FileInputStream fis = null;
  InputStreamReader isr = null;
  BufferedReader br = null;
  try{
    fis = new FileInputStream("c:/a.txt");  //节点类
    isr = new InputStreamReader(fis,"UTF-8");  //转化类
    br = new BufferedReader(isr);  //装饰类
    String line;
    while((line = br.readLine()) != null){
      //...
    }
  }
  catch (Exception ex){
    ex.printStackTrace();
  }finally{
  try{
    br.close();
    }catch (Exception ex){
    ex.printStackTrace();
    }
  }
}
//读文件2:使用try-resource
public static void ReadFile(){
  String line;
  try(BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("c:/a.txt")))){
    while((line = br.readLine()) != null){
      System.out.println(line);
    }
  }catch (Exception ex){
    ex.printStackTrace();
  }
}

二进制文件读写

与文本文件读写的不同在于最外层由BufferedReader / BufferedWriter转变为了BufferedInputStream / BufferedOutputStream

//写文件 DataOutputStream(BufferedOutputStream(FileOutputStream))
public static void WriteFile(){
  FileOutputStream fos = null;
  BufferedOutputStream bos = null;
  DataOutputStream dos = null;
  try{   
    fos = new FileOutputStream("c:/a.dat");//节点类
    bos = new BufferedOutputStream(fos);//装饰类
    dos = DataOutputStream(bos);//装饰类
    dos.writeUTF("a");
    }catch(Exception ex){
    ex.printStackTrace();
    }finally{
      try{
      dos.close();
      }catch (Exception ex){
      ex.printStackTrace();
      }
    }
}
//读文件 try-resource
//DataInputStream(BufferedInputStream(FileInputStream))
public static void ReadFile(){
  try(DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream("c:/a.dat")))){
      String a,b;
      int c,d;
      a = dis.readUTF();
      b = dis.readInt();
      c = dis.readInt();
      d = dis.readUFT();
      System.out.println("a:"+a);
      System.out.println("c:"+c);
      System.out.println("d:"+d);
      System.out.println("b:"+b);
    }
  }catch (Exception ex){
    ex.printStackTrace();
  }
}

压缩:1.打开输出Zip文件 2.添加一个ZipEntry 3.打开一个输入文件,读数据,向ZipEntry写数据,关闭输入文件。 4.重复以上两个步骤,写入多个文件到zip文件中。 5.关闭Zip文件。

//单个压缩
public class SingleFileZip{
    public static void main(String args[]) throws Exception{
        File file = new File("c:/temp/abc.txt"); //定义要压缩的文件
        File zipFile = new File("c:/temp/single2.zip"); //定义压缩文件的名称
        InputStream input = new FileInputStream(file); //定义文件输入流
        ZipOutputStream zipOut = null; //声明压缩流的对象
        zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
        zipOut.putNextEntry(new ZipEntry(file.getName())); //设置ZipEntry对象
        zipOut.setComment("single file zip"); //设置注释
        //压缩过程
        int temp = 0;
        while((temp=input.read())!=-1){ //读取内容
            zipOut.write(temp);    //压缩输出
        }
        input.close(); //关闭输入流
        zipOut.close(); //关闭输出流
        System.out.println("single file zip done.");
    }
//把单个文件改成多个文件压缩
int temp = 0 ;
if(file.isDirectory()){ //判断是否是文件夹
   File lists[] = file.listFiles() ;  //列出全部子文件
   for(int i=0;i<lists.length;i++){
      input = new FileInputStream(lists[i]) ; //定义文件的输入流
      zipOut.putNextEntry(new ZipEntry(file.getName()
         +File.separator+lists[i].getName())) ; //设置ZipEntry对象
      System.out.println("" + lists[i].getName());
      while((temp=input.read())!=-1){  //读取内容
         zipOut.write(temp) ;  //压缩输出
      }
      input.close() ;   //关闭输入流
   }
}
zipOut.close() ;  //关闭输出流
System.out.println("multiple file zip done.");

解压:1.打开Zip文件 2.获取下一个ZipEntry 3.新建一个目标文件,从ZipEntry读取数据,向目标文件写入数据。 4.重复以上两步骤。 5.关闭Zip文件。

public class SingleFileUnzip{  
    public static void main(String args[]) throws Exception{     
        //待解压文件, 需要从zip文件打开输入流,读取数据到java中
    	File zipFile = new File("c:/temp/single.zip") ;//定义压缩文件名称          
        ZipInputStream input = null ;   // 定义压缩输入流  
        input = new ZipInputStream(new FileInputStream(zipFile)) ;//实例化ZIpInputStream  
        ZipEntry entry = input.getNextEntry() ;//得到一个压缩实体  
        System.out.println("压缩实体名称:" + entry.getName()) ;//获取压缩包中文件名字 
        
        //新建目标文件,需要从目标文件打开输出流,数据从java流入
        File outFile = new File("c:/temp/" + entry.getName());
        OutputStream out = new FileOutputStream(outFile) ;//实例化文件输出流  
        int temp = 0 ;  
        while((temp=input.read())!=-1){  
            out.write(temp) ;  
        }  
        input.close() ; //关闭输入流  
        out.close() ; //关闭输出流
        System.out.println("unzip done.") ;
    }  
}
public class MultipleFileUnzip{  
    public static void main(String args[]) throws Exception{    
    	//待解压的zip文件,需要在zip文件上构建输入流,读取数据到Java中
        File file = new File("c:/temp/multiple.zip") ; //定义压缩文件名称  
        File outFile = null ;   // 输出文件的时候要有文件夹的操作  
        ZipFile zipFile = new ZipFile(file) ; //实例化ZipFile对象  
        ZipInputStream zipInput = null ; //定义压缩输入流  
        
        //定义解压的文件名
        OutputStream out = null ; //定义输出流,用于输出每一个实体内容  
        InputStream input = null ; //定义输入流,读取每一个ZipEntry  
        ZipEntry entry = null ; //每一个压缩实体  
        zipInput = new ZipInputStream(new FileInputStream(file)) ;  //实例化ZIpInputStream 
        
        //遍历压缩包中的文件
        while((entry = zipInput.getNextEntry())!=null){ //得到一个压缩实体  
        	System.out.println("解压缩" + entry.getName() + "文件") ;  
            outFile = new File("c:/temp/" + entry.getName()) ;   //定义输出的文件路径  
            if(!outFile.getParentFile().exists()){  //如果输出文件夹不存在 
                outFile.getParentFile().mkdirs() ;   
                // 创建文件夹 ,如果这里的有多级文件夹不存在,请使用mkdirs()
                // 如果只是单纯的一级文件夹,使用mkdir()就好了
            }  
            if(!outFile.exists()){  //判断输出文件是否存在
            	if(entry.isDirectory())
            	{
            		outFile.mkdirs();
            		System.out.println("create directory...");
            	}
            	else
            	{
            		outFile.createNewFile() ;   //创建文件
            		System.out.println("create file...");
            	}                  
            }  
            if(!entry.isDirectory())
            {
            	input = zipFile.getInputStream(entry) ; //得到每一个实体的输入流  
                out = new FileOutputStream(outFile) ; //实例化文件输出流  
                int temp = 0 ;  
                while((temp=input.read())!=-1){  
                    out.write(temp) ;  
                }  
                input.close() ;  //关闭输入流  
                out.close() ; //关闭输出流  
            }
        }  
        input.close() ;  
    }  
}