字节流 IO流

字节流

IO流概述和分类

字节流 IO流_第1张图片
读得懂的是字符流,读不懂就是字节流
image.png

字节流写数据

在java.io包下,要导包
InputStream表示所有输入字节流的超类,OutputStream表示所有输入字节流的超类,子类名称都是以其父类名作为子类名的后缀
image.png

//FileOutputStream(String name),创建文件输出流以指定的名称写入文件
//创建字节输出流对象
FileOutputStream fos = new FileOutputStream(name:"myByteStream\\fos.txt");//alt enter抛出异常 FileNotFoundException
/*
创建字节输出流对象做了三件事情
    调用系统功能创建了文件 
    创建了字节输出流对象
    让字节输出流对象指向创建好的文件
*/

//write (int b)将指定的字节写入此文件输出流
fos.write(b:97);//抛出异常IOException 上面那个异常是这个的子类
//上面输出的是字符 也就是ASCII码值为97的字符,即a
fos.write(b:57);//输出字符9
fos.write(b:55);//输出字符7

//void close();关闭此文件输出流闭关释放与此流相关联的任何系统资源
fos.close();

所有和IO操作的最后都要释放资源
字节流 IO流_第2张图片

字节流写数据3种方式

字节流 IO流_第3张图片

//创建文件输出流以指定的名称写入文件
FileOutputStream fos = new FileOutputStream(name:"myByteStream\\fos.txt");//alt enter抛出异常 FileNotFoundException
//上面就是将输入的那个字符串路径封装成了一个新的File对象

///File file 创建文件输出流以写入由指定的File对象表示的文件
File file = new File(pathname:"myByteStream\\fos.txt");
FileOutputStream fos2 = new FileOutputStream(file);
//也就是
FileOutputStream fos3 = new FileOutputStream(new File(pathname:"myByteStream\\fos.txt"));

//写数据方式
//int b  下面输出abcde
fos.write(b:97);
fos.write(b:98);
fos.write(b:99);
fos.write(b:100);

//byte[] b 将字节从指定的字节数组写入此文件输出流
//先定义一个字节数组
byte[] bys = {97,98,99,100,101};//ASCII码值 还是转化成对应的字符 输出abcde
fos.write(bys);
//也可以通过String类的一个方法获得字节数组 getBytes();返回字符串对应的字节数组
byte[] bys = "abcde".getBytes();//通过字符串得到一个字节数组
fos.write(bys);//输出一样


///byte[] b,int off,int len 从指定的字节数组开始,从偏移量off开始写入此文件输出流
fos.write(bys,off:0,bys.length);//输出一样
fos.write(bys,off:1,len:3);//从索引1位置开始写三个 也就是写入bcd

//释放资源
fos.close();

字节流写数据的两个小问题

换行
//创建文件输出流以指定的名称写入文件
FileOutputStream fos = new FileOutputStream(name:"myByteStream\\fos.txt");//alt enter抛出异常 FileNotFoundException
//写数据
for(int i = 0;i<10;i++){
    fos.write("Hello".getBytes());
    fos.write("\r\n".getBytes());//windows系统\r\n时换行 用记事本打开才能换行 linux \n换行 mac \r换行
}

//释放资源
fos.close();

字节流 IO流_第4张图片

追加写入
//追加写入
FileOutputStream(String name,Boolean append);
//如果第二个参数append为true,则字节将写入文件的末尾而不是开头 true就是追加写入


//创建文件输出流以指定的名称写入文件
FileOutputStream fos = new FileOutputStream(name:"myByteStream\\fos.txt",append:true);//alt enter抛出异常 FileNotFoundException
//写数据
for(int i = 0;i<10;i++){
    fos.write("Hello".getBytes());
    fos.write("\r\n".getBytes());//windows系统\r\n时换行 用记事本打开才能换行 linux \n换行 mac \r换行
}

//释放资源
fos.close();

字节流 IO流_第5张图片

字节流写数据加异常处理

字节流 IO流_第6张图片
字节流 IO流_第7张图片

//加入finally来实现释放资源
//创建文件输出流以指定的名称写入文件
FileOutputStream fos = null;
try{
    fos = new FileOutputStream(name:"myByteStream\\fos.txt");
    fos.write("Hello".getBytes());
}catch(IOException e){
    e.printStackTrace();
}finally{
    if(fos != null){//不判断的花如果路径不存在执行finally那就会产生一个空指针
        try{
            fos.close();
        }catch(IOException e){
            e.printStackTrace();
        }
    } 
}

字节流读数据(一次读一个字节数据)

把文件fos.txt中的内容读取出来在控制台输出
字节流 IO流_第8张图片

//创建文件输出流以指定的名称写入文件
FileInputStream fis = new FileInputStream(name:"myByteStream\\fis.txt");//alt enter抛出异常IOException 

//调用字节输入流对象的读数据方法
//int read(); 从该输入流读取一个字节的数据
//读取数据 如果文件到达末尾,那么返回值是-1
//换行可以自己读取出来


//读取数据
int by = fis.read();
while(by != -1){
    System.out.print(by);
    System.out.print((char)by);//将ASCii码值强制转化为字符串
    by = fis.read();//输出前面那个然后读取下一个 再进行判断
}

//优化上面的循环
//fis.read()读数据
//by = fis.read() 把读取到的数据赋值给by
//by != -1 判断读取到的数据是否是-1
int by;
while((by = fis.read()) != -1){
    System.out.print(by);
    System.out.print((char)by);//将ASCii码值强制转化为字符串
}

//释放资源
fis.close();

案例 复制文本文件

把"E:\itcast\窗里窗外.txt"复制到模块目录下的"窗里窗外.txt"
字节流 IO流_第9张图片
字节流 IO流_第10张图片

//根据数据源创建字节流输入对象
FileInputStream fis = new FileInputStream(name:"E:\\itcast\\窗里窗外.txt");//alt enter抛出异常IOException 
//根据目的地创建字节输出流对象
FileOutputStream fos = new FileOutputStream(name:"myByteStream\\窗里窗外.txt");//alt enter抛出异常IOException 

//读写数据 复制文本文件 一次读取一个 一次写入一个
int by;
while((by = fis.read()) != -1){
    fos.write(by);
}

//释放资源
fis.close();
fos.close();

字节流读数据(一次读一个字节数组数据)

把文件fos.txt中的内容读取出来在控制台输出
字节流 IO流_第11张图片

//创建字节输入流对象
FileInputStream fis = new FileInputStream(name:"myByteStream\\fis.txt");//alt enter抛出异常IOException 

//调用字节输入流对象的读数据方法 一次读一个字节数组
//int read(byte[] b); 从该输入流读取最多b.length个字节的数据到一个字节数组
byte[] bys = new byte[5];//创建一个字节数组容器

//实际读取长度是-1,说明已经到了末尾


//第一次读取数据
int len = fis.read(bys);
sout(len);//输出5
//String(byte[] bytes)
sout(new String(bys));//输出Hello

//第一次读取数据
int len = fis.read(bys);
sout(len);//输出5
sout(new String(bys));//输出wor

/*
Hello\r\n
world\r\n
输出 第一次Hello
     第二次\r\nwor 在控制台输出\r\n就变成了换行空格
     第三次ld\r\nr 因为最后只剩下四个 所以只有前面四个位置的内容换了,第五个没换还保留原来第五个的内容也就是r 输出变成ld 换行 r
*/
//释放资源
fis.close();

字节流 IO流_第12张图片
所以说len返回的不是字节数组的长度,而是实际我们读取的数据的个数

sout(new String(bys,offset:0,len));//读了几个数据就转换几个数据

优化用循环改进

byte[] bys = new byte[1024];//一般是1024及其整数倍
int len;
while((len = fis.read(bys))!= -1){
    sout(new String(bys,offset:0,len));//读了几个数据就转换几个数据
}
//释放资源
fis.close();

案例 复制图片

把"E:\itcast\mn.jpg"复制到模块目录下的"mn.jpg"
字节流 IO流_第13张图片

//根据数据源创建字节流输入对象
FileInputStream fis = new FileInputStream(name:"E:\\itcast\\mn.jpg");//alt enter抛出异常IOException 
//根据目的地创建字节输出流对象
FileOutputStream fos = new FileOutputStream(name:"myByteStream\\mn.jpg");//alt enter抛出异常IOException 

//读写数据 复制图片 一次读取一个字节数组 一次写入一个字节数组
byte[] bys = new byte[1024];
int len;
while((len = fis.read(bys))!= -1){
    fos.write(bys,offset:0,len);
}

//释放资源
fis.close();
fos.close();

你可能感兴趣的:(java)