IO流知识点总结——博客园:师妹开讲啦

课本知识点总结--博客园:师妹开讲啦

Java中的流是有序的数据序列,是传递数据信息的载体,也是程序中的数据所经历的路径

流根据方向可分为输入流和输出流:输入流是将数据源传递给程序,输出流是将数据从程序传递到目的地,如内存、文件、网络等。

根据流的角色可分为节点流(FileInputStream、FileOutputStream、FileReader、FileWriter)和处理流

根据组成流的不同,可以将其分为字节流(FileInputStream、FileOutputStream、BufferedInoutStream、BufferedOutputStream、ObjectInputStream、ObjectOutputStream)和字符流(FileReader、FileWriter、BufferedReader、BufferedWriter、InputStreamReader、OutputStreamWriter):字节流是由字节组成的,主要用于处理二进制数据(图片、音频文件),字符流是由字符组成,主要用于处理文本的数据。

java.io.File类不属于Java流系统,但它是文件流进行文件操作的辅助类。

File类的对象是一个“文件或目录”的抽象代表。File类的对象并不打开文件或目录,而是指定要操作的文件或目录。File类的对象一旦创建,就不能再更改,即它代表的抽象路径是不能改变的。

String list[]=file.list();//只返回文件名,没有路径信息

File listFile[]=file.listFiles();//不但返回文件名称还含有路径信息

mkdir()——返回值类型:boolean,只能创建单层目录,不能含有子目录,即只能在已存在的目录中创建目录

mkdirs()——返回值类型:boolean,可以创建多级目录,可以含有子目录,即可以在不存在的目录中创建文件夹

例1:给定一个目录,列出此目录下的所有文件和目录

public class ListFile{

  public static void main(String[] args){

    System.out.println("请输入路径:");

    Scanner scan=new Scanner(System.in);

    String path=scan.next();

    File file=new File(path);

    fileList(file);

    public static void fileList(File file){

      if(file.isFile()){

        System.out.println(file.getName());

      }else{

        System.out.println("\t"+file.getPath()+"是目录");

        File fileName[]=file.listFiles();

        for(int i=0;i<fileName.length;i++){

          fileList(fileName[i]);

      }

    }

  }

}

向文件中写入时,若指定文件在操作前不存在,则操作之后系统会自动创建该文件,但目标文件存在的目录必须存在,否则抛出FileNotFoundException异常

String s="Java学习手记";

byte[] b=s.getBytes();

char[] c=s.toCharArray();

字节流是对文件本身直接进行操作,不需要通过缓冲区,而字符流则要通过缓冲流来操作文件,即使用字节流时,就算没有执行close()方法关闭字节流的操作,还是可以向文件输出内容的,但在字符流中,若不执行close()方法,就无法像文件写入内容,因为程序在执行过程中引入了缓冲区机制,即写操作先将内容放入缓冲区,若写操作完毕后,不将缓冲区内容刷新到文件,文件将为空,但可以使用flush()强制清除内容。执行close()方法时默认执行flush()方法

转换流:BufferedRead——readLine()一次读取一行,BufferedWriter——newLine()写入一个行分隔符

内存操作流:ByteArrayInputStream、ByteArrayOutputStream

ByteArrayInputStream将数据写入内存中,ByteArrayInputStream类的实例化对象和执行read()方法都不需要处理异常,但调用close()方法需要处理异常,可调用的close()是没有任何操作的一个空方法,在关闭字节数组输入流后仍可被调用,而不会产生任何IOException

内存操作流一般用于处理临时信息,因为临时信息不需要保存,使用后就可以删除

PrintStream类是FilterOutputStream的子类

例2:使用Scanner从文件中获取数据

public class ScannerDemo{

  public static void main(String[] args){

    File file=new File("E:/JavaDemo/10/poetry.txt");

    if(!(file.exists())){

      System.out.println("文件不存在");

      System.exit(0);

    }

    FileInputStream fis=null;

    Scanner scan=null;

    try{

      fis=new FileInputStream(file);

      scan=new Scanner(fis);

    }catch(Exception e){

      e.printStackTreace();

    }

    StringBuffer sbu=new StringBuffer();

    while(scan.hasNext()){

      sbu.append(scan.next()).append("\n");

    }

    System.out.print(sbu);

  }

}

随机(任意)访问文件类:RandomAccessFile

java.io.RandomAccessFile类不属于流,是Object的子类,但融合了流类InputStream和OutputStream的功能,既提供与InputStream类似的read()方法,又提供OutputStream类似的write()方法,还提供更高级的直接读写各种基本数据类型数据的读写方法,例如readInt()、writeInt(),该类还可以从文件的任意位置开始访问文件,但要求文件中的各个数据保存的长度必须相等

顺序输入流(合并流):SequenceInputStream

SequenceInputStream类可以将多个输入流串流在一起,合并为一个输入流,在关闭输入流时,可只关闭顺序输入流,因为顺序输入流的close()方法将依次关闭被串联的输入流,但不会关闭输出流

ZipEntry类的对象是用来表示ZIP文件条目,代表ZIP文件内的进入点(entry)

例3:ZipOutputStream类压缩文件夹

public class ZipOutputStreamDemo{

  public static void main(String[] args){

    File f1=new File("zip"); 

    File f2=new File("zipjava.zip");

    FileInputStream fis=null;

    FileOutputStream fout=null;

    ZipOutputStream zout=null;

    File fileName[]=null;

    byte b[]=new byte[1024];

    int temp=0;

    try{

      fout=new FileOutputStream(f2);

      zout=new ZipOutputStream(fout);

      zout.setComment("Use ZipOutputStream compression zip Directory");//设置注释

      if(f1.isDirectory()){

        fileName=f1.listFiles();

        for(int i=0;i<fileName.length;i++){

          fis=new FileInputStream(fileName[i]);

          zout.putNextEntry(new ZipEntry(fileName[i].toString()));

          System.out.println("正在压缩"+fileName[i]+".......");

          while((temp=fis.read(b))!=-1){

            zout.write(b,0,temp);

          }

          System.out.println("压缩"+fileName[i]+"完成");

        }

      }

      zout.close();

      fout.close();

      fis.close();

    }catch(Exception e){

      e.printStackTrace();

    }

  }

}

例4:ZipFile类解压缩ZIP文件

public class ZipFileDemo{

  public static void main(String[] args){

    File file=new File("zipjava.txt");

    File zipFile=new File("java.zip");

    InputStream in=null;

    FileOutputStream fout=null;

    ZipEntry entry=null;

    ZipFile zip=null;

    byte b[]=new byte[1024];

    int temp=0;

    try{

      zip=new ZipFile(zipFile);

      entry=new ZipEntry("java.txt");

      in=zip.getInputStream(entry);

      fout=new FileOutputStream(file);

      while((temp=in.read(b))!=-1){

        fout.write(b,0,temp);

      }

      zip.close();

      fout.close();

    } catch(Exception e){

      e.printStackTrace();

    }

  }

}

博客园:师妹开讲啦

对象序列化

序列化:对象存储,对象转换为字节    反序列化:字节转换为对象

对象的序列化的用途:1、把对象的字节序列永久的保存到硬盘上,通常存放在一个文件中 2、在网络上传送对象的字节序列

如需要某个对象能支持序列化机制,必须让它实现Serializable接口,该接口只是一个标记接口,实现该接口无需实现任何方法,仅仅表明该类的对象是可序列化的

对象被序列化时参与序列化的内容:属性、类名,不能序列化的内容:方法、类中的所有方法、static关键字和transient关键字修饰的属性

Serializable接口和Externalizable接口均可以完成对象的序列化和反序列化,被Serializable接口声明的类对象的内容都将被序列化,而Externalizable接口声明的类的对象可以选择需要序列化的内容。但一般使用Serializable接口实现序列化,因为该接口不需要实现任何方法,而Externalizable接口定义了readExternal()和writeExternal()方法,实现该接口的类必须实现这两个方法

 

 视频知识点总结

创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件,而且该文件回被创建到指定目录下,如果该目录下已有同名文件,将被覆盖。

字节流如若不使用close()方法,结果仍可在文件中显示,字符流如若不使用close()方法则为空,可以使用flush()将缓冲去中缓存的内容推出,就可显示出内容。

FileWriter fw=new FileWriter(“demo.txt”,true);//传递一个true参数,代表不覆盖已有的文件,并在已有文件的末尾处进行数据续写。

记事本当中不能识别\n”,要想换行使用“\r\n

只要用到缓冲区,就要刷新(flush()

关闭缓冲区,就是在关闭缓冲区中的流对象

缓冲区中提供了一个跨平台的换行符(newLine()

缓冲区提供了一个一次读一行的方法readLine(),方便于对文本数据的获取,返回的时候只返回回车符之前的数据内容,并不返回回车符。当返回null时,表示读到文件末尾。

byte[] buf=new byte[fis.available()];//定义一个刚刚好的缓冲区,不用再循环了

(建议在文件小的前提下使用,如若过大还是使用数组的1024倍较合适)

11111111—提升到int型(11111111 11111111 11111111 11111111)仍是-1,只要在前面补0-1&255)—25500000000 00000000 00000000 11111111),既可以保留原字节数据不变,又可以避免-1的出现。

System.setIn()//重新分配“标准”输入流。    System.setOut()// 重新分配“标准”输出流。 

 

相当于复制文件getParent()方法返回的是绝对路径中的父目录,若File f=new File(“a.txt”);getParent()则返回null

File f1=new File(“C:\\text.java”);File f2=new File(“D:\\hahah.java”);f.renameTo(f1);//true                renameTo()方法类似于剪切 

package practice;

import java.io.BufferedWriter;

import java.io.File;

import java.io.FileWriter;

import java.util.ArrayList;

import java.util.List;

public class JavaFileList {

public static void main(String[] args) {

File dir=new File("f:/java"); 

List<File> list=new ArrayList<File>();

fileToList(dir, list);

File file=new File(dir,"javaList.txt");

writeToFile(list, file.toString());   

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

}

}

}

public static void writeToFile(List<File> list,String javaListFile){

BufferedWriter bufw=null;

try{

bufw=new BufferedWriter(new FileWriter(javaListFile));

for(File f:list){

String path=f.getAbsolutePath();

bufw.write(path);

bufw.newLine();

bufw.flush();

}

}catch(Exception e){

e.printStackTrace();

}finally{

try

if(bufw!=null){

bufw.close();

}

}catch(Exception e){

e.printStackTrace();

}

}

}

} 

 

package practice;

//Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。

//属性列表中每个键及其对应值都是一个字符串。

import java.io.BufferedReader;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.FileReader;

import java.io.IOException;

import java.util.Properties;

import java.util.Set;

public class PropertiesDemo {

public static void main(String[] args) throws IOException {

setAndGet();

method_1();

loadDemo();

}

public static void setAndGet(){

Properties prop=new Properties();

prop.setProperty("zhangsan", "30");

prop.setProperty("lisi", "39");

// String value=prop.getProperty("lisi");

//stringPropertyNames()返回此属性列表中的键集,其中该键及其对应值是字符串,

//如果在主属性列表中未找到同名的键,则还包括默认属性列表中不同的键。

Set<String> names=prop.stringPropertyNames();

for(String s:names){

System.out.println(s+":"+prop.getProperty(s));// 用指定的键在此属性列表中搜索属性

}

}

public static void method_1() throws IOException{

BufferedReader bufr=new BufferedReader(new FileReader("info.txt"));

String line=null;

Properties prop=new Properties();

while((line=bufr.readLine())!=null){

String[] arr=line.split("=");

prop.setProperty(arr[0],arr[1]);

}

bufr.close();

System.out.println(prop);

}

public static void loadDemo() throws IOException{

Properties prop=new Properties();

FileInputStream fis=new FileInputStream("info.txt");

prop.load(fis);//从输入流中读取属性列表(键和元素对)

prop.setProperty("wangwu", "39");//只改变内存的结果,不能改变文件本身

FileOutputStream fos=new FileOutputStream("info.txt");

prop.store(fos, "haha");// 以适合使用 load(InputStream) 方法加载到 Properties 表中的格式,

//将此 Properties 表中的属性列表(键和元素对)写入输出流。

//System.out.println(prop);

prop.list(System.out);//将属性列表输出到指定的输出流

fos.close();

fis.close();

}

package practice;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.util.Properties;

public 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, "");

}

}

 

将多个文件合并至一个文件中

package practice;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.SequenceInputStream;

import java.util.Enumeration;

import java.util.Vector;

public class SequenceDemo{

public static void main(String[] args) throws IOException{

//Vector 类可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引

//进行访问的组件。但是,Vector 的大小可以根据需要增大或缩小,以适应创建

//Vector 后进行添加或移除项的操作。

Vector<FileInputStream> v=new Vector<FileInputStream>();

v.add(new FileInputStream("e:/1.txt"));//将指定元素添加到此向量的末尾

v.add(new FileInputStream("e:/2.txt"));

v.add(new FileInputStream("e:/3.txt"));

//实现 Enumeration 接口的对象,它生成一系列元素,一次生成一个。

//连续调用 nextElement 方法将返回一系列的连续元素。

Enumeration<FileInputStream> en=v.elements();// 返回此向量的组件的枚举

SequenceInputStream sis=new SequenceInputStream(en);

FileOutputStream fos=new FileOutputStream("e:/4.txt");

byte[] buf=new byte[1024];

int len=0;

while((len=sis.read(buf))!=-1){

fos.write(buf,0,len);

}

fos.close();

sis.close();

}

}

博客园:师妹开讲啦

切割、合并文件

package practice;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.SequenceInputStream;

import java.util.ArrayList;

import java.util.Enumeration;

import java.util.Iterator;

public class SplitFile {

public static void main(String[] args) throws IOException{

// splitFile();

merge();

}

public static void merge() throws IOException{

ArrayList<FileInputStream> a1=new ArrayList<FileInputStream>();

for(int x=1;x<=5;x++){

a1.add(new FileInputStream("e:/"+x+".part"));

}

final Iterator<FileInputStream> it=a1.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:/0.jpg");

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("吴亦凡.jpg");

FileOutputStream fos=null;

byte[] buf=new byte[1024*10];

int len=0;

int count=1;

while((len=fis.read(buf))!=-1){

fos=new FileOutputStream("e:/"+(count++)+".part" );

fos.write(buf,0,len);

fos.close();

}

fis.close();

}

}

操作对象ObjectInputStreamObjectOutputStream需要实现Serializable接口

(写入文件的信息看不懂)

静态变量不能实现序列化

非静态不想实现序列化则可在前加:transient//transient int age;

一般在实现对象流的时候,对象实体的文件以“.object”为后缀名

-----------管道流:PipedInputStream和PipedOutputStream与线程结合使用

RandomAccessFile该类不算是IO体系中的子类,而是直接继承自Object,但它是IO包中的成员,因为它具备读和写功能。内部封装了一个数组,而且通过指针对数组的元素进行操作。可以通过getFilePointer获取指针位置,同时可以通过seek改变指针的位置。

该类只能操作文件,而且操作文件还有模式,只读r,读写rw等,而且该对象的构造函数要操作的文件不存在会自动创建。如果存在则不会覆盖。

如果模式为只读,不会创建文件,会去读取一个已存在的文件,如果该文件不存在则会出现异常。

一个中文两个字节

RandomAccessFile raf=new RandomAccessFile(“ran.txt”,”r”);//r:只读、rw:读写、

Seek()//设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取  或写入操作。既可往前跳又可往后跳

skipBytes()// 尝试跳过输入的 n 个字节以丢弃跳过的字节(只可往前跳)

DataInputStream和DataOutputSteam用于操作基本数据类型的数据的对象。

//写入文件的信息看不懂、读取时必须按写入的顺序读

“你好”的Gbk文件用utf-8解码结果是??

“你好”的Utf_8文件用gbk解码结果是三个别的文字

编码:字符串变成字节数组String-byte[];str.getBytes(charsetName)

解码:字节数组变成字符串byte[]-String:new String(byte[],charsetName);

Integet.toBinaryString(b)将数值b转换成二进制,若只想要后八位则b&255

 

 

    

 

    

posted @ 2016-12-19 21:57  师妹开讲啦  阅读(302)  评论(1编辑  收藏  举报