------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
IO是java体系中非常重要的一部分。虽然对安卓不是很了解,但是据说在安卓中IO更是很重要的部分,这块的学习不难,有几处需要明确,也就是IO内需要操作的数据类型,掌握了这些,对IO中OutputStream,InputStream,writer,Reader掌握好了,基本问题就不大。下面是IO流学习的一些笔记。
IO流综述
IO流--数据流
概念:用于操作设备之间的数据传输
分类:数据--字符流和字节流;流向--输入流和输出流。
字节流的抽象基类:InputStream,OutputStream 字符流的抽象基类:reader,writer。
IO流写入文件FileWriter
操作文件:在硬盘上创建文件并写入数据
过程:1,创建一个writer子类FileWriter对象,该对象一初始化就要明确被操作的文件。
FileWriter fw =new FileWriter(“demo.tet”);
//产生指定名称的文件,如果该目录下有同名文件将会被覆盖。
2,调用write方法将字符串写入到流中。
fw.write(“abcde”)。
3,将数据刷到目的地中,刷新流对象中的缓冲区。
fw.flush();
fw.close()。关闭流资源,关闭之前会刷新一次缓冲的数据。
IO异常的处理方式,抛是不合适的。
----要在外面建立对象,try内初始化,在finally内关闭流,关闭之前要判断流是否为空。
文件的续写:对已有文件-----传递一个true参数表示不复写。并在文件的末尾处进行续写:
FileWriter fw =new FileWriter(“demo.txt”,true);换行:/r/
IO流读取文件FileReader
注意:读是不用刷的
过程---一次读一个:1,创建一个文件读入对象,和指定文件相关联。文件要先存在,否则会发生异常。
FileReader fr = new FileReader(“demo.txt”);
2,调用读取流的read方法:
int ch =fr.read(); read一次读取一个。读到末尾,返回-1.
(提升):循环条件,返回-1.
while(true){ int ch = fr.read();if(ch=-1) break; syso((char)ch)}
3,要关闭。
---通过字符数组读取:1、同上
2,定义一个字符数组,用于存储字符。该read方法返回的是读到的字符个数。
char [] buf =new char[1024];通常情况下是1024
int num =fr.read(buf);
练习:拷贝文件代码
import java.io.*;
class CopyText
{
public static void main(String[] args) throws IOException
{
copy_2();
}
public static void copy_2()
{
FileWriter fw = null;
FileReader fr = null;
try
{
fw = new FileWriter("SystemDemo_copy.txt");
fr = new FileReader("SystemDemo.java");
char[] buf = new char[1024];
int len = 0;
while((len=fr.read(buf))!=-1)
{
fw.write(buf,0,len);
}
}
catch (IOException e)
{
throw new RuntimeException("读写失败");
}
finally
{
if(fr!=null)
try
{
fr.close();
}
catch (IOException e)
{
}
if(fw!=null)
try
{
fw.close();
}
catch (IOException e)
{
}
}
}
public static void copy_1()throws IOException
{
FileWriter fw = new FileWriter("RuntimeDemo_copy.txt");
FileReader fr = new FileReader("RuntimeDemo.java");
int ch = 0;
while((ch=fr.read())!=-1)
{
fw.write(ch);
}
fw.close();
fr.close();
}
}
字符流的缓冲区
概念:为了提高对数据的读写效率。
类:BufferedWriter,BufferedReader,要结合流使用,在流的基础上进行增强。
BufferedWriter:
过程:1,同上1创建流。
2,加入缓冲技术。BufferedWriter bw =new BufferedWriter(fw);
3,bw.write("abcde");
注意:用了缓冲区,就要刷新。bw.flush()。
4,关闭缓冲区。也就关闭了缓冲区内的流 对象。
方法:newLine。行 分隔符。
BufferedReader:
过程:1,同上
2,同上
3,String s1 =new br.readLine();读取一行。##最为方便。
(提升)循环不为空。
方法:一次读一行,方便对文本数据的获取。末尾返回null,因为返回的是字符串类型。
练习: 缓冲区的练习。
import java.io.*;
class CopyTextByBuf
{
public static void main(String[] args)
{
BufferedReader bufr = null;
BufferedWriter bufw = null;
try
{
bufr = new BufferedReader(new FileReader("BufferedWriterDemo.java"));
bufw = new BufferedWriter(new FileWriter("bufWriter_Copy.txt"));
String line = null;
while((line=bufr.readLine())!=null)
{
bufw.write(line);
bufw.newLine();
bufw.flush();
}
}
catch (IOException e)
{
throw new RuntimeException("读写失败");
}
finally
{
try
{
if(bufr!=null)
bufr.close();
}
catch (IOException e)
{
throw new RuntimeException("读取关闭失败");
}
try
{
if(bufw!=null)
bufw.close();
}
catch (IOException e)
{
throw new RuntimeException("写入关闭失败");
}
}
}
}
另外:readLine方法:返回只返回回车符之前的内容,不返回回车符。
装饰设计模式:
概念:对已有的对象进行功能增强,可以定义一个类将已有对象传入,基于已有对象的功能,
并加强功能。那么自定义的类就是装饰类。
继承与装饰的区别:
装饰比继承灵活,而且降低了类与类之间的关系。
方法:LineNuberReader getLineNumber 获取行号 带行号的装饰类
字节流:
分类:OutputStream,InputStream
FileOutputstream:
1,字节流里不存在缓冲区,不需要刷新。
2.但是资源要关闭。
FileInputStream:
1;两种读的方式。
其它特有:available:可以计算数据量。可以定义一个刚刚好的缓冲区,,不需要再循环。
Byte [] buf =new Byte(fis.availabl())
2:还是以1024整数倍为主。
字节流的缓冲区:
BufferedFileOutputStream,BufferedFileInputStream
IO流其它类
1,读取键盘录入:
过程:1,InputStream in =System.in;
2,int by =in.read();
练习: 获取键盘录入。
import java.io.*;
class ReadIn
{
public static void main(String[] args) throws IOException
{
InputStream in = System.in;
StringBuilder sb = new StringBuilder();
while(true)
{
int ch = in.read();
if(ch=='\r')
continue;
if(ch=='\n')
{
String s = sb.toString();
if("over".equals(s))
break;
System.out.println(s.toUpperCase());
sb.delete(0,sb.length());
}
else
sb.append((char)ch);
}
}
}
2,读取转换流:
概念:定义在字符流体系中。
其它:字节流转换成字符流。InputStreamReader
练习:TransStreamDemo
3,写入转换流:OutputStreamWriter。
##重点键盘录入标准写法:
BufferedReader bufr =new BufferedReader(new InputStreamReader(System.in))
----流的操作规律:
确定流对象----两个明确1,明确源和目的。2,操作的数据是否为纯文本。
源是输入流(inputStream,reader),目的是输出流(outputStream,writer)。
是纯文本用字符流,不是就用字节流。
体系明确后再确定使用哪个具体的对象。
是否需要提高效率。是就加入缓冲区。
注意:---- 转换流使用:
字符和字节之间的桥梁通常涉及到字符编码转换时需要用到转换流。
4,printStackTrace:异常日志存取
properties的list方法可以列出系统信息。prop.list()
创建源(流对象);new PrintStream();
5,IO包中比较重要的对象:
File类:用于将文件和文件夹封装成对象。可以对文件的属性信息进行操作。流只能操作数据。
过程:创建File对象,File f =new File(“a.txt”)
方法:1,创建:createNewFile返回布尔型,有异常信息----创建临时文件。
mkdir创建文件夹只能创建单级文件夹。mkdirs
2,判断:canExceute判断是否可以执行
##exists()判断文件是否存在。isFile isDirectory
3,删除:delete返回布尔型 void deleteOnExit()在程序退出时判断制文件。
4,获取信息:getName getPath lastModified getParent length renameTo---改名字
文件的功能:listRoots 列出系统盘符
**递归:
概念:因为目录中还有目录,只要使用同一个列出目录功能的函数完成即可,
在列出过程中如果还是目录的话,就可以再次调用本功能。
也就是函数调用自身。
注意:限定条件--递归次数
6,properties
概念:是hashtable的子类,里面存的键值对都是字符串。
与IO技术相结合的集合容器。
设置或获取:setProperties(key,value);getProperties(key);stringPropertyNames()
存取配置文件:文件中的数据放在properties集合内。
步骤:1,用一个流与文件关联。
2,读取一行文件将改行数据用“=”进行切割。
3,等号左边作为键,右边作为值,存取到Properties集合。
代码:BufferedReader bufr =new BufferedReader(new FileReader(”info.txt“));
String line =null
Properties prop =new Properties()
while((line = bufr.readLine())!=null))
{String[] arr =line.splid("=");
prop.setProperty(arr[0],arr[1]);
}
方法:load加载。将流中数据加载进properties。 list :列出集合目录。 store将集合中的数据存储到指定文件中。
练习: 记录使用次数,次数到了报出注册信息。
import java.io.*;
import java.util.*;
class RunCount
{
public static void main(String[] args) throws IOException
{
Properties prop = new Properties();
File file = new File("count.ini");
if(!file.exists())
file.createNewFile();
FileInputStream fis = new FileInputStream(file);
prop.load(fis);
int count = 0;
String value = prop.getProperty("time");
if(value!=null)
{
count = Integer.parseInt(value);
if(count>=5)
{
System.out.println("您好,使用次数已到,拿钱!");
return ;
}
}
count++;
prop.setProperty("time",count+"");
FileOutputStream fos = new FileOutputStream(file);
prop.store(fos,"");
fos.close();
fis.close();
}
}
7,字节打印流:printStream
可以接受的参数类型 file string inputStream
8,字符打印流:printwriter常用。
9,合并流:SequenceInputStream
分段练习:
import java.io.*;
import java.util.*;
class SplitFile
{
public static void main(String[] args) throws IOException
{
splitFile();
merge();
}
public static void merge()throws IOException
{
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
for(int x=1; x<=3; x++)
{
al.add(new FileInputStream("c:\\splitfiles\\"+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("e:\\splitfiles\\0.bmp");
byte[] buf = new byte[1024];
int len = 0;
while((len=sis.read(buf))!=-1)
{
fos.write(buf,0,len);
}
fos.close();
sis.close();
}
public static void splitFile()throws IOException
{
FileInputStream fis = new FileInputStream("e:\\psp.jpg");
FileOutputStream fos = null;
byte[] buf = new byte[1024*1024];
int len = 0;
int count = 1;
while((len=fis.read(buf))!=-1)
{
fos = new FileOutputStream("c:\\splitfiles\\"+(count++)+".part");
fos.write(buf,0,len);
fos.close();
}
fis.close();
}
}
10,对象的序列化:
概念: 可以直接操作对象的流,ObjectOutputStream
注意:要启用Serializable接口。才能实现对象的序列化。
静态不能被序列化。 transient 修饰不能被序列化。
11,管道流:PipedInputStream();
12,RanAccessFile:继承Object。内部封装了字节输入流和输出流。该类只能操作文件。
方法:seek调整指针, skipBytes(int n)跳过字节。
13,DateInputStream:用于操作基本数据的流对象
特殊方法:writeUTF只能用指定的方法读出来。readUTF
ByteArryInputStream,ByteOutputStream:内存为源和目的的操作。不需要关闭。