• 微信公众号:美女很有趣。 工作之余,放松一下,关注即送10G+美女照片!

IO

开发技术 开发技术 2周前 (05-04) 8次浏览

  最近,因为项目不是太想学习新的新知识,就想总结前面的知识。下面我们就简单归纳归纳JAVA-IO知识。

  IO是java中十分重要的知识,那么什么是IO,即inout,java中是通过“流”来处理io的,进而实现了程序与外设的数据传输。

  • 流的特点:

    1、先进先出:最先写入的输出流,会最先被输入流读取到

    2、顺序存储:写入是可以先一个一个的写入一串字节,读入时,也可以一串一串的读入,不能随机访问(randomAccessFile)除外。

    3、每一种流的功能是单一的,只能是只读或者只写

  •   流的分类

    1、按照数据的方向:输入流,输出流

    2、按处理数据单位:字节流,字符流

    3、按照功能:   节点流,处理流

  输入流和输出流就比较好理解,从外部读取文件,就是输入流,将数据写入到外部文件,就是输出流。

  字节流和字符流:总的来说就是,字节流能够处理一切的文件,而字符流只能处理纯文本文件。那么,我们都有字节流能处理一切的文件,为什么还要有字符流呢,原因是:在java中采用Unicode编码,在Unicode中,一个英文占用一个字节(8bits),我们中文为2个字节(16bits)。但是在UTF-8编码中,英文占用2个字节,中文占用3个字节,我们使用字节流处理中文,如果一次读写一个字符对应的字节数,就不会有问题,但是如果如果我们将字符对应的的字节分裂开来,就会出现乱码了。

  区别:字节流本身是没有缓冲区的,但是缓冲字节流,相比较于字节流,效率提升就比较大。但是字符流本身是有缓冲区的,所以说缓冲字符流对于字符流的效率提升就不是很大。。

 

 

 

  1、FileOutputStream(字节输出流):,继承自OutputStream,一般用于写入诸如图像数据的原始字节流。 要编写字符流,请考虑使用FileWriter
下面我们来简单演示一下fileOutputStream的常用方法和构造方法
FileOutputStream​(File file)
创建文件输出流以写入由指定的 File对象表示的文件。
FileOutputStream​(FileDescriptor fdObj)
创建要写入指定文件描述符的文件输出流,该文件描述符表示与文件系统中实际文件的现有连接。
FileOutputStream​(File file, boolean append)
创建文件输出流以写入由指定的 File对象表示的文件。
FileOutputStream​(String name)
创建文件输出流以写入具有指定名称的文件。
FileOutputStream​(String name, boolean append)
创建文件输出流以写入具有指定名称的文件。 
  可以看到FileOutputStream主要有两种构造方法,一种是传入文件对象,另外一种方法时传入一个文件路径(保证文件存在),另外我们会发现还有一个boolean append的参数,这个参数的意义就是,是否追加,
就是如果原文件如果有字节,我们传入不写,或者是传入false的时候,它就会覆盖原来的内容。下面看演示↓:
 1 FileOutputStream fileOutputStream = new FileOutputStream("a.txt");
 2         byte[] bytes1 = new byte[]{66,67,68};       //BCD
 3         byte[] bytes2 = new byte[]{69,70,71,72,73}; //EFGHI
 4         byte[] bytes3 = "XYZ".getBytes();
 5 
 6         fileOutputStream.write(65);      //会写入A
 7         fileOutputStream.write(bytes1);     //会写入B,C,D
 8         fileOutputStream.write(bytes2,1,2);     //传入一个字节数组,从指定下标开始写入指定长度,从F开始,写入两个长度就是FG
 9         fileOutputStream.write(bytes3);     //会写入XYZ
10         
11         fileOutputStream.close();       //关闭流,一定不要忘记,一定不要忘记,一定不要忘记
12         System.out.println("ok");

字节输出流->>>>>>:结果

IO

 

 

 可以看到:我们可以写入一个字节,一个字节数组,或者是一个从指定下标开始,写入指定长度的数组,最后不要忘记关闭就行。

 

 

 

  2、FileInputStream (字节读取流):继承自inputStream,用于读取字节,并返回一个int类型的数组或者字节。下面我们演示一下构造方法和常用api

  

 
构造器 描述
FileInputStream​(File file)
通过打开与实际文件的连接来创建 FileInputStream ,该文件由文件系统中的 File对象 file命名。
FileInputStream​(FileDescriptor fdObj)
使用文件描述符 fdObj创建 FileInputStream ,该文件描述符表示与文件系统中实际文件的现有连接。
FileInputStream​(String name)
通过打开与实际文件的连接来创建 FileInputStream ,该文件由文件系统中的路径名 name命名。 

  和FileOutputStream类似,FileInputStream 主要也是两种构造方法,一个是传入文件对象,另外一个是传入文件路径(该文件存在)。

 

int read()
从此输入流中读取一个字节的数据。
int read​(byte[] b)
从此输入流 b.length最多 b.length字节的数据读 b.length字节数组。
int read​(byte[] b, int off, int len)
从此输入流 len最多 len字节的数据读入一个字节数组。 

    Read(byte[] b):读取一个字节数组的数据    
    Read():读取一个字节的数据
    read(byte[] b int off ,int len):从指定长度开始,读取指定的长度字节的数据



演示一次读取一个数据:
1 FileInputStream fileInputStream = new FileInputStream("a.txt");  //a.txt的内容是:ABCDEF
2         while (true){
3             int i = fileInputStream.read();
4             if (i == -1){                   //字节读取流,返回的是一个int类型,如果读取到结尾,就会返回-1,返回-1就跳出循环
5                 break;
6             }
7             System.out.print((char) i+" ");
8         }
9         fileInputStream.close();

输出结果:A B C D E F 
分析:::可以看出,一次读入一个字节数据,读到末尾就返回-1


下面演示一次读取一个byte数组的数据:
 1  ////txt的内容是小写字母表,一共26个
 2         FileInputStream fileInputStream = new FileInputStream("a.txt");
 3         //创建一个10个字节长度的字节数组
 4         byte[] bytes = new byte[10];
 5         int len = fileInputStream.read(bytes);
 6         //每读取一次,就new为字符串,并打印
 7         System.out.println(new String(bytes)+"长度为:"+len);
 8         fileInputStream.read(bytes);
 9         System.out.println(new String(bytes)+"长度为:"+len);
10         fileInputStream.read(bytes);
11         System.out.println(new String(bytes)+"长度为:"+len);
12         fileInputStream.close();

输出结果:

abcdefghij长度为:10
klmnopqrst长度为:10
uvwxyzqrst长度为:10

 

  分析:可以看到我们每一次读取了10b长度的数组,但是细心就会发现,我们最后一次明明没有10个b长度的数据,但是也读取了10个,这里我们就分析其中的具体过程,我们第一次读取abcdefghij,

然后第二次读取klmnopqrst,其中就会替换掉原来第一次读取的,我们第三其实读取的是uvwxyz,替换掉第二次读取的klmnopqrst,但是只有uvwxyz,最后的qrst就没有被替换掉,所以就造成了这个结果,

这也是我们平时,下载的安装包,总会比官方的给出的大小会多出那么几kb。

  解决方法,在构建为字符串时,将返回的长度,传给new String()构造方法,下面看代码:

 

 1    ////txt的内容是小写字母表,一共26个
 2         FileInputStream fileInputStream = new FileInputStream("a.txt");
 3         //创建一个10个字节长度的字节数组
 4         byte[] bytes = new byte[10];
 5         int len = fileInputStream.read(bytes);
 6         //每读取一次,就new为字符串,并打印
 7         System.out.println(new String(bytes,0,len)+"长度为:"+len);
 8         len = fileInputStream.read(bytes);
 9         System.out.println(new String(bytes,0,len)+"长度为:"+len);
10         len = fileInputStream.read(bytes);
11         System.out.println(new String(bytes,0,len)+"长度为:"+len);
12         fileInputStream.close();

输出结果:

abcdefghij长度为:10
klmnopqrst长度为:10
uvwxyz长度为:6

 







 

 


 


程序员灯塔
转载请注明原文链接:IO
喜欢 (0)