毕向东之IO与File类

/*IO流:
java对数据的操作是通过流的方式
流按照操作数据分为:字节流与字符流
流按流向分为:输入流与输出流
字节流的抽象基类:InputStream,OutputStream
字符流的抽象基类:Reader,Writer
 */
import java.io.*;
public class Test1 {
    public static void main(String[] args)throws IOException {
        //创建一个写文件对象,该对象一被初始化就必须要指明被操作的文件
        //而且该文件会被创建到指定的目录下,同名文件将覆盖
        FileWriter fw=new FileWriter("F:\\QQ文件\\demo1.txt");
        fw.write("aaaa");//将数据写入流中
        fw.flush();//刷新流的缓冲,将数据刷到目的地中
        fw.write("ccc");//其实是调用系统的方法来写数据,所以会有异常
        fw.close();//关闭之前会调用刷新
        //流关闭后不能直接再写数据 必须有流对象才能写
        //对已有文件进行数据续写
        FileWriter fw1=new FileWriter("F:\\QQ文件\\demo1.txt",true);
        fw1.write("\r\n续写");//换行
        fw1.close();
    }
}

 

 

/*对IO异常的处理
 */
import java.io.*;
public class Test2 {
    public static void main(String[] args) {
        FileWriter fw=null;//让fw的作用域变大
        try{
            fw=new FileWriter("F:\\QQ文件\\demo1.txt");
            fw.write("yichang");
        }catch(IOException e){
            System.out.println("写入异常");
        }finally{//一定要关闭
            if(fw!=null){
                try{
                    fw.close();                    
                }catch(IOException e){
                    System.out.println("流关闭异常");
                }
            }
        }
    }
}

 

 

import java.io.*;
public class Test3 {
    public static void main(String[] args)throws IOException{
        //创建一个文件读取流对象和指定名称的目录
        FileReader fr=new FileReader("F:\\QQ文件\\demo1.txt");
        FileReader fr1=new FileReader("F:\\QQ文件\\demo1.txt");
        int ch=0;
        while((ch=fr.read())!=-1){//一次读一个字符且自动往下读
            System.out.print((char)ch);//返回的数据是int型
        }
        fr.close();
        //第二种读取方式
        int num=0;
        char[] arr=new char[2];
        while((num=fr1.read(arr))!=-1){//read返回的是读取的个数
            System.out.print(new String(arr,0,num));//只截取读到的数据,避免输出重复
        }//利用数组的重装
        fr1.close();
    }
}

 

 

/*复制文件的原理:
 1.定义流与被复制文件相关联
 2.读取再写入
 */
import java.io.*;
public class Test4 {
    public static void main(String[] args)throws IOException {
        FileReader fr=new FileReader("F:\\QQ文件\\demo1.txt");
        FileWriter fw=new FileWriter("F:\\QQ文件\\fuzhi.txt");
        int num=0;
        char[] arr=new char[1024];
        while((num=fr.read(arr))!=-1){
            fw.write(arr,0,num);
        }
        fr.close();
        fw.close();
    }
}

 

 

/*字符流的缓冲区:为了提高对数据的读写效率
所以在创建缓冲区之前,必须要先有流对象
对应类:BufferedWriter,BufferedReader:利用的装饰模式(传对象而不是继承)
 */
import java.io.*;
public class Test5 {
    public static void main(String[] args)throws IOException {
        FileWriter fw=new FileWriter("F:\\QQ文件\\demo1.txt",true);
        //缓冲区背后其实就是加入了数组
        BufferedWriter bw=new BufferedWriter(fw);
        bw.newLine();//换行,\r\n只适用于wendows
        bw.write("abcdef");
        bw.close();//关闭缓冲区就是在关闭缓冲区的流对象(内部调用)
        FileReader fr=new FileReader("F:\\QQ文件\\demo1.txt");
        BufferedReader br=new BufferedReader(fr);
        String str;
        while((str=br.readLine())!=null){//不包括\r\n
            System.out.println(str);
        }
        br.close();
    }
}

 

 

import java.io.*;
public class Test6 {
    public static void main(String[] args) {
        BufferedWriter bw=null;
        BufferedReader br=null;
        try{
            bw=new BufferedWriter(new FileWriter("F:\\QQ文件\\fuzhi.txt"));
            br=new BufferedReader(new FileReader("F:\\QQ文件\\demo1.txt"));
            String str;
            while((str=br.readLine())!=null){
                bw.write(str);
                bw.newLine();
            }
        }catch(IOException e){
            System.out.println("读写异常");
        }finally{
            if(bw!=null){
                try{
                    bw.close();  
                }catch(IOException e){
                    System.out.println("关闭失败");
                }
            }
            if(br!=null){
                try{
                    br.close();
                }catch(IOException e){
                    System.out.println("关闭失败");
                }
            }
        }
    }
}

 

 

//LineNumberReader extends BufferedReader
import java.io.*;
public class Test7 {
    public static void main(String[] args)throws IOException{
        LineNumberReader lnr=new LineNumberReader(new FileReader("F:\\QQ文件\\fuzhi.txt"));
        String str;
        //lnr.setLineNumber(100);//行号默认从0开始
        while((str=lnr.readLine())!=null){
            System.out.println(lnr.getLineNumber()+":"+str);
        }
        lnr.close();
    }
}
class MyLineNumberReader{//LineNumberReader的原理
    private FileReader fr;
    private int count=0;
    public MyLineNumberReader(FileReader fr){
        this.fr=fr;
    }
    public int getLineNumber(){
        return count;
    }
    public String readLine()throws IOException{
        StringBuilder sb=new StringBuilder();
        int ch;
        count++;  
        while((ch=fr.read())!=-1){//一行行读
            if(ch=='\r')
                continue;
            if(ch=='\n')
                return sb.toString();
            sb.append((char)ch);
        }
        if(sb.length()!=0)
            return sb.toString();
        return null;
    }
    public void close()throws IOException{
        fr.close();
    }
}

 

 

/*字节流:字符流用于操作文本,字节操作图片等等
LineNumberReader extends BufferedReader
InputStream 读   -->Reader
OutputStream 写 -->Writer
FileInputStream -->FileReader
FileOutputStream -->FileWrider
BufferedInputStream -->BufferedReader
BufferedOutputStream -->BufferedWrider
 */
import java.io.*;
public class Test8 {
    public static void main(String[] args)throws IOException{
        FileInputStream fis=new FileInputStream("F:\\图片\\tupian.jpg");
        FileOutputStream fos=new FileOutputStream("F:\\图片\\fuzhi.jpg");
        int len;
        byte[] arr=new byte[1024];//字节流写入字节数组
        while((len=fis.read(arr))!=-1){
            fos.write(arr,0,len);
        }
        fos.close();
        fis.close();
    }
}

 

 

/*自定义字节流的缓冲区时需要注意:
while条件里面的-1代表数据都读完了
而字节里面的数据都是由零一组成,所以要避免读到8个1(-1);
处理方法:
1111-1111 一个字节,等于负一
   1111-1111-1111-1111 提升为int型的再与上
 & 0000-0000-1111-1111 也就是与上0xff;
   0000-0000-1111-1111 这样就不再等于负一
也就避免了把八个数据1当成了负一来处理
 */
import java.io.*;
public class Test9 {
    public static void main(String[] args) {
        long start=System.currentTimeMillis();
        BufferedInputStream bis=null;
        BufferedOutputStream bos=null;
        try{
            bis=new BufferedInputStream(new FileInputStream("F:\\图片\\美女.jpg"));
            bos=new BufferedOutputStream(new FileOutputStream("F:\\图片\\复制.jpg"));
            int count;
            byte[] arr=new byte[1024];
            while((count=bis.read(arr))!=-1){
                bos.write(arr, 0, count);
            }
        }catch(IOException e){
            throw new RuntimeException("读取失败");
        }finally{
            if(bis!=null){
                try{
                    bis.close();
                }catch(IOException e){
                    throw new RuntimeException("读取关闭失败");
                }
            }
            if(bos!=null){
                try{
                    bos.close();
                }catch(IOException e){
                    throw new RuntimeException("写入关闭失败");
                }
            }
        }
        long end=System.currentTimeMillis();
        System.out.println((end-start)+"毫秒");
    }
}

 

 

//键盘录入
import java.io.*;
public class Test10 {
    public static void main(String[] args)throws Exception{
        InputStream in=System.in;//标准的输入流
        StringBuilder sb=new StringBuilder();
        int ch;
        while(true){
            ch=in.read();
            if(ch=='\r')
                continue;
            if(ch=='\n'){
                if(sb.toString().equals("over"))
                    break;
                System.out.println(sb.toString());
                sb.delete(0, sb.length());
            }
            else{
                sb.append((char)ch);
            }
        }
    }
}

 

 

/*键盘录入的原理其实就是读一行数据的原理也就是readLine方法
 又因为readLine方法是字符流BufferedReader类的方法
 所以需要将字节流转换成字符流才能使用readLine方法(缓冲区的)
 */
import java.io.*;
public class Test11 {
    public static void main(String[] args)throws IOException{
        InputStream in=System.in;//获取键盘录入对象
        //将字节流对象转换成字符流对象,使用转换流
        InputStreamReader isr=new InputStreamReader(in);
        //为了提高效率,将字符流进行缓冲区高效操作(一个一个读变为一行行读)
        BufferedReader bufr=new BufferedReader(isr);
        OutputStream out=System.out;
        OutputStreamWriter osw=new OutputStreamWriter(out);
        BufferedWriter bufw=new BufferedWriter(osw);
        String line;
        while((line=bufr.readLine())!=null){
            if(line.equals("over"))
                break;
            bufw.write(line);
            bufw.newLine();//缓冲区的方法
            bufw.flush();
        }
        bufr.close();
    }
}

 

 

/*需求:将键盘录入的数据存入文件中
1.明确源和对象: 
 源:输入流 InputStream,Reader
 目的:输出流 OutputStream,Writer
2.操作数据是纯文本用字符流,否则字节流
目的:想要把录入的数据按照指定的编码表(UTF-8),将数据存到文件中.
但是FileWriter使用的是默认编码表GBK,而只有转换流才能指定编码表
 */
import java.io.*;
public class Test12 {
    public static void main(String[] args)throws IOException{
        BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter budw=new BufferedWriter(new FileWriter("F:\\QQ文件\\1.txt"));
        String line;
        while(true){
            line=bufr.readLine();
            if(line.equals("over"))
                break;
            budw.write(line);
            budw.flush();
        }
    }
}

 

 

/*改变默认的输入输出
 */
import java.io.*;
public class Test13{
    public static void main(String[] args)throws IOException {
        System.setIn(new FileInputStream("F:\\QQ文件\\1.txt"));
        System.setOut(new PrintStream("F:\\QQ文件\\2.txt"));
        BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in,"GBK"));
        BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));
        String line;
        while((line=bufr.readLine())!=null){
            if(line.equals("over"))
                break;
            bufw.write(line);
            bufw.flush();
        }
    }
}

 

 

//异常的日志文件处理
import java.io.*;
import java.text.*;
import java.util.*;
public class Test14 {
    public static void main(String[] args) {
        int[] arr=new int[2];
        try{
            System.out.println(arr[3]);
        }catch(Exception e){
            try{
                PrintStream ps=new PrintStream("F:\\QQ文件\\Exception.log");
                System.setOut(ps);//整个主函数的out都变了
                Date da=new Date();//大写HH为24时制
                SimpleDateFormat sd=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String str=sd.format(da);
                e.printStackTrace(ps);
                ps.print(str);
                ps.flush();
            }catch(IOException io){
                System.out.println("日志文件创建异常");
            }
        }
        System.out.println("打印在日志文件中了");
    }
}

 

 

import java.util.*;
import java.io.*;
public class Test15 {
    public static void main(String[] args)throws IOException{
        Properties p=System.getProperties();//获取系统性能
        PrintStream ps=new PrintStream("F:\\QQ文件\\1.txt");
        p.list(ps);//列表的形式打印
    }
}

 

 

/*File类:用来将文件或文件夹封装成对象
 File类常见方法:
 1.创建:
     boolean createNewFile();在指定位置创建文件,不存在时才创建,而输出流对象一建立就会创建文件,存在时会覆盖
     boolean mkdir();创建文件夹
     boolean mkdirs();创建多级文件夹
 2.删除:
     boolean delete();立马删除
     void    deleteOnExit();虚拟机结束后删除
 3.判断:
     boolean canExecute();能否执行
     boolean exists();文件是否存在
     boolean isFile();是不是文件
     boolean isDirectory();是不是文件夹
     boolean isAbsolute();是否是绝对路径(路径全名)
     boolean isHidden();是否是隐藏文件
 4.获取信息:
     String getName();获取文件目录或文件的名称
     String getPath();//父目录不存在时返回null
     String getParent();返回此抽象路径名父目录的路径名字符串
     String getAbsoluteParh();返回此抽象路径名的绝对路径名字符串。
     File   getAbsoluteFile();返回此抽象路径名的绝对路径名形式。
     long   lastModified();文件最后一次被修改的时间
     long   length();文件里面内容的长度
 */
import java.io.*;
public class Test16 {
    public static void main(String[] args)throws IOException {
        File f1=new File("F:\\QQ文件");//将文件夹封装成对象
        File f2=new File("F:\\QQ文件","1.txt");//文件夹中的文件
        File f3=new File(f1,"2.txt");//  由于\\不能跨平台
        File f4=new File("F:"+File.separator+"QQ文件"+File.separator+"4.txt");
        //注意:以上并不是创建文件,而只是封装
        sop(f1);
        sop(f2.createNewFile());//创建新文件
        sop(f2.delete());
        sop(f2.canExecute());//判断文件f2能不能执行
        sop(f2.exists());
        sop(f2.mkdir());
        sop(f2.length());
        f2.renameTo(f3);//f2名称改为f3
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

 这个只能过滤一层,如果文件夹中包含文件夹就不行了,所以需要用到递归,见下面

//接口 FilenameFilter:文件名的过滤器(选该名字的文件)
//接口 FileFilter:路径名的过滤器(选该路径名的文件)
import java.io.*;
public class Test17 {
    public static void main(String[] args) {
        File f=new File("c:");
        File[] arr=File.listRoots();
        arr=f.listFiles();//所以文件或文件夹的对象,与list的区别
//        for(File name:arr){
//            System.out.println(name);
//        }
        File[] fileArr=f.listFiles(new FilenameFilter(){
            public boolean accept(File dir,String name){
                return name.endsWith(".ini");//只选.ini的文件存到fileArr里
            }//dir=f,返回为真时存入fileArr中
        });
        for(File name:fileArr){
            System.out.println(name);
        }
    }
}

 

/**
     * 获取指定路径中的视频文件
     * @param list 装扫描出来的视频文件实体类
     * @param file 指定的文件
     */
    public static void getVideoFile(final List<VideoInfo> list, File file) {// 获得视频文件
        file.listFiles(new FileFilter() {
            @Override
            public boolean accept(File file) {
                // sdCard找到视频名称
                String name = file.getName();
                int i = name.indexOf('.');
                if (i != -1) {
                    name = name.substring(i);//获取文件后缀名
                    if (name.equalsIgnoreCase(".mp4")  //忽略大小写
                            || name.equalsIgnoreCase(".3gp")
                            || name.equalsIgnoreCase(".wmv")
                            || name.equalsIgnoreCase(".ts")
                            || name.equalsIgnoreCase(".rmvb")
                            || name.equalsIgnoreCase(".mov")
                            || name.equalsIgnoreCase(".m4v")
                            || name.equalsIgnoreCase(".avi")
                            || name.equalsIgnoreCase(".m3u8")
                            || name.equalsIgnoreCase(".3gpp")
                            || name.equalsIgnoreCase(".3gpp2")
                            || name.equalsIgnoreCase(".mkv")
                            || name.equalsIgnoreCase(".flv")
                            || name.equalsIgnoreCase(".divx")
                            || name.equalsIgnoreCase(".f4v")
                            || name.equalsIgnoreCase(".rm")
                            || name.equalsIgnoreCase(".asf")
                            || name.equalsIgnoreCase(".ram")
                            || name.equalsIgnoreCase(".mpg")
                            || name.equalsIgnoreCase(".v8")
                            || name.equalsIgnoreCase(".swf")
                            || name.equalsIgnoreCase(".m2v")
                            || name.equalsIgnoreCase(".asx")
                            || name.equalsIgnoreCase(".ra")
                            || name.equalsIgnoreCase(".ndivx")
                            || name.equalsIgnoreCase(".xvid")) {
                        VideoInfo vi = new VideoInfo();
                        vi.displayName = file.getName();//文件名
                        vi.filePath = file.getAbsolutePath();//文件路径
                        list.add(vi);
                        LogUtils.i("tag","文件名:"+vi.displayName+",路径:"+vi.filePath);
                        return true;
                    }
                } else if (file.isDirectory()) {
                    getVideoFile(list, file);
                }
                return false;
            }
        });
    }

 

/*输出指定路径的所有文件夹和文件(Test17只能输出父目录)
因为目录中还有目录,只要使用同一个列出目录的功能函数就可以完成
也就是利用递归的思想
 */
import java.io.*;
public class Test18 {
    public static void main(String[] args) {
        File f=new File("E:\\郭天祥视频");
        File[] farr=f.listFiles();
        showDir(farr);
    }
    public static void showDir(File[] farr){
        for(int i=0;i<farr.length;i++){
            if(farr[i].isDirectory()){//判断是不是目录
                System.out.println(farr[i]);
                showDir(farr[i].listFiles());
            }else
                System.out.println(farr[i]);
        }
    }
}

 

/*文件删除原理:先删除里面的再删除外面的,
如果某文件夹里面有文件,该文件不能直接删除,必须先删除里面的才能删除外面的
文件便利的时候要注意隐藏文件:f.isHidden()
 */
import java.io.*;
public class Test19 {
    public static void main(String[] args) {
        File f=new File("F:\\QQ文件\\111");
        deleteDir(f);//删除f文件夹
    }
    public static void deleteDir(File file){
        File[] arr=file.listFiles();
        for(int i=0;i<arr.length;i++){
            if(arr[i].isDirectory()){
                deleteDir(arr[i]);
            }else//不是目录就删除
                System.out.println(arr[i].delete());
        }//文件夹中的文件删除后再删除该文件夹
        System.out.println(file.delete());//删除当前目录
    }
}

 

 

/*需求:将一个指定目录下的java文件的绝对路径存储到一个文本文件中
 思路:1.通过递归找出所有.java文件,并把它的绝对路径存入集合中
     2.将集合中的数据写入文件中
 */
import java.io.*;
import java.util.*;
public class Test20 {
    public static void main(String[] args) throws IOException {
        File f1=new File("E:\\学习文件");
        File f2=new File("F:\\QQ文件\\22.txt");
        List<File> list=new ArrayList<File>();
        fileToList(f1,list);//将f1文件里的java文件路径存入集合
        listToFile(list,f2);//将list中的内容写入文本文件中
    }
    public static void fileToList(File file,List<File> list){
        File[] farr=file.listFiles();
        for(int i=0;i<farr.length;i++){
            if(farr[i].isDirectory()){
                fileToList(farr[i],list);
            }else{
                if(farr[i].getName().endsWith(".java")){
                    list.add(farr[i].getAbsoluteFile());
                }
            }
        }
    }
    public static void listToFile(List<File> list,File file)throws IOException{
        BufferedWriter bufw=null;
        try{
            bufw=new BufferedWriter(new FileWriter(file));
            for(File f:list){//f为绝对路径
                bufw.write(f.toString());
                bufw.newLine();
                bufw.flush();
            }
        }catch(IOException e){
            throw e;//抛出去交给调用者处理
        }finally{
            if(bufw!=null){
                try{
                    bufw.close();
                }catch(IOException e){
                    throw e;
                }
            }
        }
    }
}

 

 

/*Properties是hashtable的子类,也就是说它具备map集合的特点
而且它里面存储的键值对都是字符串,它是集合中和IO技术相结合的集合容器
注意:如果一流对象指向的路径相同(如下fis,fos)在进行集合加载时,如果这两个流对象都写在load之前,
集合将加载不成功,还会把原有的数据删掉
 */
import java.util.*;
import java.io.*;
public class Test21 {
    public static void main(String[] args)throws IOException{
        Properties prop=new Properties();
        FileInputStream fis=new FileInputStream("F:\\QQ文件\\11.txt");
        prop.load(fis);//将fis的内容加载到prop集合中
        prop.setProperty("wangwu", "15");//修复集合的内容
        FileOutputStream fos=new FileOutputStream("F:\\QQ文件\\11.txt");
        prop.store(fos, "zhushi");//将prop集合的内容存储到fos中
        prop.list(System.out);
        fis.close();
        fos.close();
    }
    public static void setPrinit(){
        Properties prop=new Properties();//性能
        prop.setProperty("zhangshan","3");
        prop.setProperty("lisi","4");
        prop.setProperty("lisi","5");
        for(String name:prop.stringPropertyNames()){
            System.out.println(name+"--"+prop.getProperty(name));
        }
    }
}

 

/*需求:记录一应用程序运行的次数,超过一定的次数给出注册提示
思路:只有在程序运行时先执行配置文件,读取运行的次数进行判断
而程序一关闭数据也就清除了,所以必须用到文件对数据进行记录;
即:集合处理文件,IO存储数据,Map+IO=Properties
步骤:1.判断配置文件存不存在,不存在则创建,并创建集合加载文件数据
2.通过集合判断配置文件中记录次数的数据是否存在,不存在就设置
3.获取次数并进行次数自增,将次数写入集合中,再通过集合存储到配置文件中
 */
import java.io.*;
import java.util.*;
public class Test22 {
    public static void main(String[] args)throws IOException{
        File file=new File("F:\\QQ文件\\properties.ini");//ini文件为配置文件
        if(!file.exists()){//判断文件是否存在
            file.createNewFile();//不存在则创建
        }
        FileInputStream fis=new FileInputStream(file);
        Properties prop=new Properties();
        prop.load(fis);//加载
        fis.close();//加载后就关闭,免得读写流错乱
        if(prop.getProperty("time")==null){//如果配置文件不存在time
            prop.setProperty("time","0");//就创建一个值
        }//time作为文件中描述次数的Key 
        System.out.println(prop);
        int count=Integer.parseInt(prop.getProperty("time"));
        count++;//获取次数并自增
        prop.setProperty("time", count+"");//将改变的次数设置到集合中
        FileOutputStream fos=new FileOutputStream(file);
        prop.store(fos, "zhushi");//将集合数据存储到文件中,注释
        if(count>=5){
            System.out.println("次数已到,请交钱购买");
            return ;//方法结束
        }
        System.out.println("已使用"+count+"次");
        fos.close();
    }
}

 

posted @ 2016-05-31 12:52  ts-android  阅读(283)  评论(0编辑  收藏  举报