XWPFTemplate获取文件流_File


IO流主要是涉及数据源和目标源之间的数据传送和书写。比如网络数据的获取,文件的下载和上传,文件拷贝,控制台的输入输出。

1. File

file是一个文件对象类,这个对象类不仅代表我们常规上的文件,还能代表目录对象。所以就会涉及要判断file是文件还是目录。file 方法相对简单。主要涉及api 如下:

file.mkdir() //创建单级目录
        file.mkdirs()//创建多级目录
        file.getAbsolutePath()//获取绝对路径的文件地址
        file.getName()// 获取文件名称
        file.getParentFile()// 获取父级文件
        file.isDirectory() //是否是目录
        file.isFile()// 是否文件
        file.length()// 文件长度
        file.listFiles() //列出子文件
        file.listFiles(FilenameFilter filenameFilter) // 根据过滤器 返回符合的文件集合
        file.canWrite();// 是否可写
        file.canRead(); // 是否能读
        file.createNewFile();// 创建新文件
        file.delete();// 删除文件
        file.exists();// 文件是否存在

1.1 递归

使用递归的形式,打印各个文件的路径很常见。

/**
     * 递归打印所有根目录下的文件
     * @param dir
     */
    public void printPath(File dir) {

        final File[] files = dir.listFiles();
        if (files == null || files.length == 0) {
            return;
        }
        for (File file : files) {
            Log.d(TAG, "printPath: " + file.getAbsolutePath());

            if (file.isDirectory()) {

                printPath(file);
            }
        }
    }

 /**
     * 使用过滤器过滤所有文件夹下.png的文件
     * @param dir
     */
    public void printFilterFile(File dir) {

        final File[] filters = dir.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return name.endsWith(".png");
            }
        });
        if (filters != null &&filters.length > 0) {
            for (File file : filters) {
                Log.d(TAG, "printPath: " + file.getAbsolutePath());
            }
        }

        for (File file : dir.listFiles()) {

            if (file.isDirectory()) {

                printFilterFile(file);
            }
        }

    }

2. RadomAccessFile

RadomAccessFile是一个独立的类,继承Object,实现了DataOutPut,DataInput接口,适用于已知大小组成的文件,可以使用seek直接定位到文件的具体位置,比如可以用于多线程断点下载,可以从指定的位置输入数据。你可以理解为它是一个文件的容器,支持读取文件和写入文件的操作。当它创建的时候,需要传入mode,一种是读(r),一种是读写(rw),不支持只写操作。也可以通过length()获取文件大小。
常用的api:

readLine() //读取一行数据
seek(pos) //定位到某处
skipBytes(n) //跳过多少字节
write(bytes)//写入字节数组
length()//获取文件大小
close()//关闭

3. 字节流

1.InputStream OutputStream(输入流和输出流)

他们是抽象类,只能继承,定义自己的子类。InputStream代表从数据源读取数据,所以常用的操作方法是read,OutputStream是写入到目标地,所有常用的操作是write。字节流顾名思义就是字节数据,字节数据能表达任何数据,这也是和字符流不一样的地方。字符流只能读取文本文件。它们常用的子类有以下对象。

2.ByteArrayInputStream ByteArrayOutputStream

字节数组流,内部还有一个缓冲区,提高读写效率。能表示多种数据类型,文件类型,网络类型,控制台。

3.ObjectInputStream ObjectOutputStream

对象类型的IO流,多用于序列化对象(把对象的数据写入到磁盘上),和反序列对象(把磁盘上的数据写入的对象上,也就是内存级别的对象)

/**
     * 序列化对象和反序列化
     */
    public void serializ2Obj(){
        final User kk = new User("kk", 11);
        try 
            //------------------------序列化对象---------------------------------
            final File file = new File("/storage/emulated/0/user.tmp");
            if (!file.exists()){
                file.createNewFile();
            }
            final ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(file));

            objectOutputStream.writeObject(kk);

            //------------------------反序列化对象---------------------------------

            final FileInputStream fileInputStream = new FileInputStream(new File("/storage/emulated/0/user.tmp"));
            final ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
            final Object readObject = objectInputStream.readObject();
            Log.d(TAG, "serializ2Obj: "+((User)readObject).toString());
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }

    }

4.FileInputStream FileOutputStream

文件类型流,主要用于读写文件使用。

public void copyFile(){
        final File file = new File("/storage/emulated/0/user.tmp");
        final File outfile = new File("/storage/emulated/0/copyuser.tmp");
        if (!outfile.exists()){
            try {
                outfile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        try {
            final FileInputStream fileInputStream = new FileInputStream(file);
            final FileOutputStream fileOutputStream = new FileOutputStream(outfile);

            byte[] bytes = new byte[1023];
            int len=0;
            while ((len=fileInputStream.read(bytes))!=-1){

                fileOutputStream.write(bytes,0,len);
            }
            fileOutputStream.close();
            fileInputStream.close();


        } catch (IOException e) {
            e.printStackTrace();
        }
    }

4.字符流:

Reader Writer 是读取和写入字符流的抽象类,主要针对文本文件进行读写操作的类,它有很多子类BufferedReader, CharArrayReader, FilterReader, InputStreamReader, PipedReader, StringReader,BufferedWriter, CharArrayWriter, FilterWriter, OutputStreamWriter, PipedWriter, PrintWriter, StringWriter。我们只挑几个常用的。

1.BufferedReader BufferedWriter

这两个对象的特点就是buffered,说明支持缓冲区读取和写入字符内容。
BufferedReader 读取文本到字符输入流,缓冲内容,可以指定缓冲区的大小,或者可使用默认的大小。有一些常用方法。如read(),readLine() ready():是否准备好读取,skip(n)跳过字符。

BufferedWriter将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。可以指定缓冲区的大小,或者接受默认的大小。该类提供了 newLine() 方法,进行换行。当然也有write方法。

2. InputStreamReader OutputStreamWriter

InputStreamReader 是字节流通向字符流的桥梁,也可以设置字符的编码类型。常用的api不多,read()读取单子字符,read(char[] c) 读取字符数组。
OutputStreamWriter 是字符流通向字节流的桥梁,也就是把字符流转换成字节流,当然也可以设置不同的编码形式,可以参考它的构造方法。write 写入字符,getEncoding() 获取编码名称。

3. FileReader FileWriter

FileReader FileWriter是InputStreamReader OutputStreamWriter的子类,主要用于处理文本文件的。

FileReader用来读取字符文件的便捷类。此类的构造方法是使用默认字符编码和默认字节缓冲区大小。
FileWriter用来写入字符文件的便捷类。提供的方法不多,该对象的构造提供File,追加字符串内容。

4.StringReader StringWriter

StringReader是一个字符写入流,提供read() skip() 跳过字符,StringWriter一个字符流,可以用其回收在字符串缓冲区中的输出来构造字符串。可以使用append© 追加字符内容。wirite 写入字符或者字符串。

5. 关闭流方法

这里的关闭流操作,其实是一个封装,因为字符流字节流四个对象都实现了Closeable接口,提供关闭功能,所以可以以多参的形式,迭代关闭。

public static void closeStream(Closeable...stream){

        for(Closeable  item:stream){

            try {
                item.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }