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();
 
 
原文地址:https://www.cnblogs.com/anbylau2130/p/3041347.html