IO流
IO流通常用来处理设备之间的数据传输
Java对数据的操作是通过流的形式
Java用于操作的流的类都在IO包
按照流向:分为输入流和输出流
按操作类型:
字节流:字节流可以操作任何数据,因为计算机的数据都是按照字节存放
字符流:字符流只能操作纯字符数据,比较方便
字符大 字节小
常用的父类:
抽象父类:InputStream(字节输入流) OutputStream(字节输出流)
抽象父类: Reader(字符输入流) Writer(字符输出流)
IO程序书写
导入IO包类,进行IO异常处理,释放资源
--------------------------------------------------------------------------
FileInputStream
FileInputStream fis = new FileInputStream("xxx.txt");
int x = fis.read();
System.out.println(x);
int y = fis.read();
System.out.println(y);
fis.close();
每read()一次,就向后移动一次并再次读取
注意,文件的结束标记是-1
while((len = fis.read())!=-1){
System.out.println(len);
}
fis.close();
为什么返回Int而不是Byte
任何文件读取的结束都是-1 为了保证读取过程中不会因为读到byte的-1而终止读取过程,因此选择读取int来执行操作
-----------------------------------------------------------------------------
拷贝图片,音乐 逐字节拷贝特别慢
available()方法 获取读取文件的所有字节个数(这个方法可能导致内存溢出)
FileInputStream fis = new FileInputStream("xxx.txt");
byte[] arr = new byte[fis.available()];//创建和文件一样大小的字节数组
fis.read(arr); 将文件上的字节读取到文件中(字节数组中)
FileOutputStream fos = new FileOutputStream("xxx");
fos.write(arr); 将字节数组中的字节数据写到文件上
----------------------------------------------------------------------------
读取小数组的方法
FileInputStream fis = new FileInputStream("xxx.txt");
byte[] arr = new byte[1024];
int len = 0;
while((len = fis.read(arr))!=-1)}{
fos.write(arr,0,len);
如果忘记加arr 返回不是读取的字节个数,而是字节的码表值,一定要先读到字节数里
-----------------------------------------------------------------------------
BufferInputStream
FileInputStream fis = new FileInputStream("xxx.txt");
FileOutputStream fos = new FileOutputStream("copy.txt");
BufferedInputStream bis = new BufferedInputStream(fis);//创建缓冲区,对输入流进行包装
BufferedOutputStream bos = new BufferedOutputStream(fos);//创建缓冲区,对输出流进行包装
int b ;
while((b=bis.read())!=-1){
bos.write(b);
}
bis.close();
bos.close();
字节流一次读取一个数组速度要更快
装饰设计模式,提供了字节缓冲区流
BuffferedInputStream bis 先在文件读取8192个数送到缓冲区,然后程序去缓冲区读取,如果所有缓冲区数据都被读完,再去获取8192个数据
BufferedOutputStream bos 程序将数据送到缓冲区,然后将缓冲区写满时,在将数据一次性送入到文件中
相比较而言,定义小数组要比Buffered读取更快,因为其读和写都是同一个数组,而Buffered操作的是两个数组
-----------------------------------------------------------------------------
flush()和close()的区别
BufferedInputStream bis = new BufferedInputStream(new FileInputStream());
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream());
如果不加close 拷贝文件会稍微小一点点 close方法具备刷新的功能,关闭流之前就会刷新一次缓冲区,将缓冲区的字节全部刷新到文件上,再关闭
用bos.flush()直接刷新缓冲区即可
close和flush相比较, flush刷新完仍然可以继续写入
flush--->实时刷新
--------------------------------------------------------------------------
字节流读写中文(字节流读取中文造成乱码)(GBK中一个字符两个字节)
FileInputStream fis = new FileInputStream("xxx.txt");
byte[] arr = new byte[3]();
int len;
while((len = fis.read())!=-1){
new String(arr,0,len);
}
fis.close();
而用字节流写出中文
FileOutputStream fos = new FileOutputStream("xxx");
fos.write("xxx".getBytes());
fos.write("\r\n".getBytes());//回车换行
fos.close();
--------------------------------------------------------------------------
标准异常处理代码
TryFinally
JDK 1.6以前
FileInputStream fis = null;
FileOutputStream fos = null;
try{
fis = new FileInputStream("xxx.txt");
fos = new FileOutputStream("xxx.txt");
}catch(Exception e){
e.printStackTrace();
}
finally{
try{
if(fis != null){
fis.close();
}
}finally{
if(fos != null){
fos.close();
}
}
JDK1.7
try(
FileInputStream fis = new FileInputStream("xxx.txt");
FileOutputStream fos = new FileOutputStream("xxx.txt");
){
int b;
while ((b = fis.read()) != -1) {
fos.write(b);
}
}
在try的小括号中书写类,必须要实现AutoCloseale接口
------------------------------------------------------
加密用异或操作,一个数异或两次等于其本身
拷贝文件
注意如果是自己拷贝文件,/r/n是换行操作符