Java基础之IO
javaIO知识
字节流 基类
inputStream
outputStream
字符流 基类
Reader
Writer
专门用于操作文件的Writer子类对象,FileWriter,后缀名是父类名,前缀名是该流对象的功能
import java.IO.*;
public static void main(String args[])
{
1,创建一个FileWriter对象,对象一初始化就要有要操作的文件
FileWriter fw=new FileWriter("Demo.txt");//该文件会被创建到指定的目录下,如果该目录下已有同名文件将被覆盖
2,写数据
fw.write("123456"); //将字符串写入流中去,内存区
3,将流中数据写入文件
fw.flush(); //只刷新,并不关闭,后面还可以使用该流
//fw.close();//该方法也可以将数据写入文件,但是该流将关闭,后面就不能再写数据了
}
IO异常的处理方式
public static void main(String args[])
{
FileWriter fw=null;
try
{
fw=new FileWriter("Demo.txt");
fw.write("123456");
}
catch(IOException e)
{
try
{
if(fw!=null)
fw.close();
}
catch(IOException e)
{
System.out.println(e.toString());
}
}
}
对已有文件追加写入
FileWriter fw=new FileWriter("Demo.txt",true);//初始化构造函数,可以选择是否覆盖以后文件
fw.write("123456");
fw.close();
读取文件
//1,创建一个文件读取对象,和指定文件项关联,要保证该文件是已经存在的,如果不存在抛出IO异常
FileReader fr=new FileReader("Demo.txt");
//2读取文件
fr.read();一次只读一个字符,可以继续往下读;
fr.close();
//一个字符一个字符的读文件
FileReader fr=new FileReader("Demo.txt");
int ch=0;
while(ch=fr.read()!=-1)
{
System.out.println("ch:"+(char)ch);
}
//以字符串方式读取
FileReader fr=new FileReader("Demo.txt");
char[] buf=new char[1024];
int num=0
while(num=fr.read(buf)!=-1)
{
System.out.println(new String(buf,0,num));
}
fr.close();
文件复制
1,一个字符一个字符的复制
FileWriter fw=new FileWriter("DemoCopy.txt");
FileReader fr=new FileReader("Demo.txt")
int ch=0;
while(ch=fr.read()!=-1)
{
fw.write(ch);
}
fr.close();
fw.close();
2,字符串形式复制
FileWriter fw=new FileWriter("DemoCopy.txt");
FileReader fr=new FileWriter("Demo.txt");
char[] buf=new char[1024];
int num=0;
while((num=fr.read(buf))!=-1)
{
fw.write(buf,0,num);
}
fr.close();
fw.close();
缓冲区的出现是为了提高流的操作效率而 出现的
所以初始化时必须由流对象
通过缓冲区复制一个文件
BufferWriter bufw=new BufferWriter(new FileWriter("DemoCopy.txt"));
BufferReader bufr=new BufferReader(new FileReader("Demo.txt"));
string line=null;
while((line=bufr.readLine())!=null) //readLine方法将一行数据读取,并返回字符串
{
bufw.write(line);
bufw.newLine();
bufw.flush();
}
bufw.close();
bufr.close();
装饰设计模式
当想要对已有对象进行功能增强时,可以定义一个类,将已有对象传入,
基于已有对象的功能,并提供加强功能,那么,自定义的该类就称为装饰类
装饰类通常会通过构造方法接收被装饰的对象,并基于被装饰对象的功能,提供更丰富的功能
装饰模式比继承要灵活,避免了代码臃肿,而且降低了类与类之间的关系
装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强的功能,
所以装饰类和被装饰类通常都属于一个体系中的
Reader 继承关系
|--TextReader
|--BufferTextReader
|--MediaReader
|--BufferMediaReader
|--FileReader
|--BufferFileReader
|--WebReader
|--BufferWebReader
Reader 装饰关系
|--TextReader
|--MediaReader
|--FileReader
|--WebReader
|--BufferReader
装饰比继承的好处: 减少了代码的臃肿,增强代码阅读性
class Source 原始类
{
public void function()
{
}
}
class SuperSource 装饰类
{
Source s=null;
public SuperSource(Source s)
{
this.s=s;
}
public void SuperFunction()
{
要操作的代码
s.function();
要操作的代码
}
}
字节流
InputStream
OutputStream
//写文件
FileOutputStream fos=new FileOutputStream("demo.txt");
fos.write("abcdef".getBytes());//字节流不需要flush()进行刷新
fos.close();
//读文件
FileInputStream fis=new FileInputStream("Demo.txt");
int ch=0;
while((ch=fis.read())!=-1)
{
System.out.prinln((char)ch);
}
fis.close();
FileInputStream fis=new FileInputStream("Demo.txt");
byte[] buf=new byte[1024];
int len=0;
while((len=fis.read(buf)!=-1))
{
System.out.println(new String(buf,0,len));
}
fis.close();
fis.available();获取文件大小
byte[] buf=new byte[fis.avaliable()] //虚拟机初始化的大小是64m
fis.read(buf);
fis.close();
字节流
FileInputStream
FileOutputStream
BufferedInputStream
BufferedOutputStream
class StreamDemo
{
//输入流
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));//如果输入流是文件的话System.in替换为new FileInputStream("Filepath")
//输出流
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));//如果输出流是文件的话System.out替换为new FileOutputStream("Filepath")
//输入流读取
while(String line=br.readLine()!=null)
{
//输出流打印输出
bw.write(line);
bw.newLine();
bw.flush();
}
br.close();
bw.close();
}
1,明确输入和输出
源:InputStream,Reader
目的:OutputStream Writer
2,明确操作的数据是否是纯文本
是:选择字符流
不是:选择字节流
3,体系明确后再确定使用哪个对象;
通过设备进行区分
原设备:内存buffer,硬盘File,键盘System.in
目的设备;内存buffer,硬盘File,控制台System.out
Properties类-----流中数据存储的集合
1.获取和设置属性
Properties prop=new Properties();
//设置属性值
prop.setProperty("zhangsan","20");
prop.setProperty("Lisi","30");
//遍历输出
Set<String> names=prop.getProperties(); //获取所有的属性值存储到set集合中
for(String n:names)
{
System.out.println(n+":"+prop.getProperty(n));
}
2,加载文件
properties加载文件时要有固定的格式
key=value
#开头的为注释,不会被Properties加载
//
Properties prop =new Properties();
FileInputStream fs=new FileInputStream("a.txt");
//将文件加载到prop中去
prop.load(fs);
System.out.println(prop);
prop.list(System.out);列出所有列表属性
prop.setProperty("anby","20");
prop.store(fs);
java存储对象的常用方式有两种
1,properties文件 主要针对键值对形式的配置
2,Xml 文件 主要针对存储多个对象的数据
打印流
printstream --字节打印流
构造函数可以接收的类型
1,file对象
2,字符串路径,string
3,字节输出流:outputStream
printwriter --字符打印流
1,file对象
2,字符串路径,string
3,字节输出流:outputStream
4,字符输出流;writer
Demo:
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
PrintWriter pw=new PrintWriter(System.out);
String line=null;
while((line=br.readLine())!=null)
{
pw.write(line);
pw.flush(); 需要刷新才能进行显示
}
pw.close();
br.close();
SequenceInputStream对象
功能:合并多个流对象
构造函数:SequenceInputStream(InputStream a1,InputStream a2)
SequenceInputStream(Enumeration<InputSteam> e)
Demo:将1.txt,2.txt,3.txt合并为4.txt
Vector<FileInputStream> v=new Vector<FileInputStream>();
v.add(new FileInputStream("1.txt"));
v.add(new FileInputStream("2.txt"));
v.add(new FileInputStream("3.txt"));
Enumeration en=v.elements();
SequenceInputStream s=new SequenceInputStream();
FileOutputStream fos=new FileOutputStream("4.txt");
byte[] buf=new byte[1024];
int len=0;
while(len=s.read(buf)!=-1)
{
fos.write(buf,0,len);
}
fos.close();
s.close(); //关闭所有流对象
切割文件
SplitFile
FileInputStream fis=new FileInputStream("1.bmp");
FileOutputStream fos =null;
byte[] buf=new byte[1024];
int len=0;
int count=1;
while((len=fis.read(buf))!=-1)
{
fos=new FileOutputStream("c:\\Temp\\"+(count++)+".part");
fos.write(buf,0,len);
fos.close();
}
fis.close();
再次合并
ArrayList<FileInputStream> al=new ArrayList<FileInputStream>();
File f=new File("c:\\Temp");
if(f.isDirectory())
{
File[] subf=f.listFiles();
for(File t:subf)
{
al.add(new FileInputStream(t.getName()));
}
}
final Iterator it=al.iterator();
Enumeration<FileInputStream> en=Enumeration<FileInputStream>()
{
public boolean hasMoeElements();
{
it.hasNext();
}
public FileinputStream nextElement()
{
return (FileInputStream)it.next();
}
}
SequenceInputStream s=new SequenceInputStream(en);
FileOutputStream fos=new FileOutputStream("target.bmp");
byte[] buf=new byte[1024];
int len=0;
while(len=s.read(buf)!=-1)
{
fos.write(buf,0,len);
}
因为虚拟机的最大内存有限,所以buf数组不能超出最大长度,否则会内存溢出
如果想切割为100M大小的子文件,可以向文件中写数据,知道文件大小为100M
然后另外新建一个文件继续保存数据,依次类推
对象序列化:
class Person implements Serializable
{
String name;
String age;
public Person(String name,String age)
{
this.name=name;
this.age=age;
}
}
//序列化
ObjectOutputStream oos=new ObjectOutputStream(new FileOnputStream("C:\\temp.tmp"));
oos.writeObject(new Person("Anby","20"));
oos.close();
//反序列化
ObjectInputStream ois=new ObjectInputStream(new FileInputSream("C:\\temp.tmp"));
Person p=(Person)ois.readObject();
ois.close();