Java基础之IO流基本操作

1、Java IO流概念

  • I/O是Input/Output的缩写, I/O技术是非常实用的技术,用于 处理设备之间的数据传输。如读/写文件,网络通讯等。
  • Java程序中,对于数据的输入/输出操作以“流(stream)” 的 方式进行。
  • java.io包下提供了各种“流”类和接口,用以获取不同种类的 数据,并通过标准的方法输入或输出数据。
  • 输入input:读取外部数据(磁 盘、光盘等存储设备的数据)到 程序(内存)中。
  • 输出output:将程序(内存) 数据输出到磁盘、光盘等存储设 备中。

2、IO流的基本分类

  • 按操作数据单位不同分为:字节流(8 bit),字符流(16 bit)
  • 按数据流的流向不同分为:输入流,输出流
  • 按流的角色的不同分为:节点流,处理流
    • 节点流
      • 直接从数据源或目的地读写数据
    • 处理流
      • 不直接连接到数据源或目的地,而是“连接”在已存 在的流(节点流或处理流)之上,通过对数据的处理为程序提 供更为强大的读写功能
字节流 字符流
输入流 InputStream Reader
输出流 OutputStream Writer

在这里插入图片描述
在这里插入图片描述

3、FileReader和FileWriter

3.1、FileReader

  • int read() 读取单个字符。作为整数读取的字符,范围在 0 到 65535 之间 (0x00-0xffff)(2个 字节的Unicode码),如果已到达流的末尾,则返回 -1
  • int read(char[] cbuf) 将字符读入数组。如果已到达流的末尾,则返回 -1。否则返回本次读取的字符数。
  • int read(char[] cbuf,int off,int len) 将字符读入数组的某一部分。存到数组cbuf中,从off处开始存储,最多读len个字 符。如果已到达流的末尾,则返回 -1。否则返回本次读取的字符数。
@Test
public void Readertest() {
    
    
    FileReader fr = null;
    try {
    
    
        //创建file 文件需要存在 不然咋读?
        File file = new File("hello.txt");

        //流的创建
        fr = new FileReader(file);

        //读取文件的内容存放在cbuf数组中 ,一般为char[1024]
        char []cbuf = new char[5];
        int len;//记录每次读取的个数
        while ((len=fr.read(cbuf))!=-1){
    
    
            //将字符读入数组。如果已到达流的末尾,则返回 -1。否则返回本次读取的字符数。
            System.out.println(new String(cbuf,0,len));
        }
    } catch (IOException e) {
    
    
        e.printStackTrace();
    } finally {
    
    
        if(fr!=null) {
    
    
        //关闭流资源
        try {
    
    
            fr.close();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
        }
    }
}

3.2、FileWriter

  • void write(int c) 写入单个字符。要写入的字符包含在给定整数值的 16 个低位中,16 高位被忽略。 即 写入0 到 65535 之间的Unicode码。
  • void write(char[] cbuf) 写入字符数组
  • void write(char[] cbuf,int off,int len) 写入字符数组的某一部分。从off开始,写入len个字符
  • void write(String str) 写入字符串。
  • void write(String str,int off,int len) 写入字符串的某一部分。
  • void flush() 刷新该流的缓冲,则立即将它们写入预期目标。
@Test
    public void WriterTest() {
    
    
        FileWriter fw = null;
        try {
    
    
            //创建file 若文件不在会自动帮你生成hello2.txt文件
            File file = new File("hello2.txt");

            //输出流的创建
            // FileWriter fw=new FileWriter(file,true);//对已经存在的文件进行添加
            // FileWriter fw=new FileWriter(file,false)/(file); 对已经存在的文件进行覆盖
            fw = new FileWriter(file);

            //文件的输出操作
            fw.write("hello world");
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if(fw!=null){
    
    
                try {
    
    
                    fw.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }

3.3、文件传输操作

    @Test
    public void ReaderWriterCopy() {
    
    
            FileReader fr = null;
            FileWriter fw = null;
            try {
    
    
                //创建流对象,建立数据存放文件
                fr = new FileReader(new File("hello.txt"));
                fw = new FileWriter(new File("hello2.txt"),true);
                //将hello.txt文件的数据存放到数组中
                char [] cbuf = new char[1024];
                int len;
                while ((len=fr.read(cbuf))!=-1){
    
    
                    fw.write(cbuf,0,len);//将cbuf数组数据通过fw写入到文件中
                }
            } catch (IOException e) {
    
    
                e.printStackTrace();
            } finally {
    
    
                if(fr!=null){
    
    
                    try {
    
    
                        fr.close();
                    } catch (IOException e) {
    
    
                        e.printStackTrace();
                    }
                }
                if(fw!=null){
    
    
                    try {
    
    
                        fw.close();
                    } catch (IOException e) {
    
    
                        e.printStackTrace();
                    }
                }
            }
        }

4、FileInputStream和FileOutputStream

4.1、通用节点流文件复制方法

public static void CopeFile(String srePath,String destPath){
    
    
        FileInputStream fis=null;
        FileOutputStream fos=null;
        try {
    
    
            //创建文件file file1
            File file=new File(srePath);
            File file1=new File(destPath);
            
            //创建输出流
            fis=new FileInputStream(file);
            fos=new FileOutputStream(file1);
            byte[] bytes=new byte[1024];
            int len;
            while ((len=fis.read(bytes))!=-1){
    
    
                fos.write(bytes,0,len);
            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }finally {
    
    
            if(fos!=null){
    
    
                try {
    
    
                    fos.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
            if(fis!=null){
    
    
                try {
    
    
                    fis.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }

4.2、实现图片加密操作

@Test
publuc void test(){
    
    
		//加密
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
    
    
            fis = new FileInputStream(new File("1.jpg"));
            fos = new FileOutputStream(new File("1srcte.jpg"));

            int len;
            byte[] by = new byte[5];
            while ((len=fis.read(by))!=-1){
    
    
                for(int i=0;i<len;i++){
    
    
                    by[i] = (byte) (by[i]^5);
                }
                fos.write(by,0,len);
            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if(fis!=null){
    
    
                try {
    
    
                    fis.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
            if(fos!=null){
    
    
                try {
    
    
                    fos.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
}

@Test
public void Test01() throws IOException{
    
    
    //解密
    FileInputStream fis = new FileInputStream(new File("1srcte.jpg"));
    FileOutputStream fos = new FileOutputStream(new File("5 .jpg"));

    int len;
    byte[] by = new byte[5];
    while ((len=fis.read(by))!=-1){
    
    
       for(int i=0;i<len;i++){
    
    
           by[i] = (byte) (by[i]^5);
       }
        fos.write(by,0,len);
    }
    
}

5、缓冲流

5.1、缓冲流文件复制通用方法

public static void CopeFileStream(String srcFile,String destFile){
    
    
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
    
    
            File file = new File(srcFile);
            File file1 = new File(destFile);

            FileInputStream fis = new FileInputStream(file);
            FileOutputStream fos = new FileOutputStream(file1);

            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);
            byte[] bt = new byte[1024];
            int len;
            while((len=bis.read(bt))!=-1){
    
    
                bos.write(bt,0,len);
            }
        }catch (IOException e) {
    
    
            e.printStackTrace();
        }finally {
    
    
            if(bis!=null)
                try {
    
    
                    bis.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            if(bos!=null)
                try {
    
    
                    bos.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
        }
    }
  • 当读取数据时,数据按块读入缓冲区,其后的读操作则直接访问缓冲区
  • 当使用BufferedInputStream读取字节文件时,BufferedInputStream会一次性从 文件中读取8192个(8Kb),存在缓冲区中,直到缓冲区装满了,才重新从文件中 读取下一个8192个字节数组。
  • 向流中写入字节时,不会直接写到文件,先写到缓冲区中直到缓冲区写满, BufferedOutputStream才会把缓冲区中的数据一次性写到文件里。使用方法 flush()可以强制将缓冲区的内容全部写入输出流
  • 关闭流的顺序和打开流的顺序相反。只要关闭最外层流即可,关闭最外层流也 会相应关闭内层节点流
  • flush()方法的使用:手动将buffer中内容写入文件
  • 如果是带缓冲区的流对象的close()方法,不但会关闭流,还会在关闭流之前刷 新缓冲区,关闭后不能再写出

6、其他的流

转换流

  • InputStreamReader
    • 将InputStream转换为Reader
  • OutputStreamWrite
    • 将Writer转换为OutputStream

在这里插入图片描述

标准输入、输出流

//实现大小写的转换
public class OtherStreamTest {
    
    
    public static void main(String[] args) throws IOException {
    
    
        InputStreamReader isr = new InputStreamReader(System.in);
        BufferedReader bos = new BufferedReader(isr);

        while(true){
    
    
            System.out.println("请输入字符!");
            String date=bos.readLine();
            if("e".equalsIgnoreCase(date)||"exit".equalsIgnoreCase(date)) {
    
    
                System.out.println("程序结束!");
                break;
            }else{
    
    
                String s = date.toUpperCase();
                System.out.println(s);
            }
        }
        bos.close();
    }
}

模范Scanner类功能

public class Test {
    
    
    public static void main(String[] args) {
    
    
        readString();
    }

    public static String readString(){
    
    
        InputStreamReader inputStreamReader = new InputStreamReader(System.in);
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String string = "";
        System.out.println("请输入");
        try {
    
    
            string=bufferedReader.readLine();
        } catch (IOException e) {
    
    
            System.out.println(e);
        }finally {
    
    
            if(bufferedReader!=null){
    
    
                try {
    
    
                    bufferedReader.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
        return string;
    }
    public static int readInt(){
    
    
        return Integer.parseInt(readString());
    }
    public static double readDouble(){
    
    
        return Double.parseDouble(readString());
    }
    public static float readFloat(){
    
    
        return Float.parseFloat(readString());
    }
    public static byte readByte(){
    
    
        return Byte.parseByte(readString());
    }
    public static short readShort(){
    
    
        return Short.parseShort(readString());
    }
    public static boolean readBoolean(){
    
    
        return Boolean.parseBoolean(readString());
    }
}

随机存取文件流

public class RandomAccessFileTest {
    
    
    public static void main(String[] args) throws IOException {
    
    
        RandomAccessFile raf = new RandomAccessFile("day08\\hello.txt","rw");

        raf.seek(3);//void seek(long pos):将文件记录指针定位到 pos 位置

        StringBuffer stringBuffer = new StringBuffer((int) new File("day08\\hello.txt").length());

        int len;
        byte[] bty = new byte[20];

        while ((len=raf.read(bty))!=-1){
    
    
            stringBuffer.append(new String(bty,0,len));//将后面的数据保存在stringBuffer中
        }
        raf.seek(3);
        raf.write("asd".getBytes());
        raf.write(stringBuffer.toString().getBytes());
        raf.close();
    }
}

谢谢大家的阅读! 若上面有写错的 欢迎纠正哦

推荐学习java基础IO视频 B站尚硅谷宋红康老师

猜你喜欢

转载自blog.csdn.net/qq_44763720/article/details/108035655