day19Java-IO-FileIn(Out)putStream-字节流

博客名称
Java-(中级)

IO-FileIn(Out)putStream

java.io.FileInputStream extends java.io.InputStream
java.io.FileOutputStream extends java.io.OutputStream
注意:InputStream和OutputStream抽象类不能实例化,每种基类的子类都是以父类名作为后缀名。
XxxOutputStream
XxxInputStream
XxxReader
XxxWriter

IO流的分类:

	流向:
  			输入流	读取数据
  			输出流 写出数据
    数据类型:
  			字节流
  				字节输入流	读取数据	InputStream
  				字节输出流	写出数据	OutputStream
  			字符流
  				字符输入流	读取数据	Reader
  				字符输出流	写出数据	Writer

注意:一般探讨IO流的时候,如果没有明确说明按哪种分类来说,默认情况下是按照数据类型来分的。

FileIn(Out)putStream-FileOutputStream(字节输出流)-构造方法

FileOutputStream(File file) :创建一个指定 File对象的输出流
FileOutputStream(File file, boolean append):创建一个指定 File对象的输出流,可以追加内容
FileOutputStream(String name):创建一个指定文件名称的输出流
FileOutputStream(String name, boolean append):创建一个指定文件名称的输出流,可以追加内容

字节输出流操作步骤:

		A:创建字节输出流对象
 		B:写数据
 		C:释放资源

需求:我要往一个文本文件中输入一句话:“hello,io”
分析:

	A:这个操作最好是采用字符流来做,但是呢,字符流是在字节流之后才出现的,所以,先操作字节流。
    B:由于我是要往文件中写一句话,所以我们要采用字节输出流。

代码演示

public class FileOutInputStreamDemo {
    public static void main(String[] args) throws IOException {
        //FileOutputStream(File file) :创建一个指定 File对象的输出流
        //再次执行代码没有追加以前一样的内容
        FileOutputStream fos1 = new FileOutputStream(new File("a.txt"));
		/*
		 * 创建字节输出流对象了做了几件事情:
		 * A:调用系统功能去创建文件
		 * B:创建fos对象
		 * C:把fos对象指向这个文件
		 */
		 
        //写数据
        fos1.write("hello.xixi".getBytes());
		//释放资源(不释放资源,也可以写数据)
		//关闭此文件输出流并释放与此流有关的所有系统资源。
		fos1.close();
        /*
		 * 为什么一定要close()呢?
		 * A:让流对象变成垃圾,这样就可以被垃圾回收器回收了
		 * B:通知系统去释放跟该文件相关的资源
		 */

		//FileOutputStream(String name):创建一个指定文件名称的输出流
        //再次执行代码没有追加以前一样的内容
        FileOutputStream fos2 = new FileOutputStream("b.txt");
        //写数据
        fos2.write("hello.haha".getBytes());
        System.out.println("-----------------------------");

        //FileOutputStream(File file, boolean append):创建一个指定 File对象的输出流,可以追加内容
        //构造方法加上true,就可追加以前一样的内容
        FileOutputStream fos3 = new FileOutputStream(new File("c.txt"),true);
        //写数据
        fos3.write("hello.hiahia".getBytes());

        //FileOutputStream(String name, boolean append):创建一个指定文件名称的输出流,可以追加内容
        //构造方法加上true,就可追加以前一样的内容
        FileOutputStream fos4 = new FileOutputStream("d.txt",true);
        fos4.write("hello.luelue".getBytes());

    }

}
FileIn(Out)putStream-FileOutputStream(字节输出流)-成员方法

public void write(int b):写一个字节
public void write(byte[] b):写一个字节数组
public void write(byte[] b,int off,int len):写一个字节数组的一部分

代码演示

public class FileOutputStreamDemo {
    public static void main(String[] args) throws IOException {
        //创建文件输出流对象
        FileOutputStream fos = new FileOutputStream("fos.txt");
        //public void write(int b):写一个字节
        fos.write(97); //97 底层是二进制数据 通过记事本-- 找到97对应的值 --a

        FileOutputStream fos2 = new FileOutputStream("fos2.txt");
        byte[] arr = {97,98,99,100,101};
        //public void write(byte[] b):写一个字节数组
        fos2.write(arr);

        FileOutputStream fos3 = new FileOutputStream("fos3.txt");
        byte[] arr2 = {97,98,99,100,101};
        //public void write(byte[] b,int off,int len):写一个字节数组的一部分
        fos3.write(arr,0,3);
    }
}

结果:文件中的内容
fos.txt

a

fos2.txt

abcde

fos3.txt

abc
FileIn(Out)putStream-FileOutputStream(字节输出流)-如何实现数据的换行?
为什么现在没有换行呢?因为只写了字节数据,并没有写入换行符号。
		如何实现呢?写入换行符号即可。
  		但是有的写文本文件打开是可以的,通过windows自带的那个不行,为什么呢?
  		因为不同的系统针对不同的换行符号识别是不一样的?
  		windows:\r\n
  		linux:\n
  		Mac:\r
  		而一些常见的个高级记事本,是可以识别任意换行符号的。

代码演示

public class FileOutputStreamDemo {
    public static void main(String[] args) throws IOException {
        // 创建字节输出流对象
        // FileOutputStream fos = new FileOutputStream("fos3.txt");
        // 创建一个向具有指定 name 的文件中写入数据的输出文件流。如果第二个参数为 true,则将字节写入文件末尾处,而不是写入文件开始处。
        FileOutputStream fos = new FileOutputStream("fos3.txt", true);
        //写数据
        for (int x = 0; x <10 ; x++) {
            fos.write("hello.io".getBytes());
            //换行
            fos.write("\r\n".getBytes());
        }
    }
}

结果:文件结果

hello.io
hello.io
hello.io
hello.io
hello.io
hello.io
hello.io
hello.io
hello.io
hello.io
FileIn(Out)putStream-FileOutputStream(字节输出流)-加入异常处理的字节输出流操作

代码演示

public class FileOutputStreamDemo {
    public static void main(String[] args) {
        FileOutputStream fos = null;
        try {
            //创建输出流对象
            //fos = new FileOutputStream("G:\\a.txt")/如果文件路径不存在返回null,所以要加上判断
            fos = new FileOutputStream("fos4.txt");
            //写数据
            fos.write("hello.io".getBytes());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException io) {
            io.printStackTrace();
        } finally {
            //为了保证释放资源,就放到finally中
            try {
                // 如果fos不是null,才需要close()
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
FileIn(Out)putStream-FileInputStream(字节输入流)-成员(构造)方法

构造方法:
FileInputStream(File file) :创建一个指定File对象的输入流
FileInputStream(String name) :创建一个指定文件名称的输入流

成员方法
A:int read():一次读取一个字节,返回的是读取的内容,返回-1说明没有内容
B:int read(byte[] b):一次读取一个字节数组,返回实际读取的长度,返回-1说明没有内容
字节输入流操作步骤:

	  A:创建字节输入流对象
	  B:调用read()方法读取数据,并把数据显示在控制台
	  C:释放资源

代码演示1
A:int read():一次读取一个字节,返回的是读取的内容

public class FileInputStreamDemo {
    public static void main(String[] args) throws IOException {
        //FileInputStream(File file) :创建一个指定File对象的输入流
        FileInputStream fis = new FileInputStream(new File("fos3.txt"));
        int by =0;
        //int read():一次读取一个字节
        while ((by =fis.read())!=-1){
        	//这里如果是中文会出现乱码,因为utf-8下,一个中文使用三个字节来表示,把三个直接换char就会乱码
            System.out.print((char)by);
        }
        //释放资源
        fis.close();
        System.out.println("-------------------------");

        //FileInputStream(String name) :创建一个指定文件名称的输入流
        FileInputStream fis2 = new FileInputStream("fos.txt");
        int by2=0;
        //int read():一次读取一个字节
        while((by2=fis2.read())!=-1){
            System.out.println(by2);
        }
        释放资源
        fis2.close();
    }
}

结果:

hello.io
hello.io
hello.io
hello.io
hello.io
hello.io
hello.io
hello.io
hello.io
hello.io
-------------------------
97

代码演示2
B:int read(byte[] b):一次读取一个字节数组,返回实际读取的长度
需要读取的fis.txt文件内容
hello
world
java

public class FileInputStreamDemo {
    public static void main(String[] args) throws IOException {
        //创建字节输入流对象
        FileInputStream fis = new FileInputStream("fis.txt");
        //创建字节数组
        byte[] bys = new byte[5];
        //第一次读取
        int len = fis.read(bys);
        //System.out.println(len);
        System.out.println(new String(bys));
        
        //第二次读取
        int len2 = fis.read(bys);
        //System.out.println(len2);
        System.out.println(new String(bys));
		
		//第三次读取
        int len3 = fis.read(bys);
        //System.out.println(len2);
        System.out.println(new String(bys));

		//第四次读取
        int len4 = fis.read(bys);
        //System.out.println(len2);
        System.out.println(new String(bys));
    }
}

结果:

hello

wor
ld
j
ava
j

结果分析:
第一次读取
hello
第二次读取:因为换行符是\r\n,因为是空字符所以看不见
\r\n
wor
第三次读取:因为换行符是\r\n,因为是空字符所以看不见
ld\r\n
j
第四次读取:因为我我使用的同一个字节数组,后面的内容会把前面的覆盖掉,每次读取5个,但是最后一次不够5个只有3个ava,
就把之前字节数组的内容没有覆盖掉,\n和j是上一次遗留下来的内容。
ava\n
j

改进代码3演示
B:int read(byte[] b):一次读取一个字节数组,返回实际读取的长度

public class FileInputStreamDemo {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("fis.txt");
        byte[] bys = new byte[105]; //没有赋值的元素默认是0
        int len5 = 0;
        while ((len5 = fis.read(bys)) != -1) {
      
            //System.out.print(new String(bys)); //千万要带上len的使用,否则内容不够会出现很多空白。
            System.out.print(new String(bys, 0, len5));
        }
        fos.close();
        System.out.println();
        System.out.println("---------------------------");

        //最终版代码实现
        FileInputStream fis1 = new FileInputStream("FileOutputStreamDemo.java");
        byte[] bytes = new byte[1024];//存储单位都是1024的倍数,所以使用1024
        int length = 0;
        while ((length = fis1.read(bytes)) != -1) {
            //System.out.println(new String(bytes));//千万要带上len的使用,否则内容不够会出现很多空白。
            System.out.println(new String(bytes,0,length));//将实际读取的内容转为字符串
        }
        fos1.close()
    }
}

结果:

hello
world
java
---------------------------
package com.ginger.demo04;

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

public class FileOutputStreamDemo {
    public static void main(String[] args) {
        FileOutputStream fos = null;
        try {
            //创建输出流对象
            //fos = new FileOutputStream("G:\\a.txt");//如果文件路径不存在返回null,所以要加上判断
            fos = new FileOutputStream("fos4.txt");
            //写数据
            fos.write("hello.io".getBytes());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException io) {
            io.printStackTrace();
        } finally {
            //为了保证释放资源,就放到finally中
            try {
                // 如果fos不是null,才需要close()
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
FileIn(Out)putStream-字节流复制文本文件

需求1:将项目路径下a.txt复制到项目路径下b.txt

数据源:从哪里来
a.txt – 读取数据 – FileInputStream

目的地:到哪里去
b.txt – 写数据 – FileOutputStream

输入流如果指定的文件,不存在则会报错,而输出流指定文件不存在则会自动参文件(注意:是创建文件,不能自动创建文件夹)
java.io.FileNotFoundException: a.txt (系统找不到指定的文件。)

前一次出现乱码的原因在于每次获取到一个字节数据,就把该字节数据转换为了字符数据,然后输出到控制台。
而这一次呢?确实通过IO流读取数据,写到文本文件,读取一个字节,就写入一个字节,你没有做任何的转换。
它会自己做转换。

代码演示

public class CopyFileDemo {
    public static void main(String[] args) throws IOException {
        //创建输入流对象
        FileInputStream fis = new FileInputStream("a.txt");
        //创建输出流对象
        FileOutputStream fos = new FileOutputStream("b.txt");
        //创建字节数组
        byte[] bys = new byte[1024];
        int len = 0;
        //读取数据
        while ((len=fis.read(bys))!=-1){
        	//写数据,写实际读取的数据
            fos.write(bys,0,len);
        }
        //释放资源
        fis.close();
        fos.close();
    }
}

结果:复制到b.txt的结果

package com.ginger.demo07;

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

public class CopyFileDemo {

    public static void main(String[] args) throws IOException {
        //创建输入流对象
        FileInputStream fis = new FileInputStream("a.txt");
        //创建输出流对象
        FileOutputStream fos = new FileOutputStream("b.txt");
        //创建字节数组
        byte[] bys = new byte[1024];
        int len = 0;
        //读取数据
        while ((len=fis.read(bys))!=-1){
            fos.write(bys,0,len);
        }
        //释放资源
        fis.close();
        fos.close();
    }
}

需求2:将D盘的a.txt复制到E盘的b.txt
数据源:从哪里来
D:\a.txt – 读取数据 – FileInputStream

目的地:到哪里去
E:\b.txt – 写数据 – FileOutputStream

代码演示:

public class CopyFileDemo2 {
	public static void main(String[] args) throws IOException {
		// 封装数据源
		FileInputStream fis = new FileInputStream("C:\\a.txt");
		// 封装目的地
		FileOutputStream fos = new FileOutputStream("D:\\b.txt");

		// 复制数据
		int by = 0;
		//读数据
		while ((by = fis.read()) != -1) {
			//写数据
			fos.write(by);
		}

		// 释放资源
		fos.close();
		fis.close();
	}
}
FileIn(Out)putStream-字节流复制图片和mp4

需求:字节流复制图片
数据源:从哪里来
东方不败.jpg – FileInpuptStream

目的地:到哪里去
E:\林青霞.jpg – FileOutptStream

代码演示

public class CopyImgDemo {
    public static void main(String[] args) throws IOException {
        //创建字节输入流对象
        FileInputStream fis = new FileInputStream("东方不败.jpg");
        //创建字节输出流对象
        FileOutputStream fos = new FileOutputStream("E:\\林青霞.jpg");
        //创建字节数组
        byte[] bys = new byte[1024];
        int len =0;
        //复制数据
        while ((len=fis.read(bys))!=-1){
            fos.write(bys,0,len);
        }
        //释放资源
        fis.close();
        fos.close();
    }
}

需求:字节流复制mp4
数据源:从哪里来
D:\纪晓斌-哥有老婆(高清).mp4 – FileInpuptStream

目的地:到哪里去
E:\纪晓斌-哥有老婆(高清).mp4 – FileOutptStream

代码演示

public class FileImgDemo02 {
    public static void main(String[] args) throws IOException {
        //创建字节输入流对象
        FileInputStream fis = new FileInputStream("D:\\周杰伦-霍元甲 (《霍元甲》电影主题曲)(高清)");
        //创建字节输出流对象
        FileOutputStream fos = new FileOutputStream("E:\\周杰伦-霍元甲 (《霍元甲》电影主题曲)(高清)");

        //创建字节数组
        byte[] bys = new byte[1024];
        int len = 0;
        //(len = fis.read(bys))!=-1
        while((len=fis.read(bys))!=-1){
                fos.write(bys,0,len);
        }
        //释放资源
        fis.close();
        fos.close();
    }
}
FileIn(Out)putStream-计算机是如何识别什么时候该把两个字节转换为一个中文呢?

在计算机中中文的存储分两个字节:

		第一个字节肯定是负数。
  		第二个字节常见的是负数,可能有正数。但是没影响。

代码演示

public class StringDemo {
	public static void main(String[] args) {
		// String s = "abcde";
		// // [97, 98, 99, 100, 101]

		String s = "我爱你中国";
		// [-50, -46, -80, -82, -60, -29, -42, -48, -71, -6]

		byte[] bys = s.getBytes();
		System.out.println(Arrays.toString(bys));
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值