黑马程序员-IO

来源:互联网 发布:皇室战争火球升级数据 编辑:程序博客网 时间:2024/06/05 04:21
IO流用来处理设备之间的数据传输。
按数据分为两种:字节流和字符路。
流向分为:输入流。输出流。
字节流的抽象基类:InputStream,OutputStream。
字符流的抽象基类:Reader,Writer。
FileWriter:创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件。而且该文件会被创建到知道目录下,如果该目录下已有同名文件。将被覆盖。该步是明确数据要存放的目的地。
FileWriter fw = new FileWriter("d.txt");
fw.write("abc"); 字符串写入到流中。
fw.flush();刷新流对象中的缓冲数据,将数据刷到目的地中。
fw.close();关闭流资源。关闭之前会刷新一次缓冲数据。
IOException处理方式:
public static void main(String[] args){FileWriter fw = null;try{    fw = new FileWriter();   fw.write("abc");}catch(IOException e){System.out.print(e.toSring());}finally{try{if(!fw==null)fw.close();}catch(IOException e){System.out.print(e.toSring());}}}

FileReader
创建读取流对象,和指定名称文件相关联。如果文件不存在,抛出FileNotFoundException.
其中colse方法不会刷新缓冲区;

对应缓冲类
BufferedWriter 特有方法newLine();
BufferedReader 特有方法readerLine();
import java.io.*;class byteDemo {public static void main(String[] args) {FileInputStream is=null ;FileOutputStream os=null;try{is= new FileInputStream("tupian.gif");os= new FileOutputStream("tupian_copy.gif");byte[] buf= new byte[1024];int len=0;while((len=is.read(buf))!=-1){os.write(buf,0,len);}}catch (IOException e){throw new RuntimeException("error");}finally{try{if(is!=null)is.close();}catch (IOException e){System.out.print("失败");}try{if(os!=null)os.close();}catch (IOException e){System.out.print("失败");}}}}


MyBufferedReader
import java.io.*;class myBuffer{public static void main(String[] args)throws IOException{Buffered br = new Buffered(new FileReader("byteDemo.java")); BufferedWriter bt = new BufferedWriter(new FileWriter("byteDemo_copy.txt"));String line = null;br.setNumber(100);while((line=br.myReadLine())!=null){bt.write(line);bt.newLine();bt.flush();}bt.close();br.myClose();}}class Buffered{private FileReader r;private int lineNumber;Buffered(FileReader r){this.r=r;}public String myReadLine()throws IOException{lineNumber++;StringBuilder sb = new StringBuilder();int num=0;while((num=r.read())!=-1){if(num=='\r')continue;if(num=='\n')return new String(lineNumber+":"+sb.toString());//elsesb.append((char)num);}if(sb.length()!=0)return new String(lineNumber+":"+sb.toString());return null;}public void myClose()throws IOException{r.close();}public void setNumber(int n){lineNumber=n;}public int getNumber(){return lineNumber;}}

字节流
FileOutputStream
FileInputStream

转换流对象:
InputStreamReader
OutputStreamWriter

流对象的操作规律:
1,明确源和目的。
2,操作的数据是否为纯文本。
3,当体系明确后,在明确使用哪个具体的对象。通过设备来区分,源设备:内存,硬盘,键盘。目的设备:内存,硬盘,控制台。


资源分割。读取流读到资源。分别输出到若干个文件中。
资源拼接。
SequenceInputStream(Enumeration<? extends InputStream> e)
SequenceInputStream(InputStream s1, InputStream s2)
首先将需要拼接的输入流对象存到集合当中,然后为了得到Enumeration对象。建立匿名对象覆盖其中的方法使其与集合相关联。
import java.io.*;import java.util.*;class SplitFile {public static void main(String[] args) throws IOException{//split();sequence();}//切割文件public static void split() throws IOException{FileInputStream fis = new FileInputStream("D:\\java\\test\\day07\\冰河世纪1.RMVB");FileOutputStream fos = new FileOutputStream("D:\\java\\test\\day07\\1.part");//定义缓冲区byte[] buf = new byte[1024*1024*10];int len = 0;int num = 1;long n =0;while((len=fis.read(buf))!=-1){n++;fos.write(buf,0,len);if(n%10==0){fos.close();fos = new FileOutputStream("D:\\java\\test\\day07\\"+(++num)+".part");}}fis.close();fos.close();     } //拼接文件public static void sequence()throws IOException{//SequenceInputStream sis = new SequenceInputStream();ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();for(int x=1;x<6;x++){al.add(new FileInputStream("D:\\java\\test\\day07\\"+x+".part"));}final Iterator<FileInputStream> it = al.iterator();Enumeration<FileInputStream> en = new Enumeration<FileInputStream>(){public  boolean hasMoreElements(){return it.hasNext();}public  FileInputStream nextElement(){return it.next();}};SequenceInputStream sis = new SequenceInputStream(en);FileOutputStream fos = new FileOutputStream("D:\\java\\test\\day07\\copy.rmvb");byte[] buf = new byte[1024*1024*10];int len = 0;while((len=sis.read(buf))!=-1){fos.write(buf,0,len);}sis.close();fos.close();}}

File:
将已有或者不存在的文件或者文件夹封装成文件对象。
File file=new File(pathname);
File file=new FIle(path,name);
常见方法:
1,创建:createNewFile();如果文件已经存在,则不创建返回false和输出流不同。
2,删除:delete();   deleteOnExit();退出时删除。
3,判断:canExecute() 是否是可执行文件。canRead(),canWrite(); exists()是否存在。mkdir()创建文件夹,创建一级目录。
mkdirs()创建多级目录。isFile(),isDirectory()。 isHidden()是否是隐藏的。isAbsolute()是否是绝对路径。
4,获取信息:getName();getPath(); getParent();返回的是绝对路径中的父目录。如果获取的是相对路径那么返回的是null。(getAbsolutePath();getAbsoluteFile();返回值不同可相互转换) lastModified();最后修改时间。length();
renameTo(),将一个文件改名,并按照路径放置文件。
目录里文件的递归例子
import java.io.*;class FileDemo {public static void main(String[] args) {File dir=new File("d:\\java");showDir(dir,0);}public static String getLevel(int level){StringBuilder sb = new StringBuilder();for(int x=0;x<level;x++){sb.append(" ");}return sb.toString();}public static void showDir(File dir,int level){System.out.println(getLevel(level)+dir.getName());level++File[] files = dir.listFiles();for(int x=0;x<files.length;x++){if(files[x].isDirectory())showDir(files[x]);elseSystem.out.println(files[x]);}}}
删除目录原理:在windows中,删除目录从里面往外面删除。所以使用递归。
import java.io.*;class  RemoveDir{public static void main(String[] args) {File dir=new File("d:\\testdir");removeDir(dir);}public static void removeDir(File dir){File[] files=dir.listFiles();for(int x=0;x<files.length;x++){if(files[x].isDirectory())removeDir(files[x]);System.out.println(files[x].toString()+"file"+files[x].delete());}System.out.println(dir+":dir:"+dir.delete());}}

listRoots()列出根盘符。
list()列出目录中的文件名。封装的对象必须是目录。该目录还必须存在。可以加入文件名过滤器。
FilenameFileter(){
public boolean accept(FIle dir,String name){
return name.endsWith(" ");
}
}

Properties对象:是hashtable的子类。也就是说它具备map集合的特点。而且他里面储存的键值都是字符串。
此对象可以直接和流向关联。
pro.load(is);
是集合中和IO技术想结合的集合容器;
该对象的特点:可以用于键值对形式的配置文件。固定格式键=值。
import java.io.*;import java.util.*;class zhuCeDemo //注册表练习{public static void main(String[] args)throws IOException {File file = new File("peizhi.ini");if(!file.exists())file.createNewFile();Properties  pro= new Properties();BufferedReader br = new BufferedReader(new FileReader(file));//读取文件pro.load(br);String value = pro.getProperty("time");int num=0;if(value!=null)num=Integer.parseInt(value);num++;if(num>=6){System.out.print("error");return;}pro.setProperty("time",num+"");FileOutputStream fos = new FileOutputStream(file);pro.store(fos,"");//将Properties里的数据通过流写到文件中br.close();fos.close();}}

对象的序列化:
ObjectInputStream和ObjectOutputStream
被操作的对象要实现Serializable(标记接口:无方法。);
可直接操作基本数据类型。将对象写到一个文件里去。将对象实例化存储。

管道流:
将输入输出管道流封装成2个对象。并且实现Runnable接口。
import java.io.*;class Read implements Runnable {private PipedInputStream in;Read(PipedInputStream in){this.in=in;}public void run(){try{byte[] buf = new byte[1024];int len=in.read(buf);String=new String(buf,0,len);System.out.println(s);}catch (IOException e){throw new RuntimeException("管道读取流失败"); }}}class Write implements Runnable{private PipedOutputStream out;Write(PipedOutputStream out){this.out=out;}public void run(){try{out.write("guandao".getBytes());out.close();}catch (IOException e){throw new RuntimeException("管道输出流失败"); }}}class PipedStreamDemo{public static void main(String[] args)throws IOException{PipedInputStream in = new PipedInputStream();PipedOutputStream out = new PipedOutputStream();in.connect(out);new Thread(new Read(in)).start();new Thread(new Write(out)).start();}}
RandomAccessFile:随机访问文件
不是IO体系中的子类,而是直接继承自Object,但是他是IO包中的成员,因为他具备读写功能,内部封装了一个数组,而且通过指针对数组的元素进行操作,可以通过getFilePointer获取指针的位置,同时可以通过seek改变指针的位置。
其实读写原理就是内部封装了字节输入和输出流。
通过构造函数可以看出该类只能操作文件。并且可以选择模式。
模式有4种:r只读方式打开,rw打开以便读写 rws对文件内容和元数据每个同步更新的都同步写入到底层设备。rwd只同步内容
如果模式为r,文件没有,不会创建文件。抛出异常。
如果模式为rw,文件不存在,创建文件,如果存在不会覆盖。
名字过长统一用多字节形式存储
import java.io.*;class RandomAccessFileDemo {public static void main(String[] args)thorws IOException{readFile();//writeFile();}public static void writeFile()thorws IOException{RandomAccessFile raf=new RandomAccessFile("ran.txt","rw");raf.write("java".getBytes());raf.writeInt(97);//raf。writeInt(97);默认写出最低8位一个字节raf.write("java1".getBytes());raf.writeInt(99);raf.close();}public static void readFile()thorws IOException{RandomAccessFile raf=new RandomAccessFile("ran.txt","rw");raf.seek(8*1);//调整对象指针raf.write("java3".getBytes());//可在指定位置继续写入数据覆盖原数据raf.skipBytes(8);//跳过指定的字节,不能往回跳byte[] buf=new byte[4];raf.read(buf);String s=new String(buf);int age=raf.readInt();System.out.print(name+":"+age);raf.close();}}

操作基本数据的流对象:
DataOutputStream与DataInputStream
import java.io.*;class DateStreamDemo {public static void main(String[] args)throws IOException{writeData();readData();}public static void readData()throws IOException{DataInputStream dis=new DataInputStream(new FileInputStream("data.txt"));//注意:读取一定要数据类型按存储顺序读,否则数据错乱。int num=dis.readBoolean();boolean b=dis.readBoolean();double d=dis.readDouble();dis.close();}public void static void write()throws IOException{DataOutputStream dos=new DataOutputStream(new FileOutputStream("data.txt"));dos.writeInt(230);dos.writeBoolean(true);dos.writeDouble(99.323);dos.close();}public static void writeUTFDemo()throws IOException{DataOutputStream dos=new DataOutputStream(new FileOutputStream("UTF.txt"));//通过UTF-8的编码形式写出数据。2格子8字节。只能用readUTF()读取dos.writeUTF("你好");dos.close();}}
操作字节数组:
ByteArrayInputStream与ByteArrayOutputStream
ByteArrayInputStream:在构造的时候,需要接收数据源,而且数据源是一个字节数组。
ByteArrayOutputStream:在构造的时候,不用定义数据目的,因为对象中已经封装了可变长度的字节数组,这就是数据目的
因为这两个流对象都操作的是数组,并没有使用系统底层资源。所谓不需要使用close关闭
import java.io.*;class  ByteArrayStream{public static void main(String[] args) {//数据源ByteArrayInputStream bis =new ByteArrayInputStream("abcd".getBytes());//数据目的ByteArrayOutputStream bos=new ByteArrayInputStream();int by=0;while((by=bis.read())!-1){bos.write(by);}System.out.print(bos.size()+":"bos.toString);}}
操作字符数组:
CharArrayReader与CharArrayWriter
操作字符串:
StringReader与StringWriter


原创粉丝点击