使用IO流写文件的一些骚操作

序言

当需要对文件进行操作时,使用IO流是不能避免的操作;比如业务中需要存储一些请求的响应结果中的一些内容。当所需处理的文件过大时,如果频繁的关闭文件流,会造成很大的开销,何时关闭?往往会造成比较大的困扰。那么如何才能比较优雅的处理文件呢?

使用案例

情景

存储数据时,行与行之间使用回车符隔开;一行的数据字段之间使用Tab键隔开

代码地址

https://github.com/mmzsblog/IO-demo

解决方案一:

使用apache提供的工具类IOUtil可以方便快捷的处理这个问题,这个工具类封装了很多方法

  • 引入apache工具类IOUtil的依赖包
    <dependencies>
        <!-- apache提供的一个IO工具类 -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>
    </dependencies>

    <repositories>
        <repository>
            <id>alimaven</id>
            <name>aliyun maven</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
  • 主要代码如下:
public static void main(String[] args) {

    List<String> list = new ArrayList();
    list.add("hello");
    list.add("third");
    list.add("method");
    list.add("io");
    list.add("util");
    OutputStream os = null;
    File filePath = new File("d:\\" + DateUtil.getCurrentDate("yyyyMMdd") + ".txt");

    try {
        os = new FileOutputStream(filePath, true);
        //一行中的字段用tab隔开
        IOUtils.writeLines(list,"\t",os);
        //行与行之间用回车隔开
        IOUtils.write("\n", os);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

解决方案二:

  • 主要代码如下:
    public static void main(String[] args) {

        File filePath = new File("d:\\" + DateUtil.getCurrentDate("yyyyMMdd") + ".txt");

        //将数据保存到StringBuffer中后再存储到文件中
        List<String> list = new ArrayList();
        list.add("hello");
        list.add("second");
        list.add("method");
        list.add("io");
        list.add("util");
        //因为此处不涉及线程安全问题,所以用了StringBuilder
        StringBuilder sb = new StringBuilder();
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String item = iterator.next();
            sb.append(item).append("\t");
        }
        String newTxt = sb.deleteCharAt(sb.length()-1).append("\n").toString();

        BufferedWriter bw = null;
        try {
            //true表示文件写入方式为追加;flase表示是覆盖
            bw = new BufferedWriter(new FileWriter(filePath, true));
            bw.write(newTxt);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (null != bw) {
                try {
                    bw.flush();
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

解决方案三:

  • 主要代码如下:
public class IOFirst {

    /**
     * description: 最复杂,但也是比较考验基本功的写法
     * author: mmzsit
     * date: 2018/12/27 17:45
    */
    public static void main(String[] args)
    {
        File log=new File("d:\\"+DateUtil.getCurrentDate("yyyyMMdd") +".txt");
        List<String> list = new ArrayList();
        list.add("hello");
        list.add("first");
        list.add("method");
        list.add("io");
        list.add("util");
        //因为此处不涉及线程安全问题,所以用了StringBuilder
        StringBuilder sb = new StringBuilder();
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String item = iterator.next();
            sb.append(item).append("\t");
        }
        String newLog = sb.deleteCharAt(sb.length()-1).toString();
        //调用appendLog方法执行文件写入操作
        appendLog(log,newLog);
    }

    /**
     * description: 此种方式是自己写的类,想怎么操作按自己的意思来
     * author: mmzsit
     * date: 2018/12/27 17:42
    */
    public static void appendLog(File filePath,String newTxt)
    {
        Scanner sc=null;
        PrintWriter pw=null;
        try{
            isExists(filePath);
            sc=new Scanner(filePath);
            StringBuilder sb=new StringBuilder();
            //先读出旧文件内容,并暂存sb中;
            while(sc.hasNextLine())
            {
                sb.append(sc.nextLine());
                //换行符作为间隔,扫描器读不出来,因此要自己添加.
                sb.append("\t\n");
            }
            if (0 != sb.length()) {
                //解决每次多余的空行
                sb.deleteCharAt(sb.length()-1);
            }
            sc.close();

            pw=new PrintWriter(new  FileWriter(filePath),true);
            //A、写入旧文件内容.
            pw.println(sb.toString());
            //B、写入新文件内容
            pw.println(newTxt);
            /*
             * 如果先写入A,最近写入在文件最后.
             * 如是先写入B,最近写入在文件最前.
             */
            pw.close();
        }
        catch(IOException ex)
        {
            ex.printStackTrace();
        }
    }

    /**
     * description: 保证文件夹的存在
     * author: mmzsit
     * date: 2018/12/27 17:42
    */
    public static void isExists(File filePath){
        //如果文件不存在,则新建.
        if(!filePath.exists())
        {
            File parentDir=new File(filePath.getParent());
            //如果所在目录不存在,则新建.
            if(!parentDir.exists()) {
                parentDir.mkdirs();
            }
            try {
                filePath.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

原文地址:https://www.cnblogs.com/mmzs/p/10219090.html

时间: 2024-10-10 21:57:45

使用IO流写文件的一些骚操作的相关文章

Java:IO流与文件基础

Java:IO流与文件基础 说明: 本文所有内容包含图片均为MrSaber自己编写,转载请练习我哦. 本章内容将会持续更新,大家可以关注一下并给我提供建议,谢谢啦. 走进流 什么是流 流:从源到目的地的字节的有序序列. 在Java中,可以从其中读取一个字节序列的对象称作 输入流,可以向其中写入一个字节序列的对象称作 输出流. ? 这些字节序列的来源可以是:文件.网络连接.内存块等. ? 抽象类InputStream和OutputStream是构成输入/输出(I/O)的基础. ? 因为面向字节的流

java io流 创建文件、写入数据、设置输出位置

java io流 创建文件 写入数据 改变system.out.print的输出位置 //创建文件 //写入数据 //改变system.out.print的输出位置 import java.io.*; public class Index{ public static void main(String[] args) throws Exception{ /** * 存储为二进制,给计算机看的 */ //创建文件 DataOutputStream sjl = new DataOutputStrea

使用IO流复制文件夹(包括子目录)

IO流用于处理设备上的数据(包括硬盘,内存,键盘录入). IO流可根据流向不同分为输入流和输出流,根据处理数据类型不同分为字节流和字符流. 字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象.本质其实就是基于字节流读取时,去查了指定的码表. 字节流和字符流的区别: a.读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节. b.处理对象不同:字节流能处理所有类型的数据(如图片.avi等),而字符流只能处理字符类型的数据. 结论:

Java IO流读写文件的几个注意点

平时写IO相关代码机会挺少的,但却都知道使用BufferedXXXX来读写效率高,没想到里面还有这么多陷阱,这两天突然被其中一个陷阱折腾一下:读一个文件,然后写到另外一个文件,前后两个文件居然不一样? 解决这个问题之后,总结了几个注意点. 注意点一:Reader/Writer读写二进制文件是有问题的 : public void copyFile1() { File srcFile = new File("E://atest//atest.txt"); File dstFile = ne

java中的IO流之文件复制

O(∩_∩)O哈哈~ 1.综述 一门成熟的语言肯定具备的几个模块:IO,通信,线程,UI...... Java作为一门成熟的程序语言,其IO流是比较复杂的.上个图大家感受下: 简单分析一下,IO分为两种流:字符流和字节流.字符流的父类Reader(读取到内存)和Writer(从内存输出),字节流的父类InputStream(读取到内存)和OutputStream(从内存输出),然后为了方便各种操作,比如为了文件操作,派生了文件流:为了对象操作,派生了对象流:等等.当初我也是傻傻分不清到底是Inp

191108、Java IO流读写文件的几个注意点

平时写IO相关代码机会挺少的,但却都知道使用BufferedXXXX来读写效率高,没想到里面还有这么多陷阱,这两天突然被其中一个陷阱折腾一下:读一个文件,然后写到另外一个文件,前后两个文件居然不一样? 解决这个问题之后,总结了几个注意点. 注意点一:Reader/Writer读写二进制文件是有问题的 : 上面代码使用BufferedReader一行一行地读取一个文件,然后使用BufferedWriter把读取到的数据写到另外一个文件中.如果文件是ASCCII形式的,则内容还是能够正确读取的.但如

IO流的文件复制

1. IO流的分类 1.根据处理数据类型的不同分为: 字符流:1)Reader 读取字符流的抽象类 常用方法: read() 读取单个字符 read(char[] cbuf) 将字符读入数组. read(char[] cbuf, int off, int len) 将字符读入数组的某一部分. close() 关闭该流并释放与之关联的所有资源. 2)Writer 写入字符流的抽象类 常用方法:write(int c) 写入单个字符. write(String str) 写入字符串 write(St

IO流 读写文件

读写文件 如前所述,一个流被定义为一个数据序列.输入流用于从源读取数据,输出流用于向目标写数据. 下图是一个描述输入流和输出流的类层次图. 下面将要讨论的两个重要的流是 FileInputStream 和 FileOutputStream: FileInputStream 该流用于从文件读取数据,它的对象可以用关键字 new 来创建. 有多种构造方法可用来创建对象. 可以使用字符串类型的文件名来创建一个输入流对象来读取文件: InputStream f = new FileInputStream

Java中常用IO流之文件流的基本使用姿势

所谓的 IO 即 Input(输入)/Output(输出) ,当软件与外部资源(例如:网络,数据库,磁盘文件)交互的时候,就会用到 IO 操作.而在IO操作中,最常用的一种方式就是流,也被称为IO流.IO操作比较复杂,涉及到的系统调用比较多,相对操作内存而言性能很低.然而值得兴奋的是,Java提供了很多实现类以满足不同的使用场景,这样的实现类有很多,我只挑选些在日常编码中经常用到的类进行说明,本节主要介绍和文件操作相关的流,下面一起来瞧瞧吧. File File是Java在整个文件IO体系中比较