IO流
(1)IO用于在设备间进行数据传输的操作
(2)分类:
A:流向
输入流 读取数据
输出流 写出数据
B:数据类型
字节流
字节输入流
字节输出流
字符流
字符输入流
字符输出流
IO流分类
字节流:
InputStream
FileInputStream
BufferedInputStream
OutputStream
FileOutputStream
BufferedOutputStream
字符流:
Reader
FileReader
BufferedReader
Writer
FileWriter
BufferedWriter
注意:
a:如果我们没有明确说明按照什么分,默认按照数据类型分。
b:除非文件用windows自带的记事本打开我们能够读懂,才采用字符流,否则建议使用字节流。
(3)FileOutputStream写出数据
A:操作步骤
a:创建字节输出流对象
b:调用write()方法
写出数据的方式:
write(byte[] b) 写一个字符数组
write(byte[] int off, int len) 写一个字符数组的一部分
write(int b) 写一个字节
c:释放资源
B:代码体现:
FileOutputStream fos = new FileOutputStream("fos.txt");
fos.write("hello".getBytes());
fos.close();
1 public class FileOutputStreamDemo { 2 3 public static void main(String[] args) throws IOException { 4 //创建字节输出流对象 5 FileOutputStream fos = new FileOutputStream("fos.txt"); 6 //写数据 7 /* 8 * write(byte[] b) 写一个字符数组 9 * write(byte[] int off, int len) 写一个字符数组的一部分 10 * write(int b) 写一个字节 11 * 12 * 这里要输入的是字符串 所以得转化成字节型 13 */ 14 fos.write("hello,IO".getBytes()); 15 //释放资源 16 fos.close(); 17 } 18 }
1 public class FileOutputStreamDemo2 { 2 public static void main(String[] args) throws IOException { 3 //创建字节输出流对象 4 FileOutputStream fos = new FileOutputStream("fos2.txt"); 5 6 //调用write方法 7 //write(int b) 8 fos.write(97); 9 fos.write(65); 10 11 //write(byte[] b) 12 byte[] bys = {97,98,100,100,102}; 13 fos.write(bys); 14 15 //write(byte[] b, int off,int len ) 16 fos.write(bys, 1, 3); 17 18 //释放资源 19 fos.close(); 20 } 21 22 }
C:要注意的问题?
a:创建字节输出流对象做了几件事情?
b:为什么要close()?
让对象成为垃圾,通知系统释放资源
c:如何实现数据的换行?
d:如何实现数据的追加写入?
1 public class FileOutputStreamDemo3 { 2 3 public static void main(String[] args) throws IOException { 4 //创建字节输出流对象 5 //从头写 6 //FileOutputStream fos = new FileOutputStream("fos3.txt"); 7 8 //追加写 9 FileOutputStream fos = new FileOutputStream("fos3.txt" ,true); 10 //写数据 11 for(int x = 0; x < 19; x++){ 12 fos.write(("hello" + x).getBytes()); 13 fos.write("\r\n".getBytes());//换行 14 } 15 16 ///释放资源 17 fos.close(); 18 } 19 }
异常的处理
1 public class FileOutputStreamDemo4 { 2 public static void main(String[] args) { 3 //为了finally 里面能够看到改对象就必须定义到外面 另外为了访问不出问题,还必须初始化值 4 FileOutputStream fos = null; 5 try{ 6 fos = new FileOutputStream("fos4.txt"); 7 fos.write("hello".getBytes()); 8 }catch (FileNotFoundException e) { 9 e.printStackTrace(); 10 }catch (Exception e) { 11 e.printStackTrace(); 12 }finally{ 13 //如果fos不是null 才执行close() 14 if (fos != null){ 15 //为了保证close一定执行 16 try{ 17 fos.close(); 18 }catch (IOException e){ 19 e.printStackTrace(); 20 } 21 } 22 } 23 } 24 25 }
(4)FileInputStream读取数据
A:操作步骤
a:创建字节输入流对象
b:调用read()方法
读取数据的方式: int read() 一次读取一个字节 int read(byte[] b) 一次读取一个字节数组
c:释放资源
B:代码体现:
FileInputStream fis = new FileInputStream("fos.txt");
//方式1
int by = 0;
while((by=fis.read())!=-1) {
System.out.print((char)by);
}
1 /* 2 * 字节输入流操作流程 3 * a.创建字节输入流对象 4 * b.调用read()方法读取数据并输出在控制台 5 * c.释放资源 6 * 7 * 读取数据的方式: 8 * a.int read() 一次读取一个字节 9 * b.int read(byte[] b) 一次读取一个字节数组 10 */ 11 public class FileInputStreamDemo { 12 public static void main(String[] args) throws IOException { 13 FileInputStream fis = new FileInputStream("fis.txt"); 14 int by = 0; 15 //读取 赋值 判断一次完成 16 while((by = fis.read()) != -1){ 17 System.out.print((char)by);//这里读取英文和符号不会出问题,因为做了强制转换,但是读取中文就会有问题了, 18 } 19 //释放资源 20 fis.close(); 21 } 22 23 }
//方式2
byte[] bys = new byte[1024];
int len = 0;
while((len=fis.read(bys))!=-1) {
System.out.print(new String(bys,0,len));
}
fis.close();
(5)案例:2种实现
A:复制文本文件
1 /* 2 * 复制文本文件 3 * 4 * 数据源 5 * a.txt 读取数据 FileInputStream 6 * 目的地 7 * b.txt 写数据 FileOutputStream 8 * 9 * 这次在复制时不会出现含有中文乱码的问题,因为通过IO流读取数据写到文本文件,没有做任何转换,读取一个写一个 10 */ 11 public class FileInputStreamDemo2 { 12 13 public static void main(String[] args) throws IOException { 14 //封装数据源 15 FileInputStream fis = new FileInputStream("a.txt"); 16 //封装目的地 17 FileOutputStream fos = new FileOutputStream("b.txt"); 18 19 int by = 0; 20 while((by = fis.read()) != -1){ 21 fos.write(by); 22 } 23 //释放资源 24 fos.close(); 25 fis.close(); 26 } 27 }
1 /* 2 * 一次读取一个字符数组:int read(byte[] b) 3 */ 4 public class FileInputStreamDemo4 { 5 6 public static void main(String[] args) throws IOException { 7 //创建字节输入流对象 8 FileInputStream fis = new FileInputStream("fis.txt"); 9 //读取数据 10 byte[] bys = new byte[1024]; 11 int len = 0; 12 while((len = fis.read(bys)) != -1){ 13 System.out.print(new String(bys, 0, len));//bys转换为字符串 14 } 15 //释放资源 16 fis.close(); 17 } 18 }
1 public class CopyFileDemo { 2 3 public static void main(String[] args) throws IOException { 4 //封装数据 5 FileInputStream fis = new FileInputStream("e:\\a.txt"); 6 FileOutputStream fos = new FileOutputStream("e:\\b.txt"); 7 8 //复制数据 9 byte[] bys = new byte[1024]; 10 int len = 0; 11 while((len = fis.read(bys)) != -1){ 12 fos.write(bys, 0, len); 13 } 14 //释放资源 15 fos.close(); 16 fis.close(); 17 } 18 }
注意:这里说一下在计算机中是怎么样来识别什么时候将两个字节转换为一个中文的。
由于在计算机中中文的存储分为两个字节:第一个字节肯定是负数,第二个字节一般是负数,也有可能是正数,但是没有 什么影响的哦。、
看下面的例子就明白了!!!!!
1 public class FileInputStreamDemo3 { 2 3 public static void main(String[] args) { 4 //String s = "abcfgj"; 5 //打印出 [97, 98, 99, 102, 103, 106] 6 7 String s = "数据了模型"; 8 //打印出 [-26, -107, -80, -26, -115, -82, -28, -70, -122, -26, -88, -95, -27, -98, -117] 9 byte[] bys = s.getBytes(); 10 System.out.println(Arrays.toString(bys)); 11 } 12 }
B:复制图片
1 /* 2 * 将f:\\a.jpg内容复制到当前项目目录下的b.jpg中 3 * 4 * 数据源:f:\\a.jpg 读取数据 FileInputStream 5 * 目的地:b.jpg 写出数据 FileOutPutStream 6 */ 7 public class CopyImage { 8 public static void main(String[] args) throws IOException { 9 //封装数据源 10 FileInputStream fis = new FileInputStream("f:\\a.jpg"); 11 //封装目的地 12 FileOutputStream fos = new FileOutputStream("b.jpg"); 13 14 //复制数据 15 int by = 0; 16 while((by = fis.read()) != -1){ 17 fos.write(by); 18 } 19 //释放资源 20 fos.close(); 21 fis.close(); 22 } 23 24 }
C:复制视频
1 /* 2 * 将e:\\天梯.mp4复制到当前项目目录下的c.mp4中 3 * 4 * 数据源: 5 * e:\\天梯.mp4 读取数据 FileInputStream 6 * 目的地: 7 * c.mp4 写出数据 FileOutputStream 8 */ 9 public class CopyMP4 { 10 11 public static void main(String[] args) throws IOException { 12 //封装数据源 13 FileInputStream fis = new FileInputStream("天梯.mp4"); 14 //封装目的地 15 FileOutputStream fos = new FileOutputStream("c.mp4"); 16 17 //复制数据 18 int by = 0; 19 while((by = fis.read()) != -1){ 20 fos.write(by); 21 } 22 23 //释放资源 24 fos.close(); 25 fis.close(); 26 } 27 }
1 /* 2 * 将e:\\天梯.mp4复制到当前项目目录下的c.mp4中 3 * 4 * 数据源: 5 * e:\\天梯.mp4 读取数据 FileInputStream 6 * 目的地: 7 * c.mp4 写出数据 FileOutputStream 8 */ 9 public class Copymp4demo { 10 11 public static void main(String[] args) throws IOException { 12 //封装数据源 13 FileInputStream fis = new FileInputStream("天梯.mp4"); 14 //封装目的地 15 FileOutputStream fos = new FileOutputStream("c.mp4"); 16 17 //复制数据 18 byte[] bys = new byte[1024]; 19 int len = 0; 20 while((len = fis.read(bys)) != -1){ 21 fos.write(bys, 0, len); 22 } 23 24 //释放资源 25 fos.close(); 26 fis.close(); 27 } 28 }
(6)字节缓冲区流
因为加入了数组这样的缓冲区,字节流一次读写一个数组的速度明显比一次读写一个字节的速度块很多,然而Java本身在设计的时候也考虑到了这样的设计思想, 提供了字节流缓冲区,缓冲区类。
写数据:BufferedOutputStream
1 public class BfferedOutputStreamDemo { 2 public static void main(String[] args) throws IOException { 3 //BufferedOutputStream(OutputStream out) 4 BufferedOutputStream bos = new BufferedOutputStream( 5 new FileOutputStream("bos.txt")); 6 //写数据 7 bos.write("hello".getBytes()); 8 //释放资源 9 bos.close(); 10 } 11 12 }
读数据:BufferedInputStream
1 public class BfferedInputStreamDemo1 { 2 //BufferedInputStream(InputStream in) 3 public static void main(String[] args) throws IOException { 4 BufferedInputStream bis = new BufferedInputStream( 5 new FileInputStream("bos.txt")); 6 //读取数据 方式一 7 int by = 0; 8 while((by = bis.read()) != -1){ 9 System.out.print((char) by); 10 } 11 12 //方式二 13 byte[] bys = new byte[1024]; 14 int len = 0; 15 while((len = bis.read(bys)) != -1){ 16 System.out.print(new String(bys, 0, len)); 17 } 18 //释放资源 19 bis.close(); 20 } 21 }
(7)案例:4种实现
复制视频
1 /* 2 *将e:\\天梯.mp4复制到当前目录下的a.mp4 3 * 4 *字节流四种方式复制文件: 5 *基本字节流一次读写一个字节 6 *基本字节流一次读取一个字符数组 7 *高效字节流一次读取一个字节 8 *高效字节流一次读取一个字节数组 9 */ 10 public class CopyMp4Demo3 { 11 public static void main(String[] args) throws IOException { 12 long start = System.currentTimeMillis(); 13 method1("e:\\天梯.mp4", "a.mp4 "); 14 //method2("e:\\天梯.mp4", "a.mp4 "); 15 //method3("e:\\天梯.mp4", "a.mp4 "); 16 //method4("e:\\天梯.mp4", "a.mp4 "); 17 long end = System.currentTimeMillis(); 18 System.out.println("共耗时:" + (end - start) + "毫秒"); 19 } 20 21 //基本字节流一次读写一个字节 22 private static void method1(String srcString, String destString) throws IOException { 23 FileInputStream fis = new FileInputStream(srcString); 24 FileOutputStream fos = new FileOutputStream(destString); 25 26 int by = 0; 27 while((by = fis.read()) != -1){ 28 fos.write(by); 29 } 30 31 fos.close(); 32 fis.close(); 33 } 34 35 //基本字节流一次读写一个字节数组 36 private static void method2(String srcString, String destString) throws IOException { 37 FileInputStream fis = new FileInputStream(srcString); 38 FileOutputStream fos = new FileOutputStream(destString); 39 40 byte[] bys = new byte[1024]; 41 int len = 0; 42 while((len = fis.read(bys)) != -1){ 43 fos.write(bys, 0, len); 44 } 45 46 fos.close(); 47 fis.close(); 48 } 49 50 //高效字节流一次读写一个字节 51 private static void method3(String srcString, String destString) throws IOException { 52 BufferedInputStream bis = new BufferedInputStream( 53 new FileInputStream(srcString)); 54 BufferedOutputStream bos = new BufferedOutputStream( 55 new FileOutputStream(destString)); 56 57 int by = 0; 58 while((by = bis.read()) != -1){ 59 bos.write(by); 60 } 61 62 bos.close(); 63 bis.close(); 64 } 65 66 //高效字节流一次读写一个字节数组 67 private static void method4(String srcString, String destString) throws IOException { 68 BufferedInputStream bis = new BufferedInputStream( 69 new FileInputStream(srcString)); 70 BufferedOutputStream bos = new BufferedOutputStream( 71 new FileOutputStream(destString)); 72 73 byte[] bys = new byte[1024]; 74 int len = 0; 75 while((len = bis.read(bys)) != -1){ 76 bos.write(bys); 77 } 78 79 bos.close(); 80 bis.close(); 81 } 82 }