生活中,你肯定经历过这样的场景。当你编辑一个文本文件,忘记了ctrl+s
,可能文件就白白编辑了。当你电脑上插入一个U盘,可以把一个视频,拷贝到你的电脑硬盘里。那么数据都是在哪些设备上的呢?键盘、内存、硬盘、外接设备等等。
我们把这种数据的传输,可以看做是一种数据的流动,按照流动的方向,以内存为基准,分为输入input
和输出output
,即流向内存是输入流,流出内存的输出流。
Java中I/O操作主要是指使用java.io
包下的内容,进行输入、输出操作。输入也叫做读取数据,输出也叫做作写出数据。
根据数据的流向分为:输入流和输出流。
-
输入流 :把数据从
其他设备
上读取到内存
中的流。 -
输出流 :把数据从
内存
中写出到其他设备
上的流。
-
字节流 :以字节为单位,读写数据的流。
-
字符流 :以字符为单位,读写数据的流。
一切文件数据(文本、图片、视频等)在存储时,都是以二进制数字的形式保存,都一个一个的字节,那么传输时一样如此。所以,字节流可以传输任意文件数据。在操作流的时候,我们要时刻明确,无论使用什么样的流对象,底层传输的始终为二进制数据
java.io.OutputStream
抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地。它定义了字节输出流的基本共性功能方法。
-
public void close()
:关闭此输出流并释放与此流相关联的任何系统资源。 -
public void flush()
:刷新此输出流并强制任何缓冲的输出字节被写出。 -
public void write(byte[] b)
:将 b.length字节从指定的字节数组写入此输出流。 -
public void write(byte[] b, int off, int len)
:从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。 -
public abstract void write(int b)
:将指定的字节输出流。
-
public void close()
:关闭此输入流并释放与此流相关联的任何系统资源。 -
public abstract int read()
: 从输入流读取数据的下一个字节。 -
public int read(byte[] b)
: 从输入流中读取一些字节数,并将它们存储到字节数组 b中 。
小贴士:
close方法,当完成流的操作时,必须调用此方法,释放系统资源。
/** * 字节流图片读写 */ public static void test02(){ FileInputStream fis =null; FileOutputStream fos =null; try { fis=new FileInputStream("F:/boss/1.png"); // 1.2 指定目的地 File file=new File("F:/boss/2.png"); fos=new FileOutputStream(file); byte[] b=new byte[1024]; int len; while((len=fis.read(b))!=-1){ fos.write(b,0,len); } } catch (Exception e) { e.printStackTrace(); } finally { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 字节流文件读写 */ public static void test01(){ try { File file=new File("F:/boss/a.txt"); //可以传入file,也可以传入字符串 FileInputStream fis= new FileInputStream(file); FileOutputStream fos=new FileOutputStream("F:/boss/b.txt"); int len; byte [] b=new byte[1024]; //循环读取 while((len=fis.read(b))!=-1){ fos.write(b,0,len); } } catch (IOException e) { e.printStackTrace(); } finally { } }
当使用字节流读取文本文件时,可能会有一个小问题。就是遇到中文字符时,可能不会显示完整的字符,那是因为一个中文字符可能占用多个字节存储。所以Java提供一些字符流类,以字符为单位读写数据,专门用于处理文本文件。
-
字符编码:字节与字符的对应规则。Windows系统的中文编码默认是GBK编码表。
idea中UTF-8
-
字节缓冲区:一个字节数组,用来临时存储字节数据。
java.io.Reader
抽象类是表示用于读取字符流的所有类的超类,可以读取字符信息到内存中。它定义了字符输入流的基本共性功能方法。
-
public void close()
:关闭此流并释放与此流相关联的任何系统资源。 -
public int read()
: 从输入流读取一个字符。 -
public int read(char[] cbuf)
: 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中 。
-
FileReader(File file)
: 创建一个新的 FileReader ,给定要读取的File对象。 -
FileReader(String fileName)
: 创建一个新的 FileReader ,给定要读取的文件的名称。
java.io.Writer
抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地。它定义了字节输出流的基本共性功能方法。
-
void write(int c)
写入单个字符。 -
void write(char[] cbuf)
写入字符数组。 -
abstract void write(char[] cbuf, int off, int len)
写入字符数组的某一部分,off数组的开始索引,len写的字符个数。 -
void write(String str)
写入字符串。 -
void write(String str, int off, int len)
写入字符串的某一部分,off字符串的开始索引,len写的字符个数。 -
void flush()
刷新该流的缓冲。 -
void close()
关闭此流,但要先刷新它。
public static void test03(){ //使用文件名称创建流对象 FileReader fileReader=null; FileWriter fw=null; try { int len; char[] b=new char[1024]; fileReader=new FileReader("F:/boss/a.txt"); fw= new FileWriter("F:/boss/c.txt"); while((len=fileReader.read(b))!=-1){ System.out.println(new String(b,0,len)); fw.write(b,0,len); } } catch (Exception e) { e.printStackTrace(); } finally { try { fw.close(); fileReader.close(); } catch (IOException e) { e.printStackTrace(); } } }
缓冲流,也叫高效流,是对4个基本的FileXxx
流的增强,所以也是4个流,按照数据类型分类:
-
字节缓冲流:
BufferedInputStream
,BufferedOutputStream
-
字符缓冲流:
BufferedReader
,
构造方法
-
public BufferedInputStream(InputStream in)
:创建一个 新的缓冲输入流。 -
public BufferedOutputStream(OutputStream out)
: 创建一个新的缓冲输出流。
构造方法
-
public BufferedReader(Reader in)
:创建一个 新的缓冲输入流。 -
public BufferedWriter(Writer out)
: 创建一个新的缓冲输出流。
1 /** 2 * 字节流文件读写 3 */ 4 public static void test01() { 5 BufferedInputStream bis = null; 6 BufferedOutputStream bos = null; 7 try { 8 File file = new File("F:/boss/a.txt"); 9 //可以传入file,也可以传入字符串 10 FileInputStream fis = new FileInputStream(file); 11 FileOutputStream fos = new FileOutputStream("F:/boss/b.txt"); 12 bis = new BufferedInputStream(fis); 13 bos = new BufferedOutputStream(fos); 14 int len; 15 byte [] b=new byte[1024*8]; 16 //循环读取 17 while((len=fis.read(b))!=-1){ 18 fos.write(b,0,len); 19 } 20 } catch (IOException e) { 21 e.printStackTrace(); 22 } finally { 23 } 24 }
1 public static void test03() { 2 //使用文件名称创建流对象 3 FileReader fileReader = null; 4 FileWriter fw = null; 5 BufferedWriter bw = null; 6 BufferedReader br = null; 7 try { 8 int len; 9 char[] b = new char[1024*8]; 10 fileReader = new FileReader("F:/boss/a.txt"); 11 fw = new FileWriter("F:/boss/c.txt"); 12 bw = new BufferedWriter(fw); 13 br = new BufferedReader(fileReader); 14 //==方式一 15 while ((len = br.read(b)) != -1) { 16 bw.write(b, 0, len); 17 } 18 //方式二:读取一行 19 String line = null; 20 while ((line = br.readLine()) != null) { 21 bw.write(b, 0, len); 22 } 23 } catch (Exception e) { 24 e.printStackTrace(); 25 } finally { 26 try { 27 bw.close(); 28 br.close(); 29 fw.close(); 30 fileReader.close(); 31 } catch (IOException e) { 32 e.printStackTrace(); 33 } 34 } 35 }
aaaa