• Java IO(三)


       File

       File类的常见方法:

      1、创建。

        boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false。和输出流不一样,输出流对象一建立就创建文件,而且文件已经存在,会覆盖。

        boolean mkdir():创建文件夹。

        boolean mkdirs():创建多级文件夹。

      2、删除。

        boolean delete():删除失败返回false。

        void deleteOnExit():在程序退出时删除指定文件。

      3、判断。

        boolean exists():文件是否存在。

        isDirectory()

        isFile()

        isHidden():是否是一个隐藏文件。

        isAbsolute():文件不存在也可以判断。

      4、获取信息。

        getName():获取文件或目录的名称。

        getPath():返回的就是File类构造函数里面的字符串,不管什么绝对或相对路径,你给我什么,我就返回什么。

        getParent():该方法返回的是绝对路径中的父目录,如果获取的是相对路径,返回null。如果相对路径中有上一层目录,那么该目录就是返回结果。

        getAbsolutePath():该方法法返回的是绝对路径。

        long lastModified()

        long length()

       示例代码如下:

    import java.io.File;
    import java.io.IOException;
    
    public class FileDemo0 {
    
        public static void main(String[] args) throws IOException {
            //consMethod();
            //method_1();
            //method_2();
            //method_3();
            //method_4();
            method_5();
        }
        
        public static void method_5() {
            File f1 = new File("d:\java\LoginDemo.java");
            File f2 = new File("d:\java\aaa.java");
            
            sop("rename:" + f2.renameTo(f1));
        }
        
        public static void method_4() {
            File f = new File("abc\file.txt");
            
            sop("path:" + f.getPath());//返回的就是File类构造函数里面的字符串,里面是什么就返回什么
            sop("abspath:" + f.getAbsolutePath());
            sop("parent:" + f.getParent());//该方法返回的是绝对路径中的父目录,如果获取的是相对路径,返回null
                                           //如果相对路径中有上一层目录,那么该目录就是返回结果。
        }
        
        public static void method_3() throws IOException {
            File f = new File("E:\MyJava\workspace\IO_Project\file2.txt");
            
            //f.createNewFile();
            //f.mkdir();
            
            /*
             * 记住在判断文件对象是否是文件或者目录时,必须要先判断该文件对象封装的内容是否存在,
             * 通过exists()判断。
             */
            sop("dir : " + f.isDirectory());
            sop("file : " + f.isFile());
            sop(f.isAbsolute());//文件不存在也可以判断
        }
        
        public static void method_2() {
            File f = new File("file.txt");
            //sop("exists : " + f.exists());
            //sop("execute: " + f.canExecute());
            
            /*
             * 创建文件夹
             */
            File dir = new File("abc\kkk\asd\qewq\as\er");
            
            sop("mkdir : " + dir.mkdirs());
            
        }
        
        public static void method_1() throws IOException {
            File f = new File("file.txt");
            f.deleteOnExit();
            //code();
            //sop("create : " + f.createNewFile());
            sop("delete :" + f.delete());
        }
        
        /*
         * 创建File对象
         */
        public static void consMethod() {
            /*
             * 将a.txt封装成file对象,可以将已有和未出现的文件或文件夹封装成对象
             */
            File f1 = new File("a.txt");
            
            File f2 = new File("d:\java\io123", "b.txt");
            
            File d = new File("d:\java\io123");
            File f3 = new File(d, "c.txt");
            
            sop("f1 : " + f1);
            sop("f2 : " + f2);
            sop("f3 : " + f3);
            
            File f4 = new File("d:" + File.separator + "java" + File.separator + "io123" + File.separator + "d.txt");
        }
        
        
        public static void sop(Object obj) {
            System.out.println(obj);
        }
    
    }

      5、列出可用的文件系统根,也就是本机上的盘符。

        listRoots()

      6、字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。如果目录为空,那么数组也将为空如果此抽象路径名不表示一个目录,或者发生 I/O 错误,则返回null

        list()

      7、返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。

        listFiles()

       代码如下:

    import java.io.File;
    import java.io.FilenameFilter;
    
    public class FileDemo1 {
    
        public static void main(String[] args) {
            //listRootsDemo();
            //listDemo();
            
            File dir = new File("c:\");
            File[] files = dir.listFiles();
            for(File f : files) {
                System.out.println(f.getName() + "::" + f.length());
            }
            
        }
        
        /*
         * 专门找指定目录下指定后缀名(例如:.java/.jpg/.mp3/.log)的文件
         */
        public static void listDemo_2() {
            File dir = new File("d:\java\io");
            
            String[] arr = dir.list(new FilenameFilter() {
                
                @Override
                public boolean accept(File dir, String name) {
                    //System.out.println("dir:" + dir + "...name:" + name);
                    /*
                    if(name.endsWith(".log"))
                        return true;
                    else
                        return false;
                    */
                    return name.endsWith(".log");
                }
            });
            
            System.out.println("len:" + arr.length);
            for(String name : arr) {
                System.out.println(name);
            }
        }
        
        public static void listDemo() {
            File f = new File("c:\abc.txt");
            
            String[] names = f.list();//调用list()方法的file对象必须是封装了一个目录。该目录还必须存在。
            for(String name : names) {
                System.out.println(name);
            }
        }
        
        public static void listRootsDemo() {
            File[] files = File.listRoots();
            
            for(File f : files) {
                System.out.println(f.length());
            }
        }
    
    }

       

       递归

       例,列出指定目录下文件或者文件夹,包含子目录中的内容。也就是列出指定目录下的所有内容。

       分析:

       因为目录中还有目录,只要使用同一个列出目录功能的函数完成即可。在列出过程中出现的还是目录的话,还可以再次调用本功能。也就是函数自身调用自身。这种表现形式或者编程手法,称为递归。 

       递归要注意:

    1. 限定条件。
    2. 要注意递归的次数,尽量避免内存溢出。

       代码如下:

    import java.io.File;
    
    public class FileDemo2 {
    
        public static void main(String[] args) {
            File dir = new File("d:\java");
            showDir(dir, 0);
        }
        /*
         * 分层级列出指定目录下的所有内容
         */
        public static String getLevel(int level) {
            StringBuilder sb = new StringBuilder();
            sb.append("|--");
            for(int x = 0; x < level; x++) {
                //sb.append("|--");
                sb.insert(0, "|  ");
            }
            return sb.toString();
        } 
        public static void showDir(File dir, int level) {
            
            System.out.println(getLevel(level) + dir.getName());
            level++;
            File[] files = dir.listFiles();
            for(int x = 0; x < files.length; x++) {
                if(files[x].isDirectory()) {
                    showDir(files[x], level);
                } else {
                    System.out.println(getLevel(level) + files[x]);
                }
                
            }
        }
    }

       举例说之,十进制数转二进制数。代码如下:

    public class FileDemo0 {
    
        public static void main(String[] args) {
            toBin(6);
        }
        
        public static void toBin(int num) {
            if(num > 0) {
                toBin(num / 2);
                System.out.print(num % 2);
            }
        }
    
    }

       图解:

       

       

       再举例说之:求和。代码如下:

    public class FileDemo0 {
    
        public static void main(String[] args) {
            int sum = getSum(100);
            System.out.println("sum = " + sum);
        }
        
        public static int getSum(int n) {
            if(n == 1)
                return 1;
            return n + getSum(n - 1);
        }
    
    }

       图解:

       删除一个带内容的目录。

       删除原理:在windows中,删除目录从里面往外删除的。既然是从里往外删除,就需要用到递归。

       代码如下:

    import java.io.File;
    
    public class RemoveDir {
    
        public static void main(String[] args) {
            File f = new File("d:\java");
            removeDir(f);
        }
        
        public static void removeDir(File dir) {
            File[] files = dir.listFiles();
            
            for(int x = 0; x < files.length; x++) {  
                if(files[x].isDirectory()) {
                    removeDir(files[x]);
                } else {     
                    System.out.println(files[x].toString() + ":-file-:" + files[x].delete());
                }
            }
            
            System.out.println(dir + "::dir::"+ dir.delete());
        }
    
    }

       Properties

       Properties是HashTable的子类,也就是说它具备map集合的特点,而且他里面存储的键值对都是字符串。是集合和IO技术相结合的集合容器。该对象的特点:可以用于键值对形式的配置文件。那么在加载数据时,需要数据有固定格式,通常是键=值。

       示例代码:

    import java.io.BufferedReader;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.Properties;
    import java.util.Set;
    
    public class PropertiesDemo0 {
    
        public static void main(String[] args) throws IOException {
            //setAndGet();
            //method_1();
            loadDemo();
        }
        
        public static void loadDemo() throws IOException {
            Properties prop = new Properties();
            FileInputStream fis = new FileInputStream("D:\java\io123\info.txt");
            //将流中的数据加载进集合
            prop.load(fis);
            
            prop.setProperty("wangwu", "21");
            
            FileOutputStream fos = new FileOutputStream("D:\java\io123\info.txt");
            
            prop.store(fos, "haha");
            //System.out.println(prop);
            prop.list(System.out);//将属性列表输出到指定的输出流。功能与System.out.println(prop);语句相似
            
            fos.close();
            fis.close();
        }
        
        /*
         * 演示,如何将流中的数据存储到集合中。(也即是Properties类中load(InputStream in)方法的原理)
         * 想要将info.txt中的键值对数据存到集合中进行操作
         * 
         * 1、用一个流和info.txt文件关联
         * 2、读取一行数据,将该行数据用“=”进行切割
         * 3、等号左边作为键,右边作为值。存入到Properties集合中即可。
         */
        public static void method_1() throws IOException {
            BufferedReader bufr = new BufferedReader(new FileReader("D:\java\io123\info.txt"));
            String line = null;
            Properties prop = new Properties();
            while((line = bufr.readLine()) != null) {
                String[] arr = line.split("=");
                prop.setProperty(arr[0], arr[1]);
                //System.out.println(arr[0]+"...."+arr[1]);
            }
            bufr.close();
            System.out.println(prop);
        }
        
        /*
         * 设置和获取元素
         */
        public static void setAndGet() {
            Properties pro = new Properties();
            pro.setProperty("zhangsan", "30");
            pro.setProperty("lisi", "39");
            //System.out.println(pro);
            String value = pro.getProperty("lisi");
            //System.out.println(value);
            
            pro.setProperty("lisi", 89+"");
            
            Set<String> names = pro.stringPropertyNames();
            for(String s : names) {
                System.out.println(s+":"+pro.getProperty(s));
            }
        }
    }

       打印流

       该流提供了打印方法,可以将各种数据类型的数据都原样打印。

       1、字节打印流(PrintStream)

       构造函数可以接收的参数类型:

    1. file对象。File
    2. 字符串路径。String
    3. 字节输出流。OutputStream  

       2、字符打印流(PrintWriter)

       构造函数可以接收的参数类型:

    1. file对象。File
    2. 字符串路径。String
    3. 字节输出流。OutputStream
    4. 字符输出流。Writer

       示例代码:

    import java.io.BufferedReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    
    public class PrintStreamDemo {
    
        public static void main(String[] args) throws IOException {
            BufferedReader bufr = 
                    new BufferedReader(new InputStreamReader(System.in));
            
            PrintWriter out = new PrintWriter(new FileWriter("a.txt"), true);//不需要写刷新代码out.flush();自动刷新。
            
            String line = null;
            
            while((line = bufr.readLine()) != null) {
                if("over".equals(line))
                    break;
                out.println(line.toUpperCase());
                //out.flush();
            }
            out.close();
            bufr.close();
        }
    }

       练习1:将一个指定目录下的java文件的绝对路径,存到一个文本文件中,建立一个java文件列表清单。

       思路:

    1. 对指定的目录进行递归。
    2. 获取递归过程中所有的java文件的路径。
    3. 将这些路径存储到集合中。
    4. 将集合的数据写入到一个文件中。

       代码:

    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    public class JavaFileList {
    
        public static void main(String[] args) throws IOException {
            File dir = new File("d:\java");
            List<File> list = new ArrayList<File>();
            fileToList(dir, list);
            File file = new File(dir, "javalist.txt");
            writeToFile(list, file.toString());
            
            //System.out.println(list.size());
        }
        
        public static void fileToList(File dir, List<File> list) {
            File[] files = dir.listFiles();
            for(File file : files) {
                if(file.isDirectory()) 
                    fileToList(file, list);
                else {
                    if(file.getName().endsWith(".java"))
                        list.add(file);
                }
            }
        }
        
        public static void writeToFile(List<File> list, String javaListFile) throws IOException {
            BufferedWriter bufw = null;
            try {
                bufw = new BufferedWriter(new FileWriter(javaListFile));
                for(File f : list) {
                    String path = f.getAbsolutePath();
                    bufw.write(path);
                    bufw.newLine();
                    bufw.flush();
                }
            } catch (IOException e) {
                throw e;
            } finally {
                try {
                    if(bufw != null) 
                        bufw.close();
                } catch (IOException e) {
                    throw e;
                }
            }
                
        }
    
    }

       练习2:用于记录应用程序运行次数,如果使用次数已到,那么给出注册提示。

       分析:

       很容易想到的是:计数器。可是该计数器定义在程序中,随着程序的运行而在内存中存在,并进行自增,可是随着该应用程序的退出,该计数器也在内存中消失了。下一次在启动该程序,又重新开始从0计数。这样不是我们想要的。

       程序即使结束,该计数器的值也存在。下次程序启动会先加载该计数器的值,并+1后重新存储起来。所以要建立一个配置文件,用于记录该软件的使用次数。该配置文件使用键值对的形式,这样便于阅读数据,并操作数据。键值对数据是map集合。数据是以文件形式存储,使用io技术。那么map+io ---> properties。配置文件可以实现应用程序数据的共享。

       代码:

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.Properties;
    
    public class RunCount {
    
        public static void main(String[] args) throws IOException {
            Properties prop = new Properties();
            File file = new File("count.ini");
            if(!file.exists()) 
                file.createNewFile();
            FileInputStream fis = new FileInputStream(file);
            prop.load(fis);
            int count = 0;
            String value = prop.getProperty("time");
            if(value != null) {
                count = Integer.parseInt(value);
                if(count >= 5) {
                    System.out.println("您好,使用次数已到,拿钱!");
                    return;
                } 
            }
            count++;
            prop.setProperty("time", count+"");
            
            FileOutputStream fos = new FileOutputStream(file);
            prop.store(fos, "");
            
            fos.close();
            fis.close();
            
        }
    }

       当然配置文件还有另外一种格式保存,那就是XML,格式如下:

    <persons>
        <person id="001">
            <name>zhangsan</name>
            <age>30</age>
            <address>bj</address>
        </person>
        <person id="002">
            <name>zhangsan1</name>
            <age>31</age>
            <address>bj</address>
        </person>
    </persons>

       一个用来解析XML格式的文件的工具:dom4j,即dom for(four的谐音) java   

       

       合并流

       SequenceInputStream表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。

       它有两个构造函数:

    1. SequenceInputStream(Enumeration<? extends InputStream> e),通过记住参数来初始化新创建的SequenceInputStream,该参数必须是生成运行时类型为InputStream对象的Enumeration型参数。
    2. SequenceInputStream(InputStream s1, InputStream s2),通过记住这两个参数来初始化新创建的SequenceInputStream(将按顺序读取这两个参数,先读取 s1,然后读取s2),以提供从此SequenceInputStream读取的字节。

       示例代码:

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.SequenceInputStream;
    import java.util.Enumeration;
    import java.util.Vector;
    
    public class SequenceDemo {
    
        public static void main(String[] args) throws IOException {
            /*
             * 将3个文件中的数据合并到1个文件中
             */
            Vector<FileInputStream> v = new Vector<FileInputStream>();
            v.add(new FileInputStream("D:\java\io123\1.txt"));
            v.add(new FileInputStream("D:\java\io123\2.txt"));
            v.add(new FileInputStream("D:\java\io123\3.txt"));
            Enumeration<FileInputStream> en = v.elements();
            
            SequenceInputStream sis = new SequenceInputStream(en);
            
            FileOutputStream fos = new FileOutputStream("D:\java\io123\4.txt");
            
            byte[] buf = new byte[1024];
            int len = 0;
            while((len = sis.read(buf)) != -1) {
                fos.write(buf, 0, len);
                
            }
            fos.close();
            sis.close();
        }
    
    }

       有合并文件,那么就有切割文件

       例,切割一张图片,再合成为一张完整的图片。

       代码:

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.SequenceInputStream;
    import java.util.ArrayList;
    import java.util.Enumeration;
    import java.util.Iterator;
    
    public class SplitFile {
    
        public static void main(String[] args) throws IOException {
            //splitFile();
            merge();
        }
        
        /*
         * 合并图片
         */
        public static void merge() throws IOException {
            //使用Vector的效率很低下,所以使用List集合
            ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
            
            for(int x = 1; x < 6; x++) {
                al.add(new FileInputStream("D:\java\io123\split\"+x+".part"));
            }
            /*
             * 匿名内部类访问局部变量,所以要用final修饰
             */
            final Iterator<FileInputStream> it = al.iterator();
            /*
             * 枚举,匿名内部类
             * 虽然见过Enumeration,但是从来没这么写过,这是用ArrayList来实现一个Enumeration。
             * 即使用Enumeration来访问ArrayList。
             */
            Enumeration<FileInputStream> en = new Enumeration<FileInputStream>() {
    
                @Override
                public boolean hasMoreElements() {
                    return it.hasNext();
                }
    
                @Override
                public FileInputStream nextElement() {
                    return it.next();
                }
                
            };
            
            
            SequenceInputStream sis = new SequenceInputStream(en);
            
            FileOutputStream fos = new FileOutputStream("D:\java\io123\ye.JPG");
            
            byte[] buf = new byte[1024];
            
            int len = 0;
            
            while((len = sis.read(buf)) != -1) {
                fos.write(buf, 0, len);
            }
            
            fos.close();
            sis.close();
            
        }
        /*
         * 切割文件(一张图片)
         */
        public static void splitFile() throws IOException {
            FileInputStream fis = new FileInputStream("D:\java\io123\DSC_0206.JPG");
            
            FileOutputStream fos = null;
            byte[] buf = new byte[1024 * 1024];//1MB大小的字节数组
            
            int len = 0;
            int count = 1;
            while((len = fis.read(buf)) != -1) {
                fos = new FileOutputStream("D:\java\io123\split\"+(count++)+".part");
                fos.write(buf, 0, len);
                fos.close();
            }
            fis.close();
        }
    
    }
  • 相关阅读:
    C#对HTTP数据还原
    Nancy.Host的Web应用
    Deep Learning
    业务规则引擎扩展模块
    LB 负载均衡的层次结构(转)
    主要的核心思想是取cookie然后发查询请求,不需要浏览器做代理(转)
    关于java mail 发邮件的问题总结(转)
    使用ping钥匙临时开启SSH:22端口,实现远程安全SSH登录管理就这么简单(转)
    利用Javamail接收QQ邮箱和Gmail邮箱(转)
    android ListView隐藏FooterView(headerView)
  • 原文地址:https://www.cnblogs.com/yerenyuan/p/5272311.html
Copyright © 2020-2023  润新知