1.IO流概述及其分类

* 1.概念(什么是IO?)
  * IO流用来处理设备之间的数据传输
  * Java对数据的操作是通过流的方式
  * Java用于操作流的类都在IO包中
  * 流按流向分为两种:输入流,输出流。
  * 流按操作类型分为两种:
    * 字节流 : 字节流可以操作任何数据,因为在计算机中任何数据都是以字节的形式存储的
    * 字符流 : 字符流只能操作纯字符数据,比较方便。
* 2.IO流常用父类
* 字节流的抽象父类:
  * InputStream
    * 1.字节输入流的所有类的超类
    * 2.抽象类不能实例化,使用的时候需要创建子类对象。
      * FileInputStream------文件输入流
        * 从系统中的某个文件中,获得输入字节。
  * OutputStream
    * 1.输出字节流的所有类的超类。
      * FileOutputStream-----文件输出流
   * 字符流的抽象父类:
    * Reader
      * 读取字符流的抽象类。
    * Writer
      * 写出字符流的抽象类。
* 3.IO程序书写
  * 使用前,导入IO包中的类
  * 使用时,进行IO异常处理
  * 使用后,释放资源

2.FileInputStream

  * read(),没有参数时,读取一个字节;也可以有参数,一个字节数组或……
  * 1.一次读取一个字节,可以读一个字节数组,从输入流读入一定长度的字节
  * 2.文件达到末尾返回-1
  * 3.方法的返回值都是int类型

FileInputStream fis = new FileInputStream("xxx.txt");
int x = fis.read();//读入一个字节数,
System.out.println(x);

3.FileInputStream返回值为什么是int?

  read()方法读取的是一个字节,为什么返回是int,而不是byte??
  因为字节输入流可以操作任意类型的文件,比如图片音频等,这些文件底层都是以二进制形式的存储的,如果每次读取都返回byte,有可能在读到中间的时候遇到11111111
那么这11111111是byte类型的-1,我们的程序是遇到-1就会停止不读了,后面的数据就读不到了,所以在读取的时候用int类型接收,如果11111111会在其前面补上24个0凑足4个字节,那么byte类型的-1就变成int类型的255了这样可以保证整个数据读完,而结束标记的-1就是int类型。

4.FileOutputStream

* 若没有源文件,则创建一个文件;若有的话,就清空文件中的内容,然后写进去。
* write() 有参数,可以是int类型整数,可以是字节数组,或一定长度的字节数组
* 1.一次写出一个字节,读取最底层的二进制代码 FileOutputStream fos = new FileOutputStream("xxx.txt");//创建输出流对象,直接指定路径
fos.write(97);
fos.write(98);
* FileOutputStream的构造方法写出数据如何实现数据的追加写入??
* //源文件中有数据内容,要想在后面追加内容,就得如下所示:
FileOutputStream fos = new FileOutputStream("xxx.txt",true);
fos.write(97);
fos.write(98);
/* 拷贝图片
FileInputStream fis = new FileInputStream("美女.jpg");
FileOutputStream fos = new FileOutputStream("小美女.jpg");
for(int b ; (b = fis.read()) != -1 ; ){
fos.write(b);
}
FileOutputStream fos = new FileOutputStream("大美女.jpg");
byte[] b = new byte[fis.available()];//文件的大小
fis.read(b);
fos.write(b);
fis.close();
fis.close();
*/

5.字节数组拷贝之available()方法

* int read(byte[] b)
* 1.把文件上的字节读取到一个字节数组中去
* 2.返回的是读到字节的个数。
* write(byte[] b)
* 1.一次写出一个字节数组
* 2.写出的是字节数组中的所有元素
* available()获取读的文件所有的字节个数
* 弊端:有可能会内存溢出

* write(byte[] b) //每次写出一个字节数组的字节
* write(byte[] b, int off, int len)//写出有效的字节个数

6.BufferedInputStream和BufferOutputStream拷贝

* A:缓冲思想
    * 字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多,
    * 这是加入了数组这样的缓冲区效果,java本身在设计的时候,
    * 也考虑到了这样的设计思想(装饰设计模式后面讲解),所以提供了字节缓冲区流
* B:BufferedInputStream和BufferedOutputStream的构造方法
* 如果文件足够大,read()方法执行一次,就会将文件上字节数据一次读取8192个字节存储在,BufferedInputStream的缓冲区中
     * 从缓冲区中返给一个字节一个字节返给b
     * 如果write一次,先将缓冲区装满,然后一股脑的写到文件上去
     * 这么做减少了到硬盘上读和写的操作

package cn.wh.*;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo_Test {
/**
* @param args
* 拷贝音频文件:
* 1.一个一个字节的输入
* 2.创建大数组输入
* 3.创建小数组
* 4.BuffeedInputStream、BufferedOutputStream
* @throws IOException
*/
public static void main(String[] args) throws IOException {
//1.一个一个字节的输入:效率比较慢,开发不建议使用
/*FileInputStream fis = new FileInputStream("喜欢你.mp3");//创建输入流对象,关联“喜欢你.jpg文件”
FileOutputStream fos = new FileOutputStream("likeyou.mp3");
int b ;
while((b = fis.read()) != -1 ){
fos.write(b);
}
fis.close();
fos.close();
*/
//2.创建一个大数组
/*FileInputStream fis = new FileInputStream("喜欢你.mp3");
FileOutputStream fos = new FileOutputStream("likeyou1.mp3");
byte[] b = new byte[fis.available()];//available()是求字节长度的,返回值类型为int。
fis.read(b);
fos.write(b);
fis.close();
fos.close();*/
//3.创建小数组进行接收:
/*FileInputStream fis = new FileInputStream("喜欢你.mp3");
FileOutputStream fos = new FileOutputStream("likeyou2.mp3");
byte[] b = new byte[1024*8];(8192)
int len ;
//len = fis.read();将文件上的数据,读取到字节数组b中
while((len = fis.read(b)) != -1){
fos.write(b,0,len);//从指定的数组中写出指定长度的字节
}
fis.close(); //关流
fos.close();*/
//4.BufferedInputStream 、BufferedOutputStream
/*BufferedInputStream bis = new BufferedInputStream(new FileInputStream("喜欢你.mp3"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("likeyou3.mp3"));
int b ;
while((b = bis.read()) != -1){
bos.write(b);
}
bis.close();
bos.close();*/
}
}

7.字节流读写中文

* 字节流读取中文的问题
  * 一个中文俩个字节
* 字节流写出中文的问题
  * 写出回车换行 (\r\t)
  * 字节流只读中文是有弊端的,有可能会读到半个中文,导致乱码产生。
  * 解决方法有:
    * 1,用字符流读(编码表+字节流)
    * 2,将文件上的所有字节一次读到内存中,在内存中将所有字节转换成对应的字符串
    * ByteArrayOutputStream
   * 字节流写中文
    * 在只写中文的时候必须转换成字节数组写出去
    * FileOutputStream fos = new FileOutputStream("ccc.txt");
    * fos.write("我爱你".getBytes());//String类中的getBytes()方法,将字符串转换成字节数。

  * 字节流可以拷贝任意类型的数据,因为所有的数据都是以字节的形式存在的
    * 拷贝的四种形式

8.流的标准处理异常代码1.6版本及其以前

* 在try()中创建的流对象必须实现了AutoCloseable这个接口,如果实现了,在try后面的{}(读写代码)执行后就会自动调用流对象的close方法将流关掉

        try finally嵌套
//标准的异常处理代码
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("aaa.txt");
fos = new FileOutputStream("bbb.txt");
int b;
while((b = fis.read()) != -1) {
fos.write(b);
}
} finally {
try {
if(fis != null)
fis.close();
}finally {
if(fos != null)
fos.close();
}
}

9.流的标准处理异常代码1.7版本

try close
try(
FileInputStream fis = new FileInputStream("aaa.txt");
FileOutputStream fos = new FileOutputStream("bbb.txt");
//MyClose mc = new MyClose();
){
int b;
while((b = fis.read()) != -1) {
fos.write(b);
}
}
给图片加密
package cn.wh;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo_Practure {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
//加密:
FileInputStream fis = new FileInputStream("美女.jpg");
FileOutputStream fos = new FileOutputStream("girl.jpg");
int b ;
while((b = fis.read()) != -1){
fos.write(b^12306);
}
//解密:
FileInputStream fis1 = new FileInputStream("girl.jpg");
FileOutputStream fos1 = new FileOutputStream("girl1.jpg");
int c ;
while((c = fis1.read()) != -1){
fos1.write(c^12306);
}
}
}
* 在控制台录入文件的路径,将文件拷贝到当前项目下
package cn.wh;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;
public class Test_03 {
/**
* @param args
* 在控制台录入文件的路径,将文件拷贝到当前项目下
* @throws IOException
*/
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
System.out.println("请输入:");
String str = sc.nextLine();
File file = new File(str);//把字符串转换成文件对象,方便利用文件对象的方法。即封装成File对象。
FileInputStream fis = new FileInputStream(file);//相当于拿到了文件的路径。
FileOutputStream fos = new FileOutputStream(file.getName());//File对象中的只得到名字的方法。
//就相当于相对路径
byte[] b = new byte[8192];
int len ;
while((len = fis.read(b)) != -1 ){
fos.write(b,0,len);
}
fis.close();
fos.close();
}
}
* 将键盘录入的数据拷贝到当前项目下的text.txt文件中,键盘录入数据当遇到quit时就退出
package cn.itcast.day20;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;
public class Demo_IO_Test_1 {
/**
* @param args
* 将键盘录入的数据拷贝到当前项目下的text.txt文件中,键盘录入数据当遇到quit时就退出
* @throws IOException
*/
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
FileOutputStream fos = new FileOutputStream("text.txt");
System.out.println("请输入:");
while(true){
String str = sc.nextLine();
if("quit".equals(str)){
break;
}
fos.write(str.getBytes());
fos.write("\r\n".getBytes());
}
}
}
flush和close的区别?
* flush刷新之后还可以继续写。
* close在关闭之前会刷新一次,把缓冲区剩余的字节刷到文件上去,但是调用之后不能再写。

IO、FileInputStream、(二十)的更多相关文章

  1. Java IO(二十) PrintStream 和 DataOutputStream 异同

    Java IO(二十) PrintStream 和 DataOutputStream 异同 一.相同点 都是继承与FileOutputStream,用于包装其它输出流. 二.不同点 (一).Print ...

  2. Java学习之路(十二):IO流<二>

    字符流 字符流是可以直接读写字符的IO流 使用字符流从文件中读取字符的时候,需要先读取到字节数据,让后在转换为字符 使用字符流向文件中写入字符时,需要把字符转为字节在写入文件 Reader和Write ...

  3. Java基础(二十六)Java IO(3)字节流(Byte Stream)

    字节流是以字节为单位来处理数据的,由于字节流不会对数据进行任何转换,因此用来处理二进制的数据. 一.InputStream类与OutputStream类 1.InputStream类是所有字节输入流的 ...

  4. Java基础学习笔记二十 IO流

    转换流 在学习字符流(FileReader.FileWriter)的时候,其中说如果需要指定编码和缓冲区大小时,可以在字节流的基础上,构造一个InputStreamReader或者OutputStre ...

  5. JAVA之旅(二十九)——文件递归,File结束练习,Properties,Properties存取配置文件,load,Properties的小练习

    JAVA之旅(二十九)--文件递归,File结束练习,Properties,Properties存取配置文件,load,Properties的小练习 我们继续学习File 一.文件递归 我们可以来实现 ...

  6. JAVA之旅(二十六)——装饰设计模式,继承和装饰的区别,LineNumberReader,自定义LineNumberReader,字节流读取操作,I/O复制图片

    JAVA之旅(二十六)--装饰设计模式,继承和装饰的区别,LineNumberReader,自定义LineNumberReader,字节流读取操作,I/O复制图片 一.装饰设计模式 其实我们自定义re ...

  7. JAVA基础知识总结:一到二十二全部总结

    >一: 一.软件开发的常识 1.什么是软件? 一系列按照特定顺序组织起来的计算机数据或者指令 常见的软件: 系统软件:Windows\Mac OS \Linux 应用软件:QQ,一系列的播放器( ...

  8. WCF学习之旅—实现支持REST客户端应用(二十四)

    WCF学习之旅—实现REST服务(二十二) WCF学习之旅—实现支持REST服务端应用(二十三) 在上二篇文章中简单介绍了一下RestFul与WCF支持RestFul所提供的方法,及创建一个支持RES ...

  9. java web学习总结(二十四) -------------------Servlet文件上传和下载的实现

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...

随机推荐

  1. ElasticSearch聚合入门(续)

    主要理解聚合中的terms. 参考:http://www.cnblogs.com/xing901022/p/4947436.html Terms聚合 记录有多少F,多少M { "size&q ...

  2. Python入门--13--递归

    什么是递归: 有调用函数自身的行为 有一个正确的返回条件 设置递归的深度: import sys sys.setrecursionlimit(10000) #可以递归一万次 用普通的方法也就是非递归版 ...

  3. PHP输出控制函数(ob系列函数)

    PHP输出控制函数(ob系列函数) flush — 刷新输出缓冲ob_clean — 清空(擦掉)输出缓冲区ob_end_clean — 清空(擦除)缓冲区并关闭输出缓冲ob_end_flush — ...

  4. BZOJ 2957 楼房重建 (线段树)

    题目链接  楼房重建 解题思路:我们可以把楼房的最高点的斜率计算出来.那么问题就转化成了实时查询x的个数,满足数列x的左边没有大于等于x的数. 我们可以用线段树维护 设t[i]为如果只看这个区间,可以 ...

  5. Linux下xz与tar的区别

    同一文件,tar.xz格式比tar.gz格式小了三分之一! 说明: xz是一个使用LZMA压缩算法的无损数据压缩文件格式. 和gzip与bzip2一样,同样支持多文件压缩,但是约定不能将多于一个的目标 ...

  6. go语言学习之路四:字典

    关联数组:(哈希或者字典) Map是go内置关联数据类型,字典是通过Key来访问Value的,访问格式如下: Value=mapName[key] 其实数组可以看做是一个键值类型为整型的字典,可以说数 ...

  7. 【kotlin】报错:required:LIst<XXX> found:List<Unit>此类型的问题

    出现问题如下: 解决方式如下: 解决思路:上面报出来的错误很明显,就是说想要的是List<XXX>类型但是给的却是List<Unit>类型,给的不是它想要的嘛 关键就是解决问题 ...

  8. Python的未来和Python的意义 & pypy & JIT

    今天在读关于Lisp的文章,感概于这门语言的生命力(Link).同时也读到了关于python的文章,Python之父谈Python的未来(Link) 文章中拿Python和Javascript作比较, ...

  9. BZOJ 题目1036: [ZJOI2008]树的统计Count(Link Cut Tree,改动点权求两个最大值和最大值)

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 8421  Solved: 3439 [Submi ...

  10. Effective C++ 条款九、十 绝不在构造和析构过程中调用virtual函数|令operator=返回一个reference to *this

      1.当在一个子类当中调用构造函数,其父类构造函数肯定先被调用.如果此时父类构造函数中有一个virtual函数,子类当中也有,肯定执行父类当中的virtual函数,而此时子类当中的成员变量并未被初始 ...