zoukankan      html  css  js  c++  java
  • 2017java文本文件操作(读写操作)

    java的读写操作是学java开发的必经之路,下面就来总结下java的读写操作。

    从上图可以开出,java的读写操作(输入输出)可以用“流”这个概念来表示,总体而言,java的读写操作又分为两种:字符流和字节流。

    什么是流?

    流是一个抽象的概念。当Java程序需要从数据源读取数据时,会开启一个到数据源的流。数据源可以是文件,内存或者网络等。同样,当程序需要输出数据到目的地时也一样会开启一个流,数据目的地也可以是文件、内存或者网络等。流的创建是为了更方便地处理数据的输入输出。

    那么字节流和字符流又有什么区别呢?

    1.字节流也称为原始数据,需要用户读入后进行相应的编码转换。而字符流的实现是基于自动转换的,读取数据时会把数据按照JVM的默认编码自动转换成字符。

    2.字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串,而字节流处理单元为1个字节,操作字节和字节数组。

    所以字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的。

    3.字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串,字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以;

    基于以上的区别,那么什么情况下用字符流,什么情况下用字节流呢?

    如果是音频文件、图片、歌曲,就用字节流好点;如果是中文(文本)的,用字符流更好;

    说了这么多,字节流和字符流处理文件到底怎么用呢?

    稍安勿躁,让我们先来看看在java中,输入输出操作的步骤是什么?

    1 使用File类打开一个文件

    通过字节流或字符流的子类,指定输出的位置,注,

    3 进行读/写操作

    4 关闭输入/输出

    IO操作属于资源操作,一定要记得关闭

    字节流:

    1.按照字节流的方式从文件中读取数据。

    package ioInJava.characterStream;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    
    public class CharIo {
    
        public static void main(String[] args) {
            
            // 第一种方式读文件,因为方法throws了异常,所以在这要捕获异常
            try {
                CharIo.readFromFileByByte();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                System.out.println("找不到文件啊");
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("读不成功啊!");
            }
            
            System.out.println("===========================");
            
            // 第二种方式读文件
            try {
                CharIo.readFromFileByteTwo();
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("还是读不成功啊!");
            }
            
        }
        
        /**
         * 第一种方法读文件
         * 通过字符流读取文件中的数据
         * @throws IOException 
         */
        public static void readFromFileByByte() throws IOException{
            File file = new File("abc.txt");
            // 如果文件不存在则创建文件
            if (!file.exists()) {
                file.createNewFile();
            }
            InputStream inputStream = new FileInputStream(file);
            // 这里定义了数组的长度是1024个字节,如果文件超出这字节,就会溢出,结果就是读不到1024字节以后的东西
            byte[] bs = new byte[1024];
            // 这里len获得的是文件中内容的长度
            int len = inputStream.read(bs);
            inputStream.close();
            System.out.println(new String(bs));
        }
        
        /**
         * 第二种方法读文件
         * 通过字符流读取文件中的数据
         * @throws IOException 
         */
        public static void readFromFileByteTwo() throws IOException{
            // 注意这里的不同,File.separator是分隔符,这里指明绝对路径,即D盘根目录下的abc.txt文件
            File file = new File("d:" + File.separator+"abc.txt");
            // 如果文件不存在则创建文件
            if (!file.exists()) {
                file.createNewFile();
            }
            InputStream inputStream = new FileInputStream(file);
            // 这里也有不同,可以根据文件的大小来声明byte数组的大小,确保能把文件读完
            byte[] bs = new byte[(int)file.length()];
            // read()方法每次只能读一个byte的内容
            inputStream.read(bs);
            inputStream.close();
            System.out.println(new String(bs));
        }
        
    }

    2.按照字节流的方式向文件中写入数据。

    package ioInJava.byteStream;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    
    /**
     * 不要被那么多的try和catch吓到奥,那只是因为不想在main上throws
     * @author wsg
     */
    public class WriteToFile {
    
        public static void main(String[] args) {
            File file = new File("D:"+File.separator+"write.doc");
            OutputStream outputStream = null;
            if (!file.exists()) {
                try {
                    // 如果文件找不到,就new一个
                    file.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            try {
                // 定义输出流,写入文件的流
                outputStream = new FileOutputStream(file);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            // 定义将要写入文件的数据
            String string = "Hell Java, Hello World, 你好,世界!";
            // 把string转换成byte型的,并存放在数组中
            byte[] bs = string.getBytes();
            try {
                // 写入bs中的数据到file中
                outputStream.write(bs);
            } catch (IOException e) {
                e.printStackTrace();
            }
            
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            
            // =================到此,文件的写入已经完成了!
            
            // 如果想在文件后面追加内容的话,用下面的方法
            OutputStream outToFileEnd = null;
            try {
                outToFileEnd = new FileOutputStream(file,true);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }finally {// 这里利用了finally总会被执行的特性,索性把后面的代码都写在finally中
                String string2 = "Here I come!!";
                byte[] bs2 = string2.getBytes();
                try {
                    outToFileEnd.write(bs2);
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    try {
                        outToFileEnd.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    =====================================================注意!!==================================================

    1.初学者一般很容易搞混,或者弄不清inputstream和outpustream到底哪个是读数据,哪个是写数据,这里要说明的是,“读和写”是相对于程序本身而言的,主要记清楚一点即可,那就是凡是需要提供给程序处理的数据就是输入数据,当然就是inputstream,这里的in是要in到程序里面去,那么数据从哪里来呢,自然是从外界(网络,内存或者文件),那么针对文件而言,inputstream就是读文件了。反之,凡是程序已经处理过的数据,当然要流出程序啦,那就是out咯,所以outputstream就是输出的,那么从程序中流出,只能到外界(网络、内存或者文件),针对文件而言,就是写操作啦!(同样的道理可以针对字符流的操作)

    【简言之,针对程序而言,in是入,out是出;这对文件而言,in是读,out是写!】

    2.inputstream和OutputStream都是抽象类,不能实例化,使用时必须实例化一个子类(其中FileInputStream和FileOutputStream使用最多)对象来进行相关操作。

    3.InputStream inputStream = new FileInputStream(fileName);当使用这个命令时,系统会提示有异常抛出,因为我们上面定义的文件程序认为是有可能存在,有可能不存在的,所以在eclipse中,给出了两个解决办法,一个是直接抛出异常声明,由系统自己解决;另一个是用try,catch结构处理异常!

    ===============================================================================================================

    3.按照字符流的方式向文件中写入数据。

    package ioInJava.characterStream;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.Writer;
    
    public class CharIo {
    
        public static void main(String[] args) throws IOException {
            // 定义一个d盘根目录下的test文档,File.separator是分隔符
            // 下面这句代码,就算原本没有这个文件,也会在对应的目录创建一个文件
            File file = new File("D:" + File.separator + "test.docx");
            // 下面这也会抛出异常,这次我们为了代码结构清晰起见,直接throw给main吧
            Writer writer = new FileWriter(file);
            String string = "今天是教师节!";
            writer.write(string);
            // 在这一定要记得关闭流
            writer.close();
        }
    }

    但是,上面的代码有一个问题,比如,载定义一个string2,再次调用writer.write(string2)方法的时候,会发现test文件中的内容会被string2的内容覆盖,要想实现内容追加到文件尾部,代码如下,其实就是小小的修改,利用它的一个方法!

    package ioInJava.characterStream;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.Writer;
    
    public class CharIo {
    
        public static void main(String[] args) throws IOException {
            // 定义一个d盘根目录下的test文档,File.separator是分隔符
            // 下面这句代码,就算原本没有这个文件,也会在对应的目录创建一个文件
            File file = new File("D:" + File.separator + "test.docx");
            // 下面这也会抛出异常,这次我们为了代码结构清晰起见,直接throw给main吧
            // 这里改变了writer的类型,变成了追加型
            Writer writer = new FileWriter(file, true);
            String string = "今天是教师节!";
            writer.write(string);
            String string2 = "祝愿所有的老师教师节快乐!";
            writer.write(string2);;
            // 在这一定要记得关闭流
            writer.close();
        }
    }

    4.按照字符流的方式从文件中读取数据。

    package ioInJava.characterStream;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.Reader;
    
    public class ReadFromFile {
    
        public static void main(String[] args) throws IOException {
            File file = new File("d:" + File.separator + "test.docx");
            Reader reader = new FileReader(file);
            char[] cs= new char[1024];
            // 上面定义了一个大小为1024的char型数组,如果文件内容过大,程序就会报错,而不是只读到1024的大小
            reader.read(cs, 0, (int)file.length());
            System.out.println(cs);
            reader.close();
        }
    
    }

    上面的代码只能读取内容不超过1024字符的内容,这显然不是我们想要的,如何读取一个任意大小的文件呢!那么最简单的方法就是加大数组的空间大小了,可以用file.length获取文件的大小,从而定义数组的大小!char[] cs= new char[(int)file.length()];

    当然,这不是最好的办法,请看下面的代码:

    package ioInJava.characterStream;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.Reader;
    import java.io.Writer;
    
    public class ReadFromFile {
    
        public static void main(String[] args) throws IOException {
            try {
                // 声明一个可变长的stringBuffer对象
                StringBuffer sb = new StringBuffer("");
                
                /*
                 * 读取完整文件
                 */
                Reader reader = new FileReader("d:" + File.separator + "test.docx");
                // 这里我们用到了字符操作的BufferedReader类
                BufferedReader bufferedReader = new BufferedReader(reader);
                String string = null;
                // 按行读取,结束的判断是是否为null,按字节或者字符读取时结束的标志是-1
                while ((string = bufferedReader.readLine()) != null) {
                    // 这里我们用到了StringBuffer的append方法,这个比string的“+”要高效
                    sb.append(string + "
    ");//读取和写入换行操作
                    System.out.println(string);
                }
                // 注意这两个关闭的顺序
                bufferedReader.close();
                reader.close();
                
                /*
                 * 完整写入文件
                 */
                Writer writer = new FileWriter("d:" + File.separator + "test2.docx");
                BufferedWriter bw = new BufferedWriter(writer);
                // 注意这里调用了toString方法
                bw.write(sb.toString());
                // 注意这两个关闭的顺序
                bw.close();
                writer.close();
                
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    上面的代码我们顺利实现了从test文件中读取全文,并将其写入test2文件中!!

    摘自:https://www.cnblogs.com/wsg25/p/7499227.html

    自古英雄出炼狱,从来富贵入凡尘。
  • 相关阅读:
    17.1.2.1 Advantages and Disadvantages of Statement-Based and Row-Based Replication
    17.1.2 Replication Formats
    Setting the Master Configuration on the Slave
    17.1.1.9 Introducing Additional Slaves to an Existing Replication Environment
    17.1.1.8 Setting Up Replication with Existing Data
    17.1.1.7 Setting Up Replication with New Master and Slaves
    17.1.1.6 Creating a Data Snapshot Using Raw Data Files
    列出display的值,并说明它们的作用
    CSS设置DIV居中
    CSS选择符有哪些?哪些属性可以继承?优先级算法如何计算?
  • 原文地址:https://www.cnblogs.com/yunliu0603/p/10044095.html
Copyright © 2011-2022 走看看