字符流
在程序中一个字符根据不同编码等于不同个字节,那么java提供了Reader、Writer两个专门操作字符流的类。
·字符输出流:Writer
·字符输入流:Reader
字符输出流:Writer
此类本身也是一个抽象类,如果要想使用此类,则肯定要使用其子类,此时如果是向文件中写入内容,所以应该使用FileWriter子类,这个类只能用来操作文本(不能写图片 音频 视频)。Writer类的常用方法:
方法或常量 描述
public abstract void close() throws IOException 关闭输出流
public void write(String str) throws IOException 将字符串输出
public void write(char[] cbuf) throws IOException 将字符数组输出
public abstract void flush() throws IOException 强制性清空缓存
示例代码:(字符流可以直接输出字符串,不需要转换为字节)
public class Demo04 {
public static void main(String[] args) throws IOException {
FileWriter fw=new FileWriter("/Users/lanou/Desktop/haha/h.txt");
fw.write(100);
//注意字符输出流 在写入文件的时候
//需要调用刷新方法
//建议:每次写入 最好都刷新一次
fw.flush();
//字符数组写入
char[] c= {'d','a','c','b'};
fw.write(c);
fw.flush();
fw.write(c, 1, 3);
fw.flush();
//使用字符串直接写入
fw.write("hello\n");
fw.flush();
//使用字符串偏移量写入
fw.write("hello", 1, 2);
fw.close();
}
}
此时如果是想追加内容,与FileInputStream的格式是一样的,添加appemd属性为true;
字符输入流:Reader
此类本身也是一个抽象类,如果要想使用此类,则肯定要使用其子类,此时如果是向文件中写入内容,所以应该使用FileReader子类.Writer类的常用方法:
方法或常量 描述
public abstract void close() throws IOException 关闭输出流
public int read() throws IOException 读取单个字符
public int read(char[] cbuf) throws IOException 将内容读到字符串数组中,返回读入的长度
示例代码:(以字符数组的形式读取出数据)
public class Demo05 {
public static void main(String[] args) throws IOException{
FileReader fr =new FileReader("/Users/lanou/Desktop/haha/h.txt");
//循环读取(两种)
int read=0;
while ((read=fr.read())!=-1) {
System.out.println((char)read);
}
char[] c =new char[1024];
while ((read = fr.read(c))!=-1) {
System.out.println(new String(c, 0, read));
}
fr.close();
}
}
利用字符流 复制文件(带异常处理):
public static void main(String[] args) {
//读
FileReader fd = null;
// 写
FileWriter fw = null;
try {
fd = new FileReader("/Users/lanou/Desktop/haha/www1.txt");
fw = new FileWriter("/Users/lanou/Desktop/haha/www.txt");
//一个一个读写
int len = 0;
while ((len = fd.read()) != -1) {
fw.write(len);
fw.flush();
}
} catch (FileNotFoundException e) {
// TODO: handle exception
throw new RuntimeException("文件没找到");
} catch (IOException e) {
// TODO Auto-generated catch block
throw new RuntimeException("文件复制失败 ");
} finally {
try {
if (fd != null) {
fd.close();
}
//两个流不能一起关,万一第一个抛出异常
//程序停止运行,第二个流会无法关闭的
} catch (IOException e) {
// TODO Auto-generated catch block
throw new RuntimeException("关闭资源失败");
}finally {
try {
if (fw != null) {
fw.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
字节-字符转换流
OutputStreamWriter和InputStreamReader
在整个IO包中,实际上就是字节流和字符流,但是除了这两个流之外,还存在一组字节流-字符流的转换类。
OutputStreamWriter:是Writer的子类,将输出的字符流转换为字节流。即:将一个字节流的输出对象变为字节流的输出对象
InputStreamReader:是Reader的子类,将输入的字节流变为字符流,即:将一个字节流的输入对象变为字符流的输入对象。
将字节的文件输出流,以字符的形式输出:
public class OutputStreamWriterDemo01
{
public static void main(String args[]) throws Exception{ //所有异常抛出
File file=new File("/Users/lanou/Desktop/haha/www1.txt");
Writer writer=null; //字符输出流
writer=new OutputStreamWriter(new FileOutputStream(file)); //字节流变为字符流
String str="hello world!!!!";
writer.write(str); //使用字符流输出
writer.close();
}
}
读的时候,也可以使用字符流的形式读取字节流的文件。
public class InputStreamReaderDemo01{
public static void main(String args[]) throws Exception{
File f = new File("/Users/lanou/Desktop/haha/www.txt") ;
Reader reader = null ;
reader = new InputStreamReader(new FileInputStream(f)) ; // 将字节流变为字符流
char c[] = new char[1024] ;
int len = reader.read(c) ; // 读取
reader.close() ; // 关闭
System.out.println(new String(c,0,len)) ;
}
};
对于FileWriter和FileReader的说明:
从JDK文档中可知FileOutputStream是OutputStream的直接子类,FileInputStream也是InputStream的直接子类,但是在字符流文件的两个操作类却有一些特殊,FileWriter并不是Writer的子类,而是OutputStream的子类,而FileReader也不是Reader的直接子类,是InputStreamReader的子类。