IO流——字符流
IO(Input Output)流
IO流用来处理设备之间的数据传输。
java对数据的操作是通过流的方式。
java用于操作流的对象都在IO包中。
流按操作数据分为两种:字节流,字符流。
流按流向分为:输入流,输出流。
输入流和输出流是相对于设备而言的。
将外设中的数据读取到内存中:输入
将内存中的数据写入到外设中:输出
字符流的由来:
其实就是,字节流读取文字字节数据后,不直接操作而是先查指定的编码表。
获取对应的文字。在对这个文字进行操作。简单说:字节流+编码表
字节流的两个顶层父类:
1、InputStream 2、OutputStream
字符流的两个顶层父类:
1、Reader 2、Writer
就从熟悉的文字开始,字符流。
需求:将一些文字存储到硬盘的一个文件中。
记住:如果要操作文字数据,建议优先考虑字符流。
并且要将数据从内存写到硬盘上,要使用字符流中的输出流。Writer
硬盘的数据基本体现是文件。希望找到一个可以操作文件的Writer。
找到了FileWriter
1、FileWriter
代码:
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterDemo {
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
/*
* 写入
* 创建一个可以往文件中写入字符数据的字符输出流对象
* 既然是往一个文件中写入文字数据,那么在创建对象时,
* 就必须明确该文件(用于存储数据的目的地)。
*
* 如果文件不存在,则会自动创建。
* 如果文件操作,则会被覆盖。
*/
FileWriter fw=new FileWriter("demo.txt");
/*
* 调用Writer类中的write(String)方法,写入数据。
* 其实数据写入到了临时存储缓冲区中
*/
fw.write("abcd");
fw.write("0000");
//进行刷新,将数据直接写到目的地中。
// fw.flush();
//关闭流,关闭资源。在关闭前会先调用flush刷新缓冲区中的数据到目的地。
fw.close();
//换行
FileWriter fw1=new FileWriter("emo.txt");
fw1.write("abcd\nhahaha");//Windows系统不识别\n,所以在记事本里显示是没有换行的
fw1.close();
FileWriter fw2=new FileWriter("mo.txt");
fw2.write("abcd\r\nhahaha");//Windows系统识别\r\n,所以在记事本里显示是有换行的
fw2.close();
FileWriter fw3=new FileWriter("o.txt");
fw3.write("abcd"+LINE_SEPARATOR+"hahaha");//为了通用,直接调用系统自身的换行符
fw3.close();
/*
* 续写
* 如果构造函数中加入true,可以实现对文件进行续写,而不会直接覆盖已有文件。
* 如果原先没有此文件,就创建,那就不存在续写这一说了。
*/
FileWriter fw4=new FileWriter("s.txt",true);
fw4.write("abcd"+LINE_SEPARATOR+"hahaha");
fw4.close();
}
}
运行结果如下图:
demo~o都是自动创建写入数据的,s文件是我事先手动创建的,里面写有Helloworld!
这些文件都是在同一个目录下的。
2、FileReader
有两种读取方式,
一种是通过read()方法
另一种是通过read(char[] cbuf)方法
这两种方法都是其父类Reader的方法
首先我们通过一个需求演示第一种读取方式
需求:读取一个文本文件,将读取到的字符打印到控制台。
代码:
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo_1 {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
/*
* 创建读取字符数据的流对象。
* 在创建读取流对象时,必须要明确被读取的文件。一定要确定该文件是存在的。
* 这个过程也就是在用一个读取流关联一个已存在的文件。
*/
/*
FileReader fr=new FileReader("test1.txt");
//用Reader中的read方法读取字符,每读一次,读到一个字符。并返回该字符的编码值
int asc1=fr.read();
System.out.println(asc1+":"+(char)asc1);//97:a
int asc2=fr.read();
System.out.println(asc2+":"+(char)asc2);//98:b
int asc3=fr.read();
System.out.println(asc3);//-1 当数据全部读完了之后,再读会返回-1
*/
FileReader fr=new FileReader("test1.txt");
int asc=0;
while((asc=fr.read())!=-1){
System.out.println((char)asc);
}
}
}
运行的结果是:
a
b
因为代码中的test1.txt文件里面的内容就只是ab。
演示第二种读取方式
需求:读取一个文本文件,将读取到的字符打印到控制台。
代码:
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo_2 {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
/*
* 使用read(char[] ch)方法读取文本文件数据
*
* 先创建字符数组
*/
/* FileReader fr=new FileReader("test2.txt");
char[] ch=new char[3];
int num1=fr.read(ch);//将读取到的字符存储到数组中,并返回读取到了多少个字符
System.out.println(num1+":"+new String(ch));//3:abc
int num2=fr.read(ch);//将读取到的字符存储到数组中,并返回读取到了多少个字符
System.out.println(num2+":"+new String(ch));//3:def
int num3=fr.read(ch);//将读取到的字符存储到数组中,并返回读取到了多少个字符
System.out.println(num3+":"+new String(ch));//2:ghf
int num4=fr.read(ch);//当读取完数据后继续读取,会返回数字-1.表示已经读完了。
System.out.println(num4+":"+new String(ch));//-1:ghf
*/
FileReader fr=new FileReader("test2.txt");
char[] ch=new char[3];//数组在平常开发中的长度一般是1024或者其整数倍。
int num=0;
while((num=fr.read(ch))!=-1){
System.out.println(new String(ch,0,num));
}
}
}
运行输出如下
abc
def
gh