------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);