黑马程序员——java基础——IO流(二)

来源:互联网 发布:qq直播是什么软件 编辑:程序博客网 时间:2024/05/25 19:56

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——

File类:用来将文件或者文件夹封装成对象,方便对文件和文件夹进行操作
File对象可以作为参数传递给流的构造函数

File对象的一些功能
File类常见方法:
1,创建。
boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false。
和输出流不一样,输出流对象一建立创建文件。而且文件已经存在,会覆盖。
boolean mkdir():创建文件夹。
boolean mkdirs():创建多级文件夹。
2,删除。
boolean delete():删除失败返回false。如果文件正在被使用,则删除不了返回falsel。
void deleteOnExit();在程序退出时删除指定文件。
3,判断。
boolean exists() :文件是否存在.
boolean isFile(): 是否是文件
boolean isDirectory();是否是目录
boolean isHidden(); 是否隐藏
boolean isAbsolute(); 测试此抽象路径名是否为绝对路径名
4,获取信息。
String getName(): 获取文件名
String getPath(): 获取路径,就是建立文件对象时所传入的路径
String getParent(): 获取path路径的父路径
String getAbsolutePath():获取绝对路径
long lastModified():返回此抽象路径名表示的文件最后一次被修改的时间。
long length():返回由此抽象路径名表示的文件的长度

//过滤出f盘下所需要类型的文件import java.io.*;class FileDemo {    public static void main(String[] args)     {        method();    }    //需求。过滤出F盘下的jpg文件    public static void method()    {        File dir = new File("f:\\");        //通过匿名内部类的形式完成        String[] name = dir.list(new FilenameFilter()//这是一个过滤器,通过返回true过滤出需要的文件类型        {            public boolean accept(File dir,String name)            {                /*                if(name.endsWith(".jpg"))                    return true ;                return false ;                */                return name.endsWith(".jpg");            }        });        for(String str : name)        {            System.out.println(str);        }    }}

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

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

//带层次的递归目录import java.io.*;class FileDemo2{    public static void main(String[] args)     {        File dir = new File("f:\\java002");        showDir(dir,0);    }    //插入分级符    public static String getLevel(int level)    {        //通过定义一个容器来加入分级符        StringBuilder sb = new StringBuilder();        sb.append("|--");        for (int x=0 ;x<level ;x++ )        {            sb.insert(0,"  ");//在容器的第一个位置加入空格,其余的元素往后推            //目的在于当存在多级目录时,只在目录的前面加分级符,再往前用空格表示        }        return sb.toString();    }    public static void showDir(File dir,int level)    {        System.out.println(getLevel(level)+dir.getPath());//带着父目录打印,打印的是目录        level++;//每次调用showDir时,就是进入了一个新的目录,所以分级符需要自增        File[] files = dir.listFiles();        for (File file : files )        {            if (file.isDirectory())                showDir(file,level);//代表进入了一个新的目录中            else            System.out.println(getLevel(level)+file.getName());            //打印的是文件,在这里getName()方法打印的是文件名,不包括目录名        }    }}

将指定目录下的.java文件的路径全部存到一个文件中
思路:
1.递归指定的目录,并找到.java的文件
2.将.java文件都存到集合中
3.获取集合中文件的路径并将路径写入指定的文件中

import java.io.*;import java.util.*;class FileToList {    public static void main(String[] args)     {        File dir = new File("f:\\java002");        List<File> list = new ArrayList<File>();        File file = new File(dir,"javalist.txt");        fileToList(dir,list);        listToFile(list,file);    }    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"))                {                    //System.out.println(file.getName());                    //存入的是文件名                    list.add(file);                }            }        }    }    public static void listToFile(List<File> list,File file)     {        BufferedWriter bufw = null;        try        {            bufw = new BufferedWriter(new FileWriter(file));//建立对象必须放在for循环的外面,不然每次循环的时候会把以前建立的文件覆盖            for (File f : list )//循环里面不能有关闭流的动作,否则将不能写入了            {                String path = f.getAbsolutePath();                //System.out.println(s);                bufw.write(path);                bufw.newLine();//一定要换行                bufw.flush();            }        }        catch (Exception e)        {            throw new RuntimeException("写入失败");        }        finally        {            try            {                if(bufw!=null)                    bufw.close();            }            catch (Exception e1)            {                throw new RuntimeException("资源关闭失败");            }        }    }}

Properties 是Hashtable的一个子类,也就是说它是一个Map集合
Properties 集合中所有的键值对都是String类型,所以不用加泛型
Properties 可以与流技术相结合

Properties集合与流相结合的运用
需求:记录一个程序的运行次数,若次数超过三次就给出注册提示
思路:
在硬盘上创建一个临时文件,用于记录程序运行的次数,每次程序运行后次数自增然后保存。程序运行时会对配置文件进行操作,可以将文件内容存储到集合中然后进行操作
想到Properties集合,可以与流相结合

import java.io.*;import java.util.*;class RunCount{    public static void main(String[] args)     {        Properties prop = new Properties();        File file = new File("count.ini");        FileInputStream fis = null;        try        {            if(!file.exists())                file.createNewFile();            fis = new FileInputStream(file);            prop.load(fis);//从输入流中读取属性列表(键和元素对)。        }        catch (Exception e)        {            throw new RuntimeException();        }        finally         {            try            {                if(fis!=null)                    fis.close();            }            catch (Exception e2)            {                throw new RuntimeException();            }        }        int count = 0 ;        String value = prop.getProperty("times");//通过键取值,键设置为times        if(value!=null)            count = Integer.parseInt(value);//count为int类型,所以需要包装成对应的类         count++;        if(count>3)            {                System.out.println("使用次数已到");                return ;            }        //将键和对应的值存入集合中,虽然改变了集合中的内容,但是原文件中的内容并没有改变        prop.setProperty("times",count+"");        FileOutputStream fos = null;        try        {            //建立操作原文件的流对象并通过集合的store方法,可以将集合中的内容保存到文件中            fos = new FileOutputStream(file);            prop.store(fos,"cishu");        }        catch (Exception e2)        {            throw new RuntimeException();        }        finally         {            try            {                if(fos!=null)                    fos.close();            }            catch (Exception e3)            {                throw new RuntimeException();            }        }    }}

其他的一些流:

打印流:
该流提供了打印方法,可以将各种数据类型的数据都原样打印。
字节打印流:PrintStream
构造函数可以接收的参数类型:
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream
字符打印流:PrintWriter
构造函数可以接收的参数类型:
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream
4,字符输出流,Writer。

合并流:SequenceInputStream,一个输出流要对应多个输入流,要用到Enumeration
切割流:一个输入流对应多个输出流,就是在循环中创建新的输出流

对对象进行操作的流:ObjectInputStream ObjectOutputStream

管道流:PipedInputStream PipedOutputStream 需要用到多线程,并且其输入流和输出流要相互关联

可以用于操作基本数据类型的数据的流对象:DataInputStream与DataOutputStream

RandomAccessFile
该类不是算是IO体系中子类。而是直接继承自Object。但是它是IO包中成员。因为它具备读和写功能。
其内部封装了一个数组,而且通过指针对数组的元素进行操作。可以通过getFilePointer获取指针位置,同时可以通过seek改变指针的位置。
其实完成读写的原理就是内部封装了字节输入流和输出流。
通过构造函数可以看出,该类只能操作文件。而且操作文件还有模式:只读r ,读写rw等。如果模式为只读 r,不会创建文件,会去读取一个已存在文件,如果该文件不存在,则会出现异常。如果模式rw,操作的文件不存在,会自动创建。如果存在则不会覆盖。

用于操作字节数组的流对象。
ByteArrayInputStream:在构造的时候,需要接收数据源,而且数据源是一个字节数组。
ByteArrayOutputStream:在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组,这就是数据目的地。
因为这两个流对象都操作的数组,并没有使用系统资源,所以,不用进行close关闭。
源设备:内存 ArrayStream。
目的设备:内存 ArrayStream。

//编码:字符串-->字节数组  String -->byte[]//解码:字节数组-->字符串  byte[]-->Stringimport java.util.*;class EncodeDemo{    public static void main(String[] args) throws Exception    {        String s = "你是谁";        byte[] b = s.getBytes("gbk");        System.out.println(Arrays.toString(b));//Arrays.toString()是将字节数组中的内容直接打印出来        String s1 = new String(b,"iso8859-1");//new String()是将字节数组中的内容解码后返回一个字符串        System.out.println(s1);        byte[] b1 = s1.getBytes("iso8859-1");        System.out.println(Arrays.toString(b1));        String s2 = new String(b1,"gbk");        System.out.println(s2);        //用gbk编码后,用iso8859-1解码出现了乱码,这时需要用iso8859-1重新编码后再用gbk解码        //注意:gbk的编码用utf-8解码出现问题后,不能用utf-8编码后再用gbk解,因为gbk和utf-8都识别中文    }}

能实现编码转换的流:InputStreamReader OutputStreamWriter
InputStreamReader(InputStream in, String charsetName)
OutputStreamWriter(OutputStream out, String charsetName)
读取文件时所用的码表必须要和文件写入时所用的码表一致,否则会乱码

0 0