java: IO总结篇

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java: IO总结篇相关的知识,希望对你有一定的参考价值。

一:概念

1.字符,字节,字符集(编码)

字节是内存存储数据的单位,字符则是一种数据。字节是存储容量的基本单位,1字节=8个二进制位,即一个8位的二进制数,是一个很具体的存储空间,如0x01,0xFA。

字符是指字母、数字、汉字和各种符号,如‘1‘,‘中‘,‘#’。一个字符在计算机中用若干个字节的二进制数表示,西文字符1个字节,中文字符2个字节。

字符集(编码):一种标准,规定使用哪些字符,每个字符分别用一个还是多个字节存储,用哪些字节存储;

2.流,字符流与字节流

流:一组有序的数据序列,可以理解为传输通道。Java中的IO流是输入输出流。

如何判断是输入流还是输出流?
以内存为参照物,如果数据是向内存流动是输入流,反之则是输出流。

将输入和输出两个端点看作是两个工厂,工厂之间需要互相运输货物,而流则是两工厂之间的公路,没有公路就不能互相运输,至于字符,字节和二进制则可以看作是运输的方式和单位大小,比如说把二进制理解成三轮车,那么字节就是小卡车,而字符则是更高级的集卡之类的。

字节流可处理所有类型的数据,如MP3,图片,文字,读取时,读到一个字节就返回一个字节;JAVA中字节流对应的类都以“Stream”结尾;

字符流仅可处理纯文本数据,读取时,读到一或多个字节,先查找指定的编码表,然后将查到的字符返回。在AVA中字符流对应的类都以“Reader”或"Writer"结尾;

字符流的底层就是字节流。而字符流主要是读取文本文件内容的,可以一个字符一个字符的读取,也可以一行一行的读取文本文件内容。而字节流读取单位为byte.byte作为计算机存储最基本单位,可以用字节流来读取很多其他格式的文件,比如图片视频等等。基于B/S和C/S的文件传输都可以采用字节流的形式。

二:函数

1.包括在输入输出功能的包Java.io中,所有方法遇到错误时均会抛出IOException异常。

2.java流分为两种流
字节流:可以用于读写二进制文件及任何类型文件byte
字符流:可以用于读写文件文本

字节流:输入(InputStream) 输出(OutputStream)
字符流:输入(Reader)         输出(writer)

Reader类的read()方法返回类型为int :作为整数读取的字符(占两个字节共16位),范围在 0 到 65535 之间 (0x00-0xffff),如果已到达流的末尾,则返回 -1(表明已成功读取完毕)
inputStream的read()虽然也返回int,但由于此类是面向字节流的,一个字节占8个位,所以返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。因此对于不能用0-255来表示的值就得用字符流来读取!比如说汉字.

 

3.FileInputStream 是文件输入流,它继承于InputStream。

通常,我们使用FileInputStream从某个文件中获得输入字节。

FileOutputStream 是文件输出流,它继承于OutputStream。

通常,我们使用FileOutputStream 将数据写入 File 或 FileDescriptor 的输出流。

 

4.带缓存的流

若不指定缓存区大小,默认为分配32个字节。

java.io.BufferedReader和java.io.BufferedWriter类各拥有8192字符的缓冲区。

BufferedReader:一个包装类,它可以包装字符流,将字符流放入缓存里,先把字符读到缓存里,到缓存满了或者你flush的时候,再读入内存,就是为了提供读的效率而设计的。如果缓冲区数据不足,才会再从文件中读取。

BufferedWriter:写入的数据并不会先输出到目的地,而是先存储至缓冲区中。如果缓冲区中的数据满了,才会一次对目的地进行写出。

 

5.从标准输入流System.in中直接读取使用者输入时,使用者每输入一个字符,System.in就读取一个字符。为了能一次读取一行使用者的输入,使用了BufferedReader来对使用者输入的字符进行缓冲。readLine()方法会在读取到使用者的换行字符时,再一次将整行字符串传入。

System.in是一个位流,为了转换为字符流,可使用InputStreamReader为其进行字符转换,然后再使用BufferedReader为其增加缓冲功能

 

三:过程

操作流程

在Java中IO操作也是有相应步骤的,以文件操作为例,主要的操作流程如下:

1 使用File类打开一个文件

2 通过字节流或字符流的子类,指定输出的位置

3 进行读/写操作

4 关闭输入/输出

IO操作属于资源操作,一定要记得关闭

 

四:常用方法 

字节流:

Inputstream:

read(int);

read(byte);

reset();

mark();

skip(long n);//以上三个只对某些子类有用

markSupported();

 

OutputStream(所有方法均返回void):

write(int);

write(byte);

flush(); //BufferedOutputStream中的方法,用来刷新内存,将内存中的数据立刻写出。

close();

 

字符流:

BufferedReader:

读取单个字符

read();//读取单个字符

readLine();//读取一个文本行,返回为字符串,无数据则返回null

 

BufferedWriter:

write();

flush();

newLine(); //写入一个行分隔符

 

五:代码

一:字节流

1.字节流的读入,写出,拷贝

其中用到字符串与字节数组的互相转化:

getBytes():将一个字符串转化为一个字节数组byte[]:getBytes(“utf-8”);

//FileInputStream
import java.io.FileInputstream;
import java.io.IOException;
import java.io.FileNotFoundException;

public class ReadByteStream{
   public static void main(String args[]){         
     //File类打开要读入的数据
     FileInputStream fis = new FileInputStream("text.txt");//使用一个相对路径

     //调用read方法来读入字节流到字节数组中,首先创建字节数组:
     Byte input = new Byte[20];
     fis.read(input);
          
     //由于所读取内容为文本,转化为字符串
     String inputString = new String(input); //后面可以指定编码方式

     System.out.println("inputString");
  }
}
//FileOutputStream 

import java.io.FileOutputstream; 
import java.io.IOException; 
import java.io.FileNotFoundException;

public class WriteByteStream{
   public static void main(String args[]){
     
      //指定写出的文件夹
      FileOutputStream fos = new FileOutputStream("text.txt");
    
      //调用write方法,首先要有待写入的数据
String outputString = "lalala啦啦啦123";

//可以直接从当前的字符串中获得字节数组
byte output[] = outputString.getBytes("UTF-8");//调用getbytes()方法
fos.write(output); } }

 

//字节流的拷贝

//打开要拷贝的文件
 FileInputStream fis = new  FileInputStream (“1.txt”);
 FileOutputStream fos = new  FileOutputStream ("copy1.txt");

//调用方法


//定义字节数组:为避免数组过小,造成拷贝不完全,需要循环读取
//read方法返回值为已从文件读取到的数据值;若返回-1,则说明已读到文件末尾

byte input[] = new Byte(50);

while(fis.read(input) != -1)
{
    fos.write(input);

}

//记得关闭
fis.close();
fos.close();

system.out.println("OK!");

 

 2.带有缓冲的字节流的读入,写出(文件容量大时高效)

//1.使用带缓冲区的字节流来进行读入,拷贝

FileInputStream fis = new  FileInputStream("Movio.mp4);//2.从这个文件中获得输入字节

//3.创建一个带缓冲的输入字节流,传入的参数为输入流,即当前的FileInputStream
BufferedInputStream bis = new BufferedInputStream(fis);//12.还可以传入参数:缓冲区大小

//8.进行文件的拷贝:
FileOutputStream fos = new FileOutputStream ("newMovio.mp4);
BufferedoutputStream bos = new BufferedOutputStream(fos);//9.带上缓冲区


//4.调用read方法,首先创建字符数组,文件里的数据就读入到这个数组
byte input[] = new byte(100);

int count = 0;//7.定义整型来统计读入了多少字节

while(bis.read(input) != -1){  5.//依旧使用循环,避免读取不完整
   bos.write(input);//10.写出字节流
     count++;
}

//6.关闭文件时:先打开的后关闭
bis.close();
fis.close();
bos.close();//11.关闭也一样
fos.close();


sysytem.out.println("共读取了:"+count +"次!");

2.1缓冲区做优化:///////////////////////////////////

二:字符流

1.使用字符流读写数据

 

六:争议

字节流在操作的时候本身是不会用到缓冲区(内存)的,是与文件本身直接操作的,而字符流在操作的时候是使用到缓冲区的

字节流在操作文件时,即使不关闭资源(close方法),文件也能输出,但是如果字符流不使用close方法的话,则不会输出任何内容,说明字符流用的是缓冲区,并且可以使用flush方法强制进行刷新缓冲区,这时才能在不close的情况下输出内容

 

以上是关于java: IO总结篇的主要内容,如果未能解决你的问题,请参考以下文章

Java 总结思考Java 答疑解惑之 IO 篇

java: IO总结篇

利用 Java io 包进行文件读写操作

java-----NIO总结

号称史上最全Java多线程与并发面试题总结—基础篇

Java基础知识回顾之七 ----- 总结篇