IO流
IO流用来处理设备之间的数据传输
java对数据的操作是通过流的方式
java对于操作流的对象都在IO包中
流按操作数据分为两种:字节流和字符流
流按流向分为:输入流和输出流。
IO流常用的基类
字节流的抽象基类:InputStream,OutputStream。
字符流的抽象基类:Reader,Writer。
字符写入流 FileWriter流的应用
import java.io.*;
public class FileWriterDemo {
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
//创建一个FileWriter对象,该对象一被初始化就必须明确被操作的文件。
// 而且该文件会被创建到指定目录下,如果存在同名文件会被覆盖。
// 作用就是创建流的输出的目的地。
FileWriter fw= new FileWriter("demo.txt");
//调用writer方法,将字符串写入到流中。
fw.write("aaaaaa");
//刷新流对象中的缓冲区将数据写入到目的文件中
fw.flush();
//关闭流资源,但是关闭之前会刷新一次内部的缓冲的数据。将数据写入之后再关闭流
//关闭之后流不能继续使用
fw.close();
}
}
字符读写流复制文件的实例
import java.io.*;
public class CopyText {
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
//copy_1();
copy_2();
}
//读入数组中在一起写入
public static void copy_2(){
FileWriter fw=null;
FileReader fr=null;
try{
fw = new FileWriter("D:\\FileWriterDemocopy.txt");
fr= new FileReader("FileWriterDemo.java");
char[] buf=new char[1024];
int len=0;
if((len=fr.read(buf))!=-1){
fw.write(buf, 0,len);
}
}catch(Exception e){
throw new RuntimeException("读写时出错了");
}finally{
try{
if(fr!=null)
fr.close();
if(fw!=null)
fw.close();
}catch(IOException e){
}
}
}
//读一个字符写一个字符
public static void copy_1() throws Exception{
//创建文件流的复制目的文件
FileWriter fw=new FileWriter("D:\\FileWriterDemo.txt");
//与已有的文件关联。
FileReader fr= new FileReader("FileWriterDemo.java");
int ch=0;
while((ch=fr.read())!=-1){
fw.write(ch);
}
fw.close();
fr.close();
}
}
字符缓冲区的类
作用:为了调高对数据读写的效率。
对应的类:BufferedReader BufferedWriter
要结合流才可以使用
在流的基础上对流的功能进行了增强。
自定义BufferderReader 实例
import java.io.*;
public class MyBufferedReaderDemo {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
FileWriter fw = new FileWriter("D:\\mybufferedReaderdemo.txt");
MyBufferedReader mybufr =new MyBufferedReader(new FileReader("FileWriterDemo.java"));
String line=null;
while ((line= mybufr.MyReadLine())!=null){
fw.write(line+"\r\n");
fw.flush();
}
fw.close();
mybufr.Myclose();
}
}
/*
需求:自定义一个BuferedReader类
实现它的ReadLine方法及关闭方法
*/
class MyBufferedReader{
private FileReader fr;
//定义一个初始化需要一个文件流的参数的构造方法
MyBufferedReader(FileReader fr){
this.fr = fr;
}
//定义MyReaderLine方法 基于一个StringBulider类用于保存读取的一行数据。
public String MyReadLine() throws IOException{
StringBuilder sb=new StringBuilder();
int ch=0;
while((ch=fr.read())!=-1){
if(ch=='\r') continue;
if(ch=='\n') return sb.toString();
else
sb.append((char)ch);
}
//避免最后一行没有换行符号的时候导致无法返回数据直接返回null结束 所以在结束之前进行一下判断
//如果存入数据了就返回。没有数据说明已经读到结尾就返回null
if(sb.length()!=0) return sb.toString();
return null;
}
public void Myclose() throws IOException{
fr.close();
}
}
自定义BufferedInputStream实例
import java.io.*;
public class BufferedStreamDemo {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
myCopyDemo();
//CopyDemo();
}
//创建以方法 用系统提供的BufferedInputStream和BufferedOutputStream进行复制文件;
public static void CopyDemo() throws IOException {
//定义一个字节文件读取缓冲流
BufferedInputStream bis= new BufferedInputStream(new FileInputStream("d:\\1.mp3"));
//定义一个字节文件写出缓冲
BufferedOutputStream bus= new BufferedOutputStream(new FileOutputStream("d:\\2.mp3"));
int b=0;
while ((b=bis.read())!=-1){
bus.write(b);
bus.flush();
}
bis.close();
bus.close();
}
public static void myCopyDemo() throws IOException {
//同我模拟的类创建一个字节文件读取缓冲流
MyBufferedInputStream bis= new MyBufferedInputStream(new FileInputStream("d:\\1.mp3"));
//定义一个字节文件写出缓冲
BufferedOutputStream bus= new BufferedOutputStream(new FileOutputStream("d:\\2.mp3"));
int b=0;
while ((b=bis.myRead())!=-1){
bus.write(b);
bus.flush();
}
bis.myClose();
bus.close();
}
}
/*明白了原理创建自己的MyBufferedInputStream类
1.自定义一个初始化需要传入字节流对象的类
2.定义一个字节缓冲数组
3.根据数据的进行数据的读取操作判断
4.定义自己的关闭方法Myclose
*/
class MyBufferedInputStream{
private InputStream in;
private byte[] buf = new byte[1024];
private int pos=0, count=0;
MyBufferedInputStream(InputStream in){
this.in = in;
}
public int myRead() throws IOException{
//通过in读取流里边的数据,储存在buf中。
if(count==0){
count = in.read(buf);
pos=0;
byte b= buf[pos];
if(count<0)
return -1;
count--;
pos++;
return b&255;//此处涉及字节和int类型转换关系问题
}else if(count>0){
byte b= buf[pos];
count--;
pos++;
return b&255;
}
return -1;
}
public void myClose() throws IOException{
in.close();
}
}
字节和字符装换流对象的应用实例
InputStreamReader:字节流到字符流的桥梁。
OutputStreamWriter:字符流到字节流的桥梁。
/*
需求 :利用转换流的从键盘中输入小写字符然后变为大写字母写入到控制台上
读取:
1.获取键盘输入流(字节流)
2.利用转换流对象 InputStreamReader 将字节流转换为字节流
3.增强读取效率 装饰缓冲流BufferedReader
写出:
1.获取键盘输出流(字节流)
2.利用转换流对象OutputStreamWriter 将字符装换为字节流输出到控制台
3.增强写出的效率 装饰缓冲流BufferedWriter
*/
import java.io.*;
public class TransStreamDemo {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//得到键盘输入流
InputStream in= System.in;
//转换为字符流
InputStreamReader isr = new InputStreamReader(in);
//装饰缓冲流
BufferedReader br= new BufferedReader(isr);
/*
//将上边三步写为一步
BufferedReader br=
new BufferedReader(new InputStreamReader(System.in));
*/
//得到输出流
OutputStream out = System.out;
//字符流转换为字节流
OutputStreamWriter osw= new OutputStreamWriter(out);
//装饰缓冲流
BufferedWriter bw= new BufferedWriter(osw);
/*//将上边三步并为一步
BufferedWriter bw=
new BufferedWriter(new OutputStreamWriter(System.out));
*/
String line =null;
while((line=br.readLine())!=null){
if(line.equals("over"))
break;
bw.write(line.toUpperCase());
bw.newLine();
bw.flush();
}
br.close();
bw.close();
}
}
流操作的基本规律
通过俩个明确来完成。
1. 明确源和目的。
源:输入流。InputStream Reader
目的:输出流。OutputStream Writer
2.操作的数据是否是纯文本。
是:字符流。
不是:字节流。
3. 当体系明确后,在明确要使用哪个具体的对象。
通过设备来进行区分:
源设备: 内存,硬盘,键盘。
目的设备:内存,硬盘,控制台。
文件复制实例
import java.io.*;
/*需求:将一个文本文件中数据存储到另一个文件中。复制文件。
*分析:
源:因为是源,所以使用读取流。InputStream Reader
是不是操作文本文件
是!选择字符流Reader
明确设备:硬盘的一个文件。
Reader 体系中可以操作文件的对象是 FileReader
FileReader fr = new FileReader("a.txt");
BufferedReader br= new BufferedReader(fr);
目的:OutputStream Writer
是否是纯文本。
是!Writer
设备:硬盘上的一个文件。
Writer 体系中的可以操作文件的对象FileWriter
FileWriter fw = new FileWriter("b.txt");
BufferedWriter bw= new BufferedWriter(fw);
*/
public class FileCopy {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//定义一个字符输入流读取要复制的文件
FileReader fr= new FileReader("D:\\a.txt");
//提高读取效率写入装饰流
BufferedReader br= new BufferedReader(fr);
//定义一个文件写出流
FileWriter fw= new FileWriter("D:\\b.txt");
//提高效率 写入装饰流
BufferedWriter bw=new BufferedWriter(fw);
String line=null;
while((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
}
}
键盘输入写入文件实例
import java.io.*;
/*需求:将一个键盘录入的信息写入到一个文件中。
*分析:
源:因为是源,所以使用读取流。InputStream Reader
是不是操作文本文件
是!选择字符流Reader
明确设备:硬盘录入。System.in
将字节流转换成字符流操作会很方便 所以用
Reader 体系中中字节流到字符流的桥梁 InputStreamReader对象
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br= new BufferedReader(isr);
目的:OutputStream Writer
是否是纯文本。
是!Writer
设备:硬盘上的一个文件。
Writer 体系中的可以操作文件的对象FileWriter
FileWriter fw = new FileWriter("c.txt");
BufferedWriter bw= new BufferedWriter(fw);
*扩展内容,想要把录入的数据按照指定的编码表,进行数据的储存。
*FileWriter 其实本身就是用的平台本身默认的字符编码(GBK);
*而转换流OutputStream这个对象本身就可以在进行流文件的传入时进行编码的指定
*所以在存储是需要要进行编码的修改时 只能用OutputStream对象进行操作
*/
public class WriterDemo {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//定义一个键盘输入流并转换为字符流
InputStreamReader isr= new InputStreamReader(System.in);
//提高读取效率写入装饰流
BufferedReader br= new BufferedReader(isr);
//定义一个文件写出流
FileWriter fw= new FileWriter("D:\\c.txt");
//提高效率 写入装饰流
BufferedWriter bw=new BufferedWriter(fw);
String line=null;
while((line=br.readLine())!=null){
if(line.equals("over"))
break;
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
}
}
输出流打印异常日志实例
import java.io.*;
import java.util.*;
import java.text.*;
public class ExceptionDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
//自定义异常然后打印
try{
int result = 1/0;
}catch(Exception e){
try{
Date date=new Date();
SimpleDateFormat dsf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String s=dsf.format(date);
PrintStream ps= new PrintStream("D:\\exception.txt");
ps.println(s);
e.printStackTrace(ps);
}catch(Exception ex){
throw new RuntimeException("日志文件创建失败");
}
}
}
}