java之通过数据流对文件的内容进行操作

按操作单位的不同分为:字节流(8bit)(InputStream、OuputStream)、字符流(16bit)(Reader、Writer)

按数据流的流向不同分为:输入流、输出流

按角色的不同分为:节点流、处理流

一、不带缓冲的流

1.文件字节输入流、文件字节输出流

package anno;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test2 {
    public static void main(String[] args) {
        test1FileInputStream();
        test2FileInputStream();
        testFileOutputStream();
    }
    public static  void test1FileInputStream() {
        String path = "F:\\test.txt";
        try {
            FileInputStream fs = new FileInputStream(path);
            //设置一个数组接收文件的内容
            //需要注意的是,如果数组设置的太小,那么可能出现读取的数据不完整或者乱码等情况
            byte[] b = new byte[30];
            //文件输入流对象有一个返回值,返回的是读取数据的长度,如果读取到一个数据了,还会向后读一个,
            //当读取完毕时会返回-1
            int len = 0;
            while((len=fs.read(b))!=-1) {
                //参数1是缓冲数据数组,参数2是从哪个位置开始转换成字符串,参数3是总共转换的长度
                System.out.println(new String(b, 0, len));
            }
            fs.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public static  void test2FileInputStream() {
        String path = "F:\\test.txt";
        File f = new File(path);
        int l = (int) f.length();
        try {
            FileInputStream fs = new FileInputStream(path);
            byte[] b = new byte[l];
            //将读取的数据存入到b中
            fs.read(b);
            //将b转换成字符串并输出
            System.out.println(new String(b));
            fs.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public static  void testFileOutputStream() {
//如果不存在该文件,则系统会新建一个 String path1
= "F:\\test2.txt"; try { FileOutputStream fo = new FileOutputStream(path1); String str = "这是我测试的输入"; fo.write(str.getBytes());//将数据写到byte中 fo.flush();//将内存中的数据写到文件中 fo.close();//关闭 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

在运行的过程中会遇到一些问题,比如说设置的byte数组来接收读取的数据,如果初始化长度给的比较小,那么读取的数据就不全,在进行test1FileInputStream()的实验中,即使按照:

            int len = 0;
            while((len=fs.read(b))!=-1) {
                //参数1是缓冲数据数组,参数2是从哪个位置开始转换成字符串,参数3是总共转换的长度
                System.out.println(new String(b, 0, len));
            }

进行输出,如果byte设置的还是太小,就会出现:

这是我新建的test.txt�
��件

这种乱码问题,于是进行了第二种方法的尝试,即在传入数据之前首先获得要接收多少字节的数据,然后在进行接收(借鉴之前在golang中文件读取并显示的思想),然后就没有问题了,即test2FileInputStream()。

输出结果:

这是我新建的test.txt文件

2.使用字节流将一个文件复制到指定的文件夹下

public static void copyFile() {
        String path = "F:\\test.txt";
        String path2 = "F:\\test2.txt";
        try {
            FileInputStream fi = new FileInputStream(path);
            FileOutputStream fo = new FileOutputStream(path2);
            File f = new File(path);
            int l = (int) f.length();
            byte[] b = new byte[l];
            int len = 0;
            while((len=fi.read(b))!=-1) {
                fo.write(b,0,len);
            }
            fo.flush();
            fo.close();
            fi.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

综合使用之前读取的方式。

3.文件字符输入流、文件字符输出流

public static  void testFileReader() {
        String path = "F:\\test.txt";
        try {
            FileReader fr = new FileReader(path);
//注意这里是char类型的数组了
char[] c = new char[20]; int len = 0; while((len=fr.read(c))!=-1) { System.out.println(new String(c, 0, len)); } fr.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void testFileWriter() { String path1 = "F:\\test2.txt"; try { FileWriter fw = new FileWriter(path1); String str = "这是我测试的输入";
//注意这里可以直接写入字符串 fw.write(str);
fw.flush();//将内存中的数据写到文件中 fw.close();//关闭 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }

需要注意的是定义char数组时仍然是需要知道数据是有多少字符的,不然长度不够,显示不全或者写入不全。(这里暂时还未了解怎么处理)

4.使用字符流将一个文件复制到指定的文件夹下

    public static void copyFile2() {
        String path = "F:\\test.txt";
        String path2 = "F:\\test2.txt";
        try {
            FileReader fr = new FileReader(path);
            FileWriter fw = new FileWriter(path2);
            char[] c = new char[30];
            int len = 0;
            while((len=fr.read(c))!=-1) {
                fw.write(c,0,len);
            }
            fw.flush();
            fw.close();
            fr.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }

 

二、带缓冲的流

为了提高数据的读写速度,java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组。

根据数据操作单位可以把缓冲流分为:BufferedInputStream/BufferedOutputStream和BufferedReader/BufferedWriter。

缓冲流要“套接”在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了些新方法。对于输出的缓冲流,写出的数据都会先在内存中缓存,使用flush()会将在内存中的数据立即写出。

你可能感兴趣的:(java之通过数据流对文件的内容进行操作)