IO(Input Output)流
IO流用来处理设备之间的数据传输
Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中
流按操作数据分为两种:字节流与字符流
按流向分为:输入流和输出流
IO流常用基类
字节流的抽象基类:
InputStream,OutputStream
字符流的抽象基类:
Reader,Writer
注意:由这四个类派生出来的子类名称都是以其父类名的后缀
io流传输文件是靠流来完成
字符流
字符是用来传输文字类型的;
创建一个FileWriter对象。该对象一被初始化,就要明确要操作的文件。如果在该目录下已有该文件,原文件会被覆盖。
创建类的时候一般不要把异常抛出;要用try;catch
如果想给文件续写,可以在文件路径后面加true;
操作完后,要把流关闭,关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据,将数据刷到目标文件中,和flush()的区别是:flush()刷新后可以继续使用,close()刷新后,流就会被关闭。
复制文件demo
FileWriter fw=null;
FileReader fr=null;
try {
fw= new FileWriter("/Users/rimi/Documents/workspace/My/src/MySelf/SuperPerson.java");
fr=new FileReader("/Users/rimi/Documents/workspace/My/src/MySelf/S.java");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
char[]ch=new char[1024];
int num;
try {
while((num=fr.read(ch))!=-1){
System.out.println(new String(ch,0,num));
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
我们在关闭流的时候一定要在finally里面,在关闭的时候要加判断,判断我们的文件是否存在,如果前面代码抛出异常是不会运行后面的代码,所以在关闭的时候要加上if判断其是否为空,不为空则关闭。
缓冲区
缓冲区的出现提高了对数据的读写效率。
所以在创建缓冲区之前,必须要有流对象。
对应的类: BufferedReader 从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。 BufferedWriter 将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。 缓冲区要结合流才可以使用 在流的基础上对流的功能进行了增强。
为了提高字符写入流效率,加入了缓冲技术,只要讲需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可
缓冲区自己写的方法:
public class MyBufferedInputStream {
int num=0;
byte []by=new byte[1024];
int index=0;
private FileInputStream fis;
public MyBufferedInputStream(FileInputStream fis){
this.fis=fis;
}
public int myRead()throws IOException{
if(num==0){
num=fis.read(by);
if(num<0){
return -1;
}
index=0;
byte b=by[index];
num--;
index++;
return b&255;
}
else if(num>0){
byte b=by[index];
num--;
index++;
return b&255;
}
return -1;
}
}
装饰设计模式
当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能,那么自定义的该类就称之为装饰类。 装饰类通常会通过构造方法接收被装饰的对象。并基于被装饰的对象的功能,提供更强的功能。
demo:
public class Person { public void eat(){ System.out.println("吃饭!");
}
}
class SuperPerson{ private Person p;
SuperPerson(Person p)
{ this.p = p; }
public void superEat()
{ System.out.println("开胃酒");
p.eat();
System.out.println("小吃、甜点"); }
将需要被缓冲的对象。传递进来。也就是,谁需要被缓冲,谁就作为参数传递给缓冲区。 这样继承体系就变得很简单。优化了体系结构。
装饰模式比继承要灵活。避免了继承体系臃肿。 而且降低了类于类之间的关系。 装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。 所以装饰类和被装饰类通常是都属于一个体系中的。
LineNumberReader
跟踪行号的缓冲字符输入流
demo:
FileReader fr=null;
try {
fr= new FileReader("/Users/rimi/Documents/workspace/Hello Word/src/lv/Zb.java");
MyLineReaderDemo lnr=new MyLineReaderDemo(fr);
//lnr.setLineNumber(100);
String str;
while((str=lnr.MyLine())!=null){
System.out.println(str);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
字节流:
想要操作图片数据,我们就要用到字节流
输入流: FileOutputStream fos = new FileOutputStream("text.txt");
fos.write("dsadsa".getBytes());
fos.close();
输出流: // 一个一个的读 int ch = 0;
while((ch = fis.read()) != -1){
System.out.println((char)ch);
}
//装进数组读 byte[] bt = new byte[1024];
int ch = 0;
while((ch = fis.read(bt)) != -1){
System.out.println(new String(bt,0,ch));
}
字节流copy图片demo:
FileInputStream fis=null;
FileOutputStream fos=null;
BufferedOutputStream bop=null;
try {
fis=new FileInputStream("/Users/rimi/Documents/workspace/Io/004b4be3a1e1aa73c62d486e9b10e7a6.jpg");
fos=new FileOutputStream("/Users/rimi/Documents/workspace/Io/10.jpg");
BufferedInputStream bis=new BufferedInputStream(fis);
// MyBufferedInputStream mis=new MyBufferedInputStream(fis);//方法在其他类
bop=new BufferedOutputStream(fos);
try {
// int sum = fis.available();//获取字节的数量
// System.out.println(sum);
//byte[]by=new byte[1024];
int num;//读取的个数
while((num=bis.read())!=-1){
bop.write(num);
}
//System.out.println(new String(by,0));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
fis.close();
bop.close();
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long endTime=System.currentTimeMillis();
System.out.println((endTime-startTime));
}
字节流缓冲区:
关键字:BufferedInputStream; BufferedOutputStream;
自己写输入缓冲方法:
public class MyBufferedInputStream {
int num=0;
byte []by=new byte[1024];
int index=0;
private FileInputStream fis;
public MyBufferedInputStream(FileInputStream fis){
this.fis=fis;
}
public int myRead()throws IOException{
if(num==0){
num=fis.read(by);
if(num<0){
return -1;
}
index=0;
byte b=by[index];
num--;
index++;
return b&255;
}
else if(num>0){
byte b=by[index];
num--;
index++;
return b&255;
}
return -1;
}
读取键盘录入:
public class ReadIn {
public static void main(String[] args) throws IOException{
// TODO Auto-generated method stub
InputStream in = System.in;
int ch = in.read();
System.out.println(ch);
} }
输出转换流:
public static void main(String[] args) throws IOException{
// TODO Auto-generated method stub
OutputStream out = System.out;
OutputStreamWriter osw = new OutputStreamWriter(out);
BufferedWriter bw = new BufferedWriter(osw);
InputStream in = System.in; InputStreamReader isr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isr); String str = null;
while((str = br.readLine()) != null){
bw.write(str);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
File类:
File file = new File("/Users/chenbo/Documents/workspace/study2/src/com/rf/cdj/io");
File file3 = new File(file,"abc2.txt");
System.out.println(file3);
删除
boolean delete() 删除成功返回true 删除失败返回
false file1.delete();
void deleteOnExit() 在程序退出时删除指定对象
判断文件是否存在:
判断是否是一个目录
file.isDirectory
判断是否是一个文件
System.out.println(file.isFile());
通过exists()判断文件内容是否存在;
获取信息 file.getName();//获取名字
file.getPath();//获取路径
file.getParent();//获取父目录
file.getAbsolutePath();//获取绝对路径 返回是String
file.getAbsoluteFile();//获取绝对路径 返回的是File对象
获取指定目录下的所有目录
public static void main(String[] args) {
printDirsStruct("/Users/chenbo/Desktop/Study1",1);
}
public static void printDirsStruct(String pathName,int index) {
File f = new File(pathName);
// 1 判断是不是目录 if (f.isDirectory()) {
for (int i = 0; i < index; i++) {
System.out.print("-");
}
// 2 如果是目录,打印自己
System.out.println(f.getName());
// 3 如果该目录里面还有子目录,就要调用自己打印该子目录。
for (String str : f.list()) {
String newPath = pathName + "/" + str;
File f1 = new File(newPath);
if (f1.isDirectory()) {
printDirsStruct(newPath, index + 1);
} } } }