1.IO流概念
IO流用来处理设备之间的数据传输,这个动作比较常见,硬盘与内存等设备之间文件的处理。
Java对数据的操作是通过流的方式,Java用于操作流的对象都在IO包中流按操作数据分为两种:字节流与字符流。 (以前只有字节流,为了方便处理文书数据,单独分离出的字符流)
流按流向分为:输入流,输出流。
2.字符流
抽象基类:Reader , Writer。
字符流数据的最常见格式是:文件
输入输出字符流结构示意图
2.1专门操作文件的Writer子类对象FileWriter
创建FileWriter:FileWriter fw= new FileWriter(“demo.txt”)
该文件会被创建指定目录下。如果该目录下存在同名文件会将其覆盖.
fw.write("字符串")//写入字符串数据,到流中。
flush()//刷新流中的数据,将数据刷入目的地中。
代码体现:
import java.io.*;
class FileWriterDemo
{
public static void main(String[] args) throws IOException
{
//创建一个FileWriter对象。该对象一被初始化就必须要明确被操作的文件。
//而且该文件会被创建到指定目录下。如果该目录下已有同名文件,将被覆盖。
//其实该步就是在明确数据要存放的目的地。
FileWriter fw = new FileWriter("demo.txt");
//调用write方法,将字符串写入到流中。
fw.write("abcde");
//刷新流对象中的缓冲中的数据。
//将数据刷到目的地中。
//fw.flush();
//关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据。
//将数据刷到目的地中。
//和flush区别:flush刷新后,流可以继续使用,close刷新后,会将流关闭。
fw.close();
}
}
对文件进行续写FileWriter fw=new FileWriter(demo.txt,true);后面的参数为true的时候,这样就不会覆盖了!2.2 FileReader
- 建立一个流对象,将已有的一个文件加载进流。
- FileReader fr=new FileReader(“Text.txt”);
- 创建一个临时存储数据的数组。
- char[] ch =new char[1024]';
- 调用流对象的读取方法将流中的数据读入到数组中。
- fr.read(ch);
完整代码
FileReader fr = null;
try{
fr = new FileReader("c:\\test.txt");
char[] buf = new char[1024];
int len= 0;
while((len=fr.read(buf))!=-1){
System.out.println(new String(buf,0,len));
}
}
catch (IOException e){
System.out.println("read-Exception :"+e.toString());
}
finally{
if(fr!=null){
try{
fr.close();
}
catch (IOException e){
System.out.println("close-Exception :"+e.toString());
}
}
}
注意事项:定义文件路径时,可以用“/”或者“\\”。在创建一个文件时,如果目录下有同名文件将被覆盖。
在读取文件时,必须保证该文件已存在,否则出异常。
2.3 复制操作
通过写入和写出,完成复制操作代码如下
//将C盘一个文本文件复制到D盘。
/*
复制的原理:
其实就是将C盘下的文件数据存储到D盘的一个文件中。
步骤:
1,在D盘创建一个文件。用于存储C盘文件中的数据。
2,定义读取流和C盘文件关联。
3,通过不断的读写完成数据存储。
4,关闭资源。
*/
import java.io.*;
class CopyText
{
public static void main(String[] args) throws IOException
{
copy_2();
}
public static void copy_2()
{
FileWriter fw = null;
FileReader fr = null;
try
{
fw = new FileWriter("SystemDemo_copy.txt");
fr = new FileReader("SystemDemo.java");
char[] buf = new char[1024];
int len = 0;
while((len=fr.read(buf))!=-1)
{
fw.write(buf,0,len);
}
}
catch (IOException e)
{
throw new RuntimeException("读写失败");
}
finally
{
if(fr!=null)
try
{
fr.close();
}
catch (IOException e)
{
}
if(fw!=null)
try
{
fw.close();
}
catch (IOException e)
{
}
}
}
//从C盘读一个字符,就往D盘写一个字符。
public static void copy_1()throws IOException
{
//创建目的地。
FileWriter fw = new FileWriter("RuntimeDemo_copy.txt");
//与已有文件关联。
FileReader fr = new FileReader("RuntimeDemo.java");
int ch = 0;
while((ch=fr.read())!=-1)
{
fw.write(ch);
}
fw.close();
fr.close();
}
}
2.4 字符流缓冲区
缓冲区的出现提高了对数据的读写效率。通过毕老师的图理解缓冲区提高效率的原理!
对应类
BufferedWriter
BufferedReader
缓冲区要结合流才可以使用。
在流的基础上对流的功能进行了增强
对应类
BufferedWriter
BufferedReader
缓冲区要结合流才可以使用。
在流的基础上对流的功能进行了增强
字符读取流缓冲区: 该缓冲区提供了一个一次读一行的方法 readLine,方便于对文本数据的获取。 当返回null时,表示读到文件末尾。 readLine方法返回的时候只返回回车符之前的数据内容。并不返回回车符。
import java.io.*;
class BufferedReaderDemo
{
public static void main(String[] args) throws IOException
{
//创建一个读取流对象和文件相关联。
FileReader fr = new FileReader("buf.txt");
//为了提高效率。加入缓冲技术。将字符读取流对象作为参数传递给缓冲对象的构造函数。
BufferedReader bufr = new BufferedReader(fr);
String line = null;
while((line=bufr.readLine())!=null)
{
System.out.print(line);
}
bufr.close();
}
}
readLine方法原理:无论是读一行,还是获取多个字符,其实都是在硬盘上一个一个读取,所有他的实质还是read方法,一次读一个。而他把回车符前面的临时数据存储起来,读到回车符的时候刷新,读取。
3.字节流
字节流的抽象基类:
InputStream ,OutputStream。
基本操作与字符流类相同
但它不仅可以操作字符,还可以操作其他媒体文件
输入输出字节流结构示意图
3.1 FileOutputStream与FileInputStream
他们的功能基本和字符流的一直,主要是操作媒体数据字节流。
3.2 字节流的缓冲区
同样是提高了字节流的读写效率。
3.3原理图

4. 转换流
InputStreamReader,OutputStreamWriter
- 转换流的由来
字符流: FileReader FileWriter。 BufferedReader BufferedWriter 字节流: FileInputStream FileOutputStream BufferedInputStream BufferedOutputStream 通过刚才的键盘录入一行数据并打印其大写,发现其实就是读一行数据的原理。 也就是readLine方法。 转换流的由来和作用: readLine方法是字符流BufferedReader类中的方法。 而键盘录入的read方法是字节流InputStream的方法。 那么能不能将字节流转成字符流在使用字符流缓冲去的readLine方法呢?
他们的优点
- 字符流与字节流之间的桥梁
- 方便了字符流与字节流之间的操作
- 转换流的应用
- 字节流中的数据都是字符时,转成字符流操作更高效。
转换流代码应用
import java.io.*;
class TransStreamDemo
{
public static void main(String[] args) throws IOException
{
//获取键盘录入对象。
//InputStream in = System.in;
//将字节流对象转成字符流对象,使用转换流。InputStreamReader
//InputStreamReader isr = new InputStreamReader(in);
//为了提高效率,将字符串进行缓冲区技术高效操作。使用BufferedReader
//BufferedReader bufr = new BufferedReader(isr);
//键盘的最常见写法。
BufferedReader bufr =
new BufferedReader(new InputStreamReader(System.in));
// OutputStream out = System.out;
// OutputStreamWriter osw = new OutputStreamWriter(out);
// BufferedWriter bufw = new BufferedWriter(osw);
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
String line = null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufr.close();
}
}
总结:字节流字符流大致的使用都是一致的,只是操作的对象不同。所以掌握其中一个就可以举一反三,里面的方法也类似的,进行对比记忆较好掌握!复制操作很重要,还有缓冲区的概念和作用!