字节流
IO流概述和分类
读得懂的是字符流,读不懂就是字节流
字节流写数据
在java.io包下,要导包
InputStream表示所有输入字节流的超类,OutputStream表示所有输入字节流的超类,子类名称都是以其父类名作为子类名的后缀
//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操作的最后都要释放资源
字节流写数据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();
追加写入
//追加写入
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();
字节流写数据加异常处理
//加入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中的内容读取出来在控制台输出
//创建文件输出流以指定的名称写入文件
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"
//根据数据源创建字节流输入对象
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中的内容读取出来在控制台输出
//创建字节输入流对象
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();
所以说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"
//根据数据源创建字节流输入对象
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();