Java | IO

1.IO开篇
2.文件与文件夹
3.四大抽象类
4.标准步骤
5.文件字节流 FileInputStream FileOutputStream
6.文件字符流 FileReader FileWriter
7.字节数组流ByteArrayInputStream ByteArrayOutputStream
8.装饰器设计模式
9.字节缓冲流BufferedInputStream BufferedOutputStream
10.字符缓冲流BufferedReader BufferedWriter
11.转换流
12.数据流
13.对象流
14.打印流
15.序列流
16.随机流 RandomAccessFile
17.CommonsIO

1.IO开篇

分类

  • 按处理对象分
    • 字节流(是给计算机看的)
    • 字符流(是给人看的)
  • 按流向分(输入输出是相对于程序的,以程序为中心)
    • 输入流(从音视频,txt,word等文件读到程序中)
    • 输出流(冲程序写出到文件)
  • 按功能分
    • 节点流(始终位于数据处理的一线)
    • 处理流(使用了装饰器设计模式的流)

常见流

FileInputStream FileOutputStream

ByteArrayInputStream ByteArrayOutputStream

FileReader FileWriter

BufferedInputStream BufferedOutputStream

InputStreamReader OutputStreamWriter

DataOutputStream DataInputStream

ObjectInputStream ObjectOutputStream

PrintStream PrintWriter

RandomAccessFile

SequenceInputStream


编码与解码

编码:由字符到字节

解码:由字节到字符

public class EncodeAndDecode {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String msg = "性命生命使命";
        //编码:默认使用工程的字符集
        byte[] datas = msg.getBytes("gbk");

        System.out.println(datas.length);

        //解码
        String newmsg = new String(datas,0,datas.length,"gbk");
        System.out.println(newmsg);

    }
}

常见乱码原因

  • 字节数不够
  • 字符集不同

2.文件与文件夹

构造一个文件对象

        String path = "IO.png";

        //构造一个文件对象的方法
        //1.该文件的路径
        File f1 = new File(path);
        System.out.println("f1:" + f1.length());

        //2.父路径 + 子路径
        String parent_path = "D:/";
        String chile_path = "IO.png";
        File f2 = new File(parent_path,chile_path);
        System.out.println("f2:" + f2.length());

        //3.父对象 + 子路径
        File f3 = new File(new File(parent_path), chile_path);
        System.out.println("f3:" + f3.length());

        System.out.println("项目路径:" + System.getProperty("user.dir"));

测试文件对象相关的功能

public class TestFileFunction  {
    public static void main(String[] args) throws IOException {
        String pathname = "IO.png";
        File f = new File(pathname);

        System.out.println("文件名称:" + f.getName());
        System.out.println("文件路径:" + f.getPath());
        //getPath返回文件路径,构造文件对象时使用的是绝对路径,就返回绝对路径,构造时使用的是相对路径,则返回相对路径

        System.out.println("绝对路径:" + f.getAbsolutePath());
        //返回file的绝对路径

        System.out.println("父对象路径:" + f.getParent());
        //返回构造file文件对象是使用的path中文件名之前的路径,存在则返回,不存在返回null

        System.out.println("是否存在:" + f.exists());
        System.out.println("是否是文件:" + f.isFile());
        System.out.println("是否是文件夹:" + f.isDirectory());
        //只要file对象存在时判断是文件还是文件夹才有意义

        System.out.println("文件的大小:" + f.length());
        //返回文件大小,若是文件夹或者不存在,返回0

        File newfile = new File("text");
        boolean flag = newfile.createNewFile();
        System.out.println("新文件是否创建成功:" + flag);
        //createNewFile函数用来创建新的文件,如果file对象不存在,则创建,如果存在,则返回false
        //如果创建file对象是给的pathname参数是一个目录,那么该函数会创建一个没有后缀的文件(名称为pathname所给的字符串)
        //注意:该函数不能创建一些与底层操作系统关键字相同的文件,如con,con3

        flag = newfile.delete();
        System.out.println("文件是否删除成功:" + flag);
    }
}

3.四大抽象类

适用音视频,图片,word等文件

  • InputStream 字节输入流
  • OutputStream 字节输出流

适用纯文本文件

  • Reader 字符输入流
  • Writer 字符输出流

能用字符流处理的一定能用字节流处理
反之,用字节流处理的不一定能用字符流处理,如图片等


4.标准步骤

  1. 创建源
  2. 选择流
  3. 具体操作
  4. 释放资源

5.文件字节流

可以处理任何类型的文件

构造器参数可以是文件对象,也可以是文件路径String path

FileInputStream一个一个字符的读取

public class IOInputByOne {
    public static void main(String[] args) {
        String path = "src.txt";
        //创建源
        File file = new File(path);

        //选择流
        InputStream in = null;
        try {
            in = new FileInputStream(file);
            int temp;

            //具体操作      一个一个的读取,in.read()里面没有参数
            while((temp = in.read()) != -1){
                System.out.println((char)temp);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            try {
                //释放资源
                if(in!=null)
                    in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

FileInputStream一卡车一卡车的读(为了提高读取速率,先设置一个容器,将内容读到容器内,当容器满时,再将容器中的内容写到文件中去)

为避免文件最后的一段内容(小于容器容量)滞留再内存中,要进行强制刷新操作out.flush()。

public class IOOutputByFlush {
    public static void main(String[] args) {
        String path = "dest.txt";

        //创建源
        File file = new File(path);

        //选择流
        OutputStream out = null;
        try {
            out = new FileOutputStream(file, true);
            //append:是否追加

            String msg = "this is a msg!
";

            //编码
            byte[] flush = msg.getBytes("utf8");

            out.write(flush,0, flush.length);
            out.flush();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(out!=null)
                {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

FileOutputStream将数据写到文件中去

public class IOOutputByFlush {
    public static void main(String[] args) {
        String path = "dest.txt";

        //创建源
        File file = new File(path);

        //选择流
        OutputStream out = null;
        try {
            out = new FileOutputStream(file, true);
            //append:是否追加

            String msg = "this is a msg!
";

            //编码
            byte[] flush = msg.getBytes("utf8");

            out.write(flush,0, flush.length);
            out.flush();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(out!=null)
                {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}


6.文件字符流

用于处理文件,仅限纯文本类型

FileReader 测试

public class Test_File_Read {
    public static void main(String[] args) {
        String path = "src.txt";
        File src = new File(path);

        Reader reader = null;
        try {
            reader = new FileReader(src);
            char[] flush = new char[1024];
            int len = -1;
            while((len=reader.read(flush))!=-1){
                String msg = new String(flush);
                System.out.println(msg);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(reader!=null)
                    reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

FileWriter测试

public class Test_File_Writer {
    public static void main(String[] args) {
        String path = "dest.txt";

        File dest = new File(path);
        Writer writer = null;
        try {
            writer = new FileWriter(dest);

            //写法一
            String msg = "I'm destination!我是目的地!!!";
            char[] flush = msg.toCharArray();
            writer.write(flush);
            writer.flush();

            //写法二
            String msg = "I'm destination!我是目的地!!!";
            writer.write(msg,0,msg.length);
            writer.flush();

            //写法三
            String msg = "I'm destination!我是目的地!!!";
            writer.append(msg).append("追加内容!");
            //append返回this对象,可以链式调用
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(writer!=null)
                    writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

7.字节数组流

用于处理字节数组
该流直接操作电脑内存,由JVM进行GC操作,不需要通知OS关闭,不像文件流Java程序不能直接操作系统资源,需要与操作系统OS打交道,让OS去释放相关资源。

它的close函数是一个空方法

1589729882211

ByteArrayInputStream测试

        //1.创建源
        String msg = "这是一段文本!";
        byte[] src = msg.getBytes();

        //2.选择流
        InputStream in = null;
        in = new ByteArrayInputStream(src);//传入字节数组
        byte[] flush = new byte[6];
        int len = -1;
        try{
            while((len=in.read(flush))!=-1){
                String str = new String(flush,0,len);
                System.out.println(str);
            }
        }
        catch (IOException e){
            e.printStackTrace();
        }
        finally {
            try {
                if(in!=null)
                    in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

ByteArrayOutputStream测试

        //1.创建源
        byte[] dest = null;

        //2.选择流,不用关联源
        ByteArrayOutputStream out = null;
        try{
            out = new ByteArrayOutputStream();
            //构造器不需要参数,它会自动的指定相关的地址,如果手的指定的话,大小不易确定,不好控制

            String msg = "show me the code!";
            byte[] datas = msg.getBytes();
            out.write(datas,0,datas.length);
            out.flush();

            //使用toByteArray函数获取字节数组流的相关数据
            dest = out.toByteArray();
            String dest_str = new String(dest,0,dest.length);
            System.out.println(dest_str);
        }catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(out!=null)
                    out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

8.装饰器设计模式

节点流永远在一线,但为了能够更加灵活方便且高效的处理数据,我们通过一个间接流去调用(装饰)节点流,这个间接流称之为处理流或者装饰流。采用了装饰器设计模式。

装饰器的四个部分:

  1. 抽象组件
  2. 具体组件
  3. 抽象装饰类
  4. 具体装饰类

装饰器设计模式的体验

public class TestDecorate {
    public static void main(String[] args) {
        Drink coffee = new Coffee();
        Drink coffee_milk = new Milk(coffee);
        System.out.println(coffee_milk.info() + "	花费:" + coffee_milk.cost());
        Drink coffee_suger = new Suger(coffee);
        System.out.println(coffee_suger.info() + "	花费:" + coffee_suger.cost());
        Drink coffee_milk_suger = new Suger(coffee_milk);
        System.out.println(coffee_milk_suger.info() + "	花费:" + coffee_milk_suger.cost());
    }
}

/**
 * 抽象组件
 */
interface Drink{
    double cost();
    String info();
}

/**
 * 具体组件
 */
class Coffee implements Drink{
    String name = "原味咖啡";

    @Override
    public double cost() {
        return 10;
    }

    @Override
    public String info() {
        return name;
    }
}

/**
 * 抽象装饰类
 */
abstract class Decorate implements Drink {
    //对抽象组件的引用
    private Drink drink;

    public Decorate(Drink drink) {
        this.drink = drink;
    }

    @Override
    public double cost() {
        return this.drink.cost();
    }

    @Override
    public String info() {
        return this.drink.info();
    }
}

/**
 * 具体装饰类Milk
 */
class Milk extends Decorate{

    public Milk(Drink drink) {
        super(drink);
    }

    @Override
    public double cost() {
        return super.cost()*4;
    }

    @Override
    public String info() {
        return super.info() + "加奶";
    }
}

/**
 * 具体装饰类Suger
 */
class Suger extends Decorate{
    public Suger(Drink drink) {
        super(drink);
    }

    @Override
    public double cost() {
        return super.cost() * 2;
    }

    @Override
    public String info() {
        return super.info() + "加糖";
    }
}
1589731203358

9.字节缓冲流

BufferedInputStream,BufferedOutputStream

处理流,可以提高数据读写速度,但只能提高一次,无论嵌套几次,都只提高一次效率

        File src = new File(srcPath);
        File dest = new File(destPath);
        InputStream in = null;
        OutputStream out = null;
        try {
            in = new BufferedInputStream(new FileInputStream(src));
            out = new BufferedOutputStream(new FileOutputStream(dest));
            //处理流这么用就行了,先new一个处理流对象,里面参数传一个节点流对象
            byte[] flush = new byte[1024];
            int len = -1;
            while ((len=in.read(flush)) != -1){
                out.write(flush,0,flush.length);
                out.flush();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //释放资源遵循先打开后关闭的原则,也可以直接关闭外层的流
            //再关闭外层流的时候,其底层也会先找到关闭内部流
            try {
                if(out!=null)
                    out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(in!=null)
                    in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

10.字符缓冲流

BufferedReader,BufferedWriter

用于处理纯文本数据,如果是音视频等文件,则无法处理

JDK的try...with...resource功能,在try后面借一个括号,在括号里面声明流,多个流以分号";"分隔

这样写的好处是我们不再需要自己手动去关闭流,jdk会自动帮我们关闭

        File src = new File(srcPath);
        File dest = new File(destPath);
        try(BufferedReader br = new BufferedReader(new FileReader(src));
            BufferedWriter bw = new BufferedWriter(new FileWriter(dest))) {
            String line = null;
            while ((line = br.readLine()) != null){
                bw.write(line);
                bw.newLine();
                bw.flush();
                //readLine读取一行,返回值String
                //newLine相当于"
",不用在字符串末尾加
了
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

11.转换流

BufferedReader,BufferedWriter

换流是字节流与字符流的桥梁,只有在处理纯文本的时候才能将字节流转换为字符流,在转换为字符流之后,我们又可以为了提高效率在外层加上一层BufferedReader或者BufferedWriter

try(BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out))) {
    String msg = "";
    while(!msg.equals("exit")) {
         msg = reader.readLine();
         writer.write(msg);
         writer.newLine();
         writer.flush();
    }
}catch (IOException e){
     e.printStackTrace();
}

12.数据流

DataOutputStream,DataInputStream

先写出后读取

1.读取顺序要和写出顺序保持一致,否则报错

2.使用了BufferedOutputStream来提高效率的话,切记要在写完后flush一下,否则也用可能报错 使用了缓冲区的任何流最后在写完数据之后flush一下,避免数据滞留在缓冲区,未完全写入,从而出现各种错误

public class TestDataIO {
    public static void main(String[] args) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(baos));
        dos.writeUTF("i'm string!");	 //写字符串
        dos.writeInt(18);			    //写int型
        dos.writeBoolean(false);		//写boolean型
        dos.flush();
        byte[] datas = baos.toByteArray();
        System.out.println(datas.length);


        DataInputStream dis = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(datas)));
        String msg = dis.readUTF();
        int age = dis.readInt();
        boolean flag = dis.readBoolean();
        System.out.println("msg:" + msg + "
age:" + age + "
flag:" + flag);
    }
}


13.对象流

ObjectOutputStream,ObjectInputStream

由对象到文件(txt,数据库文件等) 序列化(也称持久化)

由文件到对象 反序列化

不是所有的对象都可以实现序列化,只有实现了java.io.Serializable接口的类才可以序列化

instanceof关键字,判断某对象是否是某个类的实例

transient关键字,透明,如果类中的某个属性比较敏感,不想再序列化的时候保存, 则可以加上此关键字,最后获取该属性的时候即变为透明,基本类型为默认值,对象为null

public class TestObject {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("obj.txt")));
        Emplayee e1 = new Emplayee(1001, "张三", 20000);
        Emplayee e2 = new Emplayee(1002, "李四", 2000);
        Emplayee e3 = new Emplayee(1003, "王五", 2000);
        Emplayee e4 = new Emplayee(1004, "赵六", 2000);
        oos.writeObject(e1);
        oos.writeObject(e2);
        oos.writeObject(e3);
        oos.writeObject(e4);
        Date d = new Date();
        oos.writeObject(d);
        oos.flush();


        ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream("obj.txt")));
        Object o1= ois.readObject();
        Object o2 = ois.readObject();
        Object o3 = ois.readObject();
        Object o4 = ois.readObject();
        Object date_obj = ois.readObject();
        System.out.println(o1);
        System.out.println(o2);
        System.out.println(o3);
        System.out.println(o4);
        if(date_obj instanceof Date){
            System.out.println((Date)date_obj);
        }
        ois.close();
        oos.close();
    }
}


14.打印流

PrintStream 对OutputStream处理

PrintWriter 增加对Writer out的处理

PrintStream

public class TestPrintStream {
    public static void main(String[] args) throws FileNotFoundException {
        PrintStream ps = new PrintStream(new BufferedOutputStream(new FileOutputStream("print.txt")),true);
        ps.println(false);
        ps.println("hello, future!");

        //重定向输出端到文件里
        System.setOut(ps);
        System.out.println("change");//此时change会被写入到print.txt文件中

        //重定向输出到控制台
        System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)), true));
        System.out.println("i'm back");
        ps.close();
    }
}

PrintWriter

public class TestPrintWriter {
    public static void main(String[] args) throws FileNotFoundException {
        PrintWriter pw = new PrintWriter(new BufferedOutputStream(new FileOutputStream("printWriter.txt")));
        pw.println("future");
        pw.println(2022);
        pw.close();

    }
}

15.序列流

如果有多个流,将多个流放到一个容器中,再将容器丢入序列流,从而把对多个流的处理简化成对一个流的处理

public class TestSequence {
    private String outPath;//输出文件
    private String srcDirs;//输入文件夹
    private List<String> srcPaths;
    private File filesDir;

    public TestSequence(String srcDirs, String outPath) {
        this.outPath = outPath;
        this.srcDirs = srcDirs;
        this.filesDir = new File(srcDirs);
        this.srcPaths = new ArrayList<>();

        for(File temp: filesDir.listFiles()){
            srcPaths.add(temp.getName());
        }
    }

    public void meger() throws IOException {
        OutputStream os = new BufferedOutputStream(new FileOutputStream(outPath));
        Vector<InputStream> vi = new Vector<>();//容器
        for(int i=0;i<srcPaths.size();i++){
            vi.add(new BufferedInputStream(new FileInputStream("dest/" + srcPaths.get(i))));
        }
        
        //序列流
        SequenceInputStream sis = null;
        sis = new SequenceInputStream(vi.elements());

        //拷贝文件到一个文件里
        byte[] flush = new byte[1024];
        int len = -1;
        while ((len=sis.read(flush))!=-1){
            os.write(flush,0,len);
        }
        os.flush();
        sis.close();
        os.close();
    }

    public static void main(String[] args) throws IOException {
        TestSequence ts = new TestSequence("dest","i'm.txt");
        ts.meger();
    }
}


16.随机流

RandomAccessFile 使用seek()函数设置起始位置偏移量

通过构造器的第二个参数mode为"r"还是"rw"区分读文件还是写文件

        RandomAccessFile raf = new RandomAccessFile(this.src,"r");
        RandomAccessFile raf2 = new RandomAccessFile(this.destPaths.get(i) ,"rw");
        //起始位置偏移
        raf.seek(beginPos);

        byte[] flush = new byte[1024];
        int len = -1;
        while ((len=raf.read(flush))!=-1){
            if(realSize>len){
                raf2.write(flush,0,len);
                realSize -= len;
            }else {
                raf2.write(flush,0,realSize);
                break;
            }
        }

17.CommonsIO

下载地址:https://mirrors.tuna.tsinghua.edu.cn/apache//commons/io/binaries/commons-io-2.6-bin.zip

导入:将下载下来的zip解压,把里面的commons.io.jar和sources.jar复制到项目中的lib文件夹,然后右键

idea:

eclipse:bulid path---->add to path

测试基本功能:

public class TestCIO {
    public static void main(String[] args) {
        //文件大小
        long len = FileUtils.sizeOf(new File("IO.png"));
        System.out.println(len);

        //文件夹大小
        len = FileUtils.sizeOf(new File("src"));
        System.out.println(len);

        //子孙文件
        Collection<File> files = FileUtils.listFiles(new File("D:\IDEA_Workspace\Sxt_Java_Study\src\IO_Study_CLL"),
                EmptyFileFilter.NOT_EMPTY,null);
        for(File file: files){
            System.out.println(file.getPath());
        }

        /**
         * FileFilterUtils      文件过滤的工具,有or,and
         * EmptyFileFilter      空文件过滤工具,有为空,不为空选项
         * SuffixFileFilter     文件后缀过滤工具
         * DirectoryFileFilter  目录过滤工具,.INSTANCE表示所有子孙集
         */
        files = FileUtils.listFiles(new File("D:\IDEA_Workspace\Sxt_Java_Study\src\IO_Study_CLL"),
                FileFilterUtils.and(new SuffixFileFilter("java"), EmptyFileFilter.NOT_EMPTY), DirectoryFileFilter.INSTANCE);
        for(File file: files){
            System.out.println(file.getPath());
        }
    }
}

测试文件拷贝

/**
 * 复制文件
 *
 * 注意事项:
 * copyDirectory仅仅是复制目录里面的内容
 * copyDirectoryToDirectory是将源目录作为子目录复制到目的目录里面去
 */
public class testCIOCopy {
    public static void main(String[] args) throws IOException {
        //复制文件
        FileUtils.copyFile(new File("D:\IDEA_Workspace\Sxt_Java_Study\src\TestCommonsIO\IO.png"), new File("D:\IDEA_Workspace\Sxt_Java_Study\src\TestCommonsIO\IO-copy.png"));
        //复制目录
        FileUtils.copyDirectory(new File("random"), new File("random-copy"));
        //复制文件到目录
        FileUtils.copyFileToDirectory(new File("hello.txt"), new File("random"));
        //复制目录到目录
        FileUtils.copyDirectoryToDirectory(new File("random"), new File("random-parent"));
        //拷贝URL内容
        String url = "http://img.netbian.com/file/2019/1216/9cc8ee311939ec9bfcf9a30a7eb380bc.jpg";
        FileUtils.copyURLToFile(new URL(url), new File("net.jpg"));

        //拷贝url到String
        String data = IOUtils.toString(new URL("http://www.baidu.com"), "utf8");
        System.out.println(data);
    }
}

测试读取文件

/**
 * 测试读取文件
 */
public class testCIOread {
    public static void main(String[] args) throws IOException {
        File file = new File("D:\IDEA_Workspace\Sxt_Java_Study\src\TestCommonsIO\shi.txt");

        //读取到字符串中
        String shi = FileUtils.readFileToString(file,"utf8");
        System.out.println(shi);

        //读取到字符数组中
        byte[] shi2 = FileUtils.readFileToByteArray(file);


        //逐行读取
        List<String> shi3 = FileUtils.readLines(file,"utf8");
        for(String temp: shi3){
            System.out.println(temp);
        }

        //类似迭代器
        LineIterator iter = FileUtils.lineIterator(file,"utf8");
        while (iter.hasNext()){
            System.out.println(iter.nextLine());
        }
    }
}

测试写入文件

/**
 * 测试CIO写文件
 */
public class testCIOwrite {
    public static void main(String[] args) throws IOException {
        String outPath = "D:/IDEA_Workspace/Sxt_Java_Study/src/TestCommonsIO/output.txt";
        File outFile = new File(outPath);

        String data = "学习是一件幸福的事情!
";
        //写String数据
        FileUtils.write(outFile,"学习是一件伟大的事业!
","utf8");
        FileUtils.writeStringToFile(outFile,"学习是一件辛苦的事情!
","utf8",true);
        //true->追加

        //写byte数组
        FileUtils.writeByteArrayToFile(outFile,data.getBytes("utf8"),0,data.getBytes().length,true);

        //写list集合
        List<String> list = new ArrayList<>();
        for(int i=0;i<10;i++){
            list.add(i + "	");
        }
        FileUtils.writeLines(outFile,list,"
",true);
        //第三个参数"
"是list元素与元素之间的间隔字符串
    }
}

原文地址:https://www.cnblogs.com/leerep/p/12908001.html