黑马程序员——IO

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


    IO就是输入/输出流的简称。这里,我们需要知道的是输出/入的方向问题,从程序所在的内存的角度来判断是输出还是输入流的。我们根据实际情况来对流进行分类,输出流:outputstream,writer。输入流inputstream,reader。有字节流:Inputstream,Outputstream。字符流:Reader,Writer。这四个派生出的子类名称都是以其分类名作为子类名的后缀。

   常见的File类,创建了File类后就可以使用file的一些方法。Filewriter:后缀名是父类命名,前缀名时该流对象的功能。创建该子类时,必须要有文件。没有会创建指定目i录下,已有的话在创建后会覆盖原来的文件。本质是创建文件存放数据。

        FileWriter f=new FileWriter(“ss.txt");   

         boolean createNewFile()创建新文件,有就不创建返回false。与输出流不同,输出流会覆盖原来的文件。

    使用一些方法后,我们需要flush,close将数据存放到目的地中。File类中有很多的方法,包括了获取文件名,文件检测,获取常规文件信息,文件相关操作,目录操作相关的方法。      

f.getName();
f.getAbsoluteFile().getParent();
String[] fileList=f.list();
for(String fileName: fileList)
{}
File[] roots=File.listRoots();
for(File root : roots)
{}
    文件名的过滤里,需要知道list()里可以接受FilnameFilter参数,通过这个参数筛选出符合条件的文件。该接口里有一个accept(File dir,String name )方法,该方法返回true,那么list()就列出符合条件的该子目录或者文件。 

String[] fileList=f.list(new filter());
class filter implements FilenameFilter
{
  
     public  boolean accept(File dir,String name)
   {
      return name.endWith(".java")||new File(name).isDirectory();    //boolean isDirectory();判断File对象所对应的是否是目录
   }
   
}
    字节流/字符流:Inputstream与reader是所有输入流的抽象基类,他们包含了如下三个方法:read(),read(byte[]/char[]  b),read(char[]/byte[] ,from ,to)。read()方法返回的是实际读取的字节/字符数。下面我们以代码来说明:
 FileInputStream f=new FileInputStream()  
 byte[] b=new byte[1024];                 //字节数组来读取该文件,read方法只能一个字节来读取,设置该数组是为了高效来读取,存储。
  int  hasone=0;
while((hasone=f.read(b))>0)              //这个涉及到read方法读到什么时候结束,直到读到-1时,方法结束
 System.out.print(new String(b,0,hasone));
}  
f.close();                      //一定不要忘了关闭IO流,这个指的是程序里所有的输入,输出的流
      OutputStream与Writer里的方法与前面很相似的,只不过在创建文件的时候,我们可以在文件名后面跟boolean型数值来判断是否覆盖从头开始写进行重写,如果为true那么就从末尾开始写。

       我们再以代码块来说明:

while((hasone=f.read(b))>0)      
{
 f.write(b,0,hasone);                  //因为字符流直接以字符为操作单位,所以Writer可以用字符串来代替字符数组。
}  
      我们需要知道io中的异常处理,我们在建立,处理,关闭io流的过程中都是可能会出现问题的,我们在每一个部都是需要进行处理的,关闭资源的操作一定要放在final里,在建立file的引用的 时候,放在外面,初始化放在try内。关闭资源的那步仍旧需要进行异常处理的。关闭之前需要判断文件是否为空。    kk

      为了提高流的效率,Buffered-- 缓冲技术,提高对数据的读写效率。字符流的缓冲区要结合字符流才可以使用,

BufferedWriter b=new BufferedWriter(f);
       缓冲区里还有一个写入分行符的方法newLine(),这个方法是跨平台的分行。BufferedReader里还有一个读一行的方法:readLine(),由于该方法返回的时候只返回回车符之前的数据内容,不返回回车符。所以我们可以在下面使用newLine()方法。  
  String line=null;
  while(l(ine=f.readLine())!=null)
{
        f.write(line);
        f.newLine();
        f.flush();
}
     装饰设计模式:当需要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能并提供增强功能。该自定义类称为装饰类。装饰比继承灵活,避免了臃肿,减低了类与类之间的关系。装饰类与被装饰类同属于一个体系中的。

     LineNumerReader带行号的输入流。getlinenumer,setlinenumer。调用时可以获取行号,设置行号。同样是装饰设计类进行增强。

     将字节流转化为字符流,使用转换流:InputStreamReader,转化为BufferedReader,可以使用readLine方法,进行高效操作。同样的也有字符同向字节,OutputStreamWriter方法。

InputStream f=System.in;
InputStreamReader i=new InputStreamReader(f);
      键盘常见写法:
BufferedReader bufr=new BufferedReader(new InputStream(System.in));
      我们如果需要将文件录入的话,就将键盘录入的改为文件即可。

     我们在使用流的时候需要明确两个条件即可:

     1.明确源和目的。

         源:Inputstream  Reader

        目的:Outputstream   Writer

      2.操作数据是否为纯文本

           是,字符流;

           否,字节流。
      3.确定设备,源设备  键盘是System.in。硬盘则是filestrram。内存是ArrayStream。
                          目的设备  控制台System.out。硬盘则是filestrram。 内存是ArrayStream。

   函数本身的调用自己称之为递归。要注意的地方是限定条件,避免内存溢出。

  public static void show(File dir)
  {
   File[] files=dir.listFiles();
   for(int x=0;x<files.length;x++)
   {
     if(files[x].isDirectory())
       show(files[x]);               
      else
         System.out.print(files[x]);
    }
   }
    

   下面我们以创建java类型的文件列表为例 ,说明file类的一些用法

package com.itheima;

import java.io.File;
import java.util.List;

 class test6
 {
	 public static void main(String[] args)
	 {
		 File dir=new File();
		 List<File> list=new ArrayList<File> ();
		 filetolist(dir,list);
		 System.out.print(list.size());
				 
		 
	 }
	 public static void  filetolist(File dir,List<File> list)
	 {
		 File[] files=dir.listFiles();
		 for(File file : files)
		 {
			 if(file.isDirectory())
				 filetolist(file,list);
			 else
			 {
				 if(file.getName().endsWith(".java"))
					 list.add(file);
			 }
		 }
	 }<pre name="code" class="java">     public static void writertofile(List<File> list,String javalistfile) throws IOException
      {
        BufferedWriter bufw=null;
         try{
                                          bufw=new BufferedWriter(new FileWriter(javaListFile));
					 for(File f: lies)
{
  String path=f.getAbsolutePath();
 bufw.writer(path);
 bufw.newline();
   bufw.flush;
} 
 }
catch(IOException e)
{
 throw e;
}
          finally
{
try
{
  if(bufw!=null)
		bufw.close();			
		}
 catch(IOException e)
					{
 throw e;
}
	}
       }
 }

       Properties 是hashtable的子类,具备map集合的特点。而且它里面储存的键值对都是字符串。该对象的特点是可以用于键值对形式的配置文件。常用的方法: 

 Properties prop=new Properties();
   prop.setProperty("xx");       //改变内存里的数据
  stringPropertyNames()是遍历列表中的键集。该集合中提供了Load方法,从1.6开始加载字符流。

prop.load();   //直接加载文件
    store 方法则是改变到流中,写入到文件中。store(file,neirong)

   打印流:提供了打印方法,可以将各种数据类型的数据原样打印。字节打印流:PrintStream ,构造函数可以接受的参数类型:file对象:File,字符串路径:String,字节输出流:outputstream。

    字符 打印流:PrintWriter file对象:File,字符串路径:String,字节输出流:outputstream,字符输出流:Writer。字符打印流常用的人方法,刷新只对流而言的。自有write方法所以使用起来更方便。

   序列流:对象序列化把内存中的java对象转换为与平台无关的二进制流,序列流从而允许把这种二进制流持久地留在磁盘上。可以将多个流并联进行处理。 由于序列化属于老版本的,使用的Vector,那么他的迭代器属于Enumeration。

Vector<FileInputStream> v=new Vector<FileInputStream>();
v.add("  ");
Enumeration<FileInputStream> en =v.elements();
SequenceInputStream sis=new SequenceInputStream(en);
FileOutputStream fos=new FileOutputStream();
   对象序列流由上面的叙述可以知道对象序列化的代码  ,创建一个序列化的输出流,将per对象写入输出流中。

ObjectOutputStream ois=new ObjectOutputStream(new FileInputStream("xxx"));
  ois.writerObject(per);

   反序列化就是从流中恢复对象,反序列化读取的仅仅是java对象的数据,而不是java类。

ObjectInputStream ois=new ObjectInputStream(new FileInputStream("xxx"));
   
 Person p=(Person)ois.readObject();
  RandomAccessFile:该类不是IO体系的子类,直接继承来自Object。但是它是IO包中的成员,因为他具备读和写功能,内部封装了一个数组,通过指针来对数组的数据进行操作,getFilePointer来获取指针位置,同时通过seek来改变指针的位置。该类只能操作文件。r:只读方式打开文件,rw:读写打开文件,rws:读写打开,对文件内容或元数据更新都同步写入底层存储设备中,rwd: 读写打开,对文件内容更新都同步写入底层存储设备中。

RandomAccessFile raf=new RandomAccessFile("xxxx","rw");  
raf.seek(300);							//seek可以设置写入的位置,raf.length(),来进行文件末尾来进行续写。
byte[] b=new byte[300];
int hasone=0;
while((hasone=raf.read(b))>0)
{}
 DataInputstream与Dataoutputstream 可以用于操作基本数据类型的数据对象。 ByteArrayInputstream与 ByteArrayOutputstream这两个对象的出现没有调用底层资源,不必关闭资源,不产生任何IO异常,此类中的方法关闭后仍可调用

  Java默认的使用Unicode字符集,常见的编码表:GBK:简体中文字符集,BIG5:繁体中文字符集,ISO-8859-1:ISO拉丁字母表NO.1,UTF-8:8位UCS转换格式。Unicode:国际标准码,融合多种文字。我们在字符流与字节流的转换中时是可以选定编码标准的。

    字符与字节的转换,String转换为byte:str.getByte(charsetName)。byt e转换为String:new String(byte[] ,CharsetName);

    


     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值