JAVA IO总结

来源:互联网 发布:2018最新网络流行语 编辑:程序博客网 时间:2024/05/19 09:02

IO

IO,即输入输出流。这里的输入输出是相对于内存的,比如向一个文件中写东西,实为从内存写到硬盘,则为输出,反之为输入。


流的概念和作用

流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。 

 

IO流的分类

根据处理数据类型的不同分为:字符流和字节流

根据数据流向不同分为:输入流和输出流

 

字符流和字节流

字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。 字节流和字符流的区别:

读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。

处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。

结论:只要是处理纯文本数据,就优先考虑使用字符流。 除此之外都使用字节流。

 

输入流和输出流

对输入流只能进行读操作,对输出流只能进行写操作,程序中需要根据待传输数据的不同特性而使用不同的流。


一、字符流:

1.FileWriter,FileReader:文件输出流 ,文件输入流


FileWriter 的方法:


FileWriter(String fileName):构造函数,指定需要写入的文件名。


write(String s):将字符串s写入流(所关联的文件)中,先保存在缓冲区(是的你没有看错,FileWriter有一个默认缓冲区,其实Writer类及它的子类都有默认的缓冲区,因为Writer类有flush方法),在flush时或close之前立即写入文件中。


write(char[] ch):[不推荐使用]将字符数组写入流中。


write(char[],offset,len):[推荐使用]将字符数组的一部分写入流中。数据最后一次写时可能没有写满数组,效率提高了一点点。


flush():刷新字符流缓冲区,如果该流已保存缓冲区中各种 write() 方法的所有字符,则立即将它们写入预期目标。


append(char c):将字符续写到文件中。


close():关闭此流,但在之前要调用flush方法。



FileReader的方法:


FileReader(String fileName):构造函数,指定需要读取的文件名。


int read():读取一个字符,返回它的Unicode值的十进制表示。


int read(char[] cbuf):[推荐使用]将字符读入数组。


int read(char[] cbuf,int offset,int len):[不推荐使用]将字符读入数组的一部分。不推荐因为不知道最后一次读数据的长度,无法知道数组使用的长度。


close():关闭流。


IO_01_FileWriterDemo.java

import java.io.FileWriter;import java.io.IOException;/** *文件字符输出流FileWriter  */public class IO_01_FileWriterDemo {//将换行符封装成一个全局常量。private static final String LINE_SEPERATOR = System.getProperty("line.separator");public static void main(String[] args) throws IOException {//文件输出流,从内存中写到硬盘上FileWriter fw = new FileWriter("a.txt");//可以用带两个参数的构造函数,支持续写,则不覆盖原文件内容//FileWriter fw = new FileWriter("a.txt", true);//write会覆盖原文件内容,文件不存在则创建。//Windows中的换行字符是\r\nfw.write("abcdefg"+LINE_SEPERATOR);//向文件中加入fw.append('f');//必须刷新,将缓冲区的数据写入到硬盘fw.flush();//close前会自动flush一次该流的缓冲。}}</span>
IO_02_FileReaderDemo.java
import java.io.FileReader;import java.io.IOException;public class IO_02_FileReaderDemo {public static void main(String[] args) throws IOException {//第二种方法read(char[])FileReader fr = new FileReader("a.txt");//使用read(char[])方法读取字符输入流中的数据,返回读取的字符个数,如果读完了则返回-1char[] arr= new char[1024];int len = fr.read(arr);//通过String(char[],offset,count)得到读取的字符串。System.out.println(new String(arr,0,len));fr.close();/*//第一种方法read()FileReader fr = new FileReader("a.txt");int num = 0;//输入输出流信息传递的桥梁while((num=fr.read()) != -1){System.out.println(num);}*/}}</span>

IO_03_FileReader_FileWriter_Practice.java

import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;/** * 使用FileReader,FileWriter将a.txt中的内容写入b.txt中  */public class IO_03_FileReader_FileWriter_Practice {public static void main(String[] args) throws IOException {FileReader fr = new FileReader("a.txt");FileWriter fw = new FileWriter("b.txt",true);//创建字符数组作为输入流和输出流信息传递的桥梁,之前的字符ch,之后的BufferedReader,BufferedWrier缓冲区也是这个作用char[] arr = new char[1024];int len = 0;while((len = fr.read(arr)) != -1){fw.write(arr,0,len);}fr.close();fw.close();}}</span>

2.BufferedWriter,BufferedReader输出流缓冲区,输入流缓冲区(不是必要的,可以提高效率)


BufferedWriter将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。

缓冲区是装饰设计模式的体现:把原来的对象作为参数传构造时进去,对对象的功能进行增强.

装饰设计模式和继承的异同:

都能进行功能拓展,装饰模式比继承要灵活。避免了继承体系臃肿。降低了类于类之间的关系。装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。所以装饰类和被装饰类通常是都属于一个体系中的。在JAVA IO中用了很多增强 如:FileRead中read()方法 只是一个一个字节去读,为了读得更快在BufferedReader就增强了read()方法而产生了reandLine()一行一行的去读.

可以指定缓冲区的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。

该类提供了 newLine() 方法,它使用平台自己的行分隔符概念,此概念由系统属性line.separator 定义。并非所有平台都使用新行符 ('\n') 来终止各行。因此调用此方法来终止每个输出行要优于直接写入新行符。

通常 Writer 将其输出立即发送到底层字符或字节流。除非要求提示输出,否则建议用 BufferedWriter 包装所有其 write() 操作可能开销很高的 Writer(如 FileWriters 和 OutputStreamWriters)。例如,

 PrintWriter out   = new PrintWriter(new BufferedWriter(new FileWriter("foo.out"))); 

将缓冲 PrintWriter 对文件的输出。如果没有缓冲,则每次调用 print() 方法会导致将字符转换为字节,然后立即写入到文件,而这是极其低效的。


BufferedWriter的方法


BufferedWriter(Writer out):创建一个使用默认大小输出缓冲区的缓冲字符输出流


close():关闭此流,但要刷新它


flush():刷新缓冲区


newLine():写入一个换行符。是BufferedWriter独有的方法。


write(String s):写入字符串


write(String s,int off,int len):写入字符串的一部分


write(char[] cbuf):写入字符数组


write(char[] cbuf,int off,int len):写入字符数组的一部分


BufferedReader的方法:


BufferedReader(Reader in):创建一个使用默认大小输出缓冲区的缓冲字符输入


int read():读取一个字符


int read(char[] cbuf,int off,int len):读取字符数组的一部分


String readLine():读取一行(以换行符为标志)


IO_04_BufferedWriter.java

import java.io.BufferedWriter;import java.io.FileWriter;public class IO_04_BufferedWriter {public static void main(String[] args) {try {FileWriter fw = new FileWriter("a.txt");BufferedWriter bufw = new BufferedWriter(fw);bufw.write("aaa");//最好写一次刷一次bufw.flush();//写入换行符bufw.newLine();bufw.flush();bufw.write("bbb");bufw.close();} catch (Exception e) {e.printStackTrace();}}}</span>
IO_05_BufferedReader_readLine.java

import java.io.BufferedReader;import java.io.FileReader;import java.io.IOException;public class IO_05_BufferedReader_readLine {public static void main(String[] args) throws IOException {FileReader fr = new FileReader("a.txt");BufferedReader br = new BufferedReader(fr);String line = null;while((line = br.readLine()) != null){System.out.println(line);}}}</span>
IO_06_BufferedWriter_BufferedReader_Practice.java
import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;public class IO_06_BufferedWriter_BufferedReader_Practice {public static void main(String[] args) throws IOException {FileReader fr = new FileReader("a.txt");BufferedReader bufr = new BufferedReader(fr);FileWriter fw = new FileWriter("b.txt");BufferedWriter bufw = new BufferedWriter(fw);String line = null;while((line = bufr.readLine()) != null){bufw.write(line);//想要和a.txt一样则需要每行写入一个换行符bufw.newLine();bufw.flush();}bufw.close();bufr.close();}}

LineNumberReader可以输出行号,继承自BufferedReader,有两个方法setLineNumber(int i), int getLineNumber();可以设置和获取当前行号.输出带有行号的内容.例如

IO_07_LineNumberReader.java

import java.io.FileReader;import java.io.IOException;import java.io.LineNumberReader;public class IO_07_LineNumberReader {public static void main(String[] args) throws IOException {FileReader fr = new FileReader("a.txt");LineNumberReader lnr = new LineNumberReader(fr);String line = null;//设置开始的行号lnr.setLineNumber(1000);while((line = lnr.readLine()) != null){System.out.println(lnr.getLineNumber()+":"+line);}lnr.close();}}
控制台输出:
1001:public class IO_05_BufferedReader_readLine {1002:public static void main(String[] args) throws IOException {1003:FileReader fr = new FileReader("a.txt");1004:BufferedReader br = new BufferedReader(fr);1005:String line = null;1006:while((line = br.readLine()) != null){1007:System.out.println(line);1008:}1009:}1010:}

二,字节流

 字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串,而字节流处理单元为1个字节,操作字节和字节数组

FileOutputStream

FileOutputStream的方法

write(byte[]):写入字节数组

write(byte[],int off,int len):写入字节数组的一部分

write(int b):写入Unicode的十进制表示的字符

FileInputStream

FileInputStream的方法

read(int i):读取该字符的Unicode的十进制表示

read(byte[]):读取该字节数组

read(byte[] int off,int len):读取字节数组的一部分

int available():返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取(或跳过)的估计剩余字节数

IO_08_FileOutputStream.java

import java.io.FileOutputStream;import java.io.IOException;public class IO_08_FileOutputStream {public static void main(String[] args) throws IOException {FileOutputStream fos = new FileOutputStream("a.txt");fos.write("hahaha".getBytes());//字节流直接读取字节,不使用缓冲机制,不需要刷新fos.close();}}
IO_09_FileInputStream.java
import java.io.FileInputStream;import java.io.IOException;public class IO_09_FileInputStream {public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("a.txt");/*//方法一:int i = 0;while((i = fis.read())!=-1){System.out.println((char)i);}*//*//方法二:available方法返回文件的字节数,可以创建字节数组一次接收,文件较大时慎用.byte[] b = new byte[fis.available()];fis.read(b);System.out.println(new String(b));*///方法三:建议使用byte[] b = new byte[1024];int len = 0;while((len=fis.read(b))!=-1){System.out.println(new String(b,0,len));}}}
BufferedOutputStream

BufferedOutputStream的方法:略,类似于BufferedWriter.只是操作的是字节数组


BufferedInputStream

BufferedInputStream的方法:略.类似于BufferedReader.只是操作的是字节数组



IO_10_FileOutputStream_FileInputStream_Practice.java

import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class IO_10_FileOutputStream_FileInputStream_Practice {public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("1.jpg");FileOutputStream fos = new FileOutputStream("2.jpg");byte[] b = new byte[1024];int len = 0;while((len=fis.read(b))!=-1){fos.write(b,0,len);}/*//一个一个读取,不要使用这种低效率的方式int ch = 0;while((ch=fis.read())!=-1){fos.write(ch);}*/fis.close();fos.close();}}



IO_11_BufferedOutputStream_BufferedInputStream_Practice.java

import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class IO_11_BufferedOutputStream_BufferedInputStream_Practice {public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("1.jpg");FileOutputStream fos = new FileOutputStream("3.jpg");BufferedInputStream bufis = new BufferedInputStream(fis);BufferedOutputStream bufos = new BufferedOutputStream(fos);byte[] b = new byte[1024];int len = 0;while((len=bufis.read(b))!=-1){bufos.write(b,0,len);//使用缓冲区write时记得刷新哦~bufos.flush();}bufis.close();bufos.close();}}

练习键盘输入:输入一个小写字母组成的字符串,换行后显示大写形式,如果输入over停止读入

使用这种方式虽然可以将InputStream读取的字节流转换成字符串但是太麻烦,可以使用之后介绍的InputStreamReader直接转换为字符流.键盘录入通常使用InputStreamReader

IO_13_readfromKeyboard.java

import java.io.IOException;import java.io.InputStream;public class IO_13_readfromKeyboard {public static void main(String[] args) throws IOException {InputStream in = System.in;StringBuffer sb = new StringBuffer();int t = 0;while ((t = in.read()) != -1) {if ((char) t == '\r') {continue;}if ((char) t == '\n') {String temp = sb.toString();System.out.println(temp.toUpperCase());sb.delete(0, sb.length());if (temp.equals("over")) {break;}} else {sb.append((char) t);}}}}
字节流转换为字符流的桥梁-----InputStreamReader的作用:从键盘读取时将其转为字符流,以便使用字符流缓冲区操作

IO_14_InputStreamReader.java

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;public class IO_14_InputStreamReader {public static void main(String[] args) throws IOException {//字节流转换为字符流,使用InputStreamReader//获取键盘录入,记住下面这句话!BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));String line=null;while(!"over".equals(line=bufr.readLine())){System.out.println(line);}}}
IO_15_OutputStreamWriter.java

字符流转换为字节流------作用:使用BufferedWriter输出到控制台上

import java.io.BufferedWriter;import java.io.IOException;import java.io.OutputStreamWriter;public class IO_15_OutputStreamWriter {public static void main(String[] args) throws IOException {//向控制台输出.字符流变字节流,用OutputStreamWriter,<span style="font-family: Arial, Helvetica, sans-serif;">记住下面这句话!</span>BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));bufw.write("aaaa哈哈\r\nbbb".toCharArray());bufw.newLine();bufw.flush();}}

IO_16_InputStramReader_OutputStreamWriter_Practice.java

import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;public class IO_16_InputStramReader_OutputStreamWriter_Practice {public static void main(String[] args) throws IOException {BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));String line=null;while(!"over".equals(line=bufr.readLine())){bufw.write(line.toCharArray());bufw.newLine();bufw.flush();}bufr.close();bufw.close();}}

小总结:

读取字节流--InputStream--加缓冲区--BufferedInputStream

读取字符流--Reader--加缓冲区--BufferedReader

写入字节流--OutputStream--加缓冲区--BufferedOutputStream
写入字符流--Writer--加缓冲区--BufferedWriter

从键盘读:

BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
写入控制台:

BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));

练习:选择合适的流对象

练习1:将a.txt复制到b.txt中

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

BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt"));

练习2:将a.txt打印到控制台上

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

BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));

练习3:将键盘输入的数据写入a.txt中

BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));

BufferedWriter bufw = new BufferedWriter(new FileWriter("a.txt"));

练习4:将键盘输入的数据打印到控制台上

BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));

练习5:将a.txt中的数据按照指定编码表uft-8写入到b.txt中--使用转换流的方法.

IO_17_TransStream_Charset.java

import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;public class IO_17_TransStream_Charset {public static void main(String[] args) throws IOException {//5.将a.txt中的数据按照指定编码表uft-8写入到b.txt中//FileReader,FileWriter使用的是系统默认的编码表(简体中文则为GBK),不能使用此类//转换流有指定编码表的方法,转换流的参数是字节流对象,则为FileOutputStream,FileInputStreamFileInputStream fis = new FileInputStream("a.txt");FileOutputStream fos = new FileOutputStream("b.txt");BufferedReader bufr = new BufferedReader(new InputStreamReader(fis,"utf-8"));BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(fos,"utf-8"));String line = null;while((line=bufr.readLine())!=null){bufw.write(line);bufw.newLine();bufw.flush();}bufr.close();bufw.close();}}

上面的对象只能操作数据,如何操作文件呢?使用File对象

1.File构造函数和静态属性.

IO_18_File_Separator.java

import java.io.File;public class IO_18_File_Separator {public static void main(String[] args) {//构造函数1:建立一个名为a.txt的File对象,该File对象可以表示一个文件或文件夹File f1 = new File("a.txt");//构造函数2:建立一个名为c:\\a.txt的<span style="font-family: Arial, Helvetica, sans-serif;">File</span><span style="font-family: Arial, Helvetica, sans-serif;">对象</span>File f2 = new File("c:\\");File f3 = new File(f2, "b.txt");//构造函数:建立一个名为c:\\a.txt 的File对象File f4 = new File("c:"+File.separator, "c.txt");System.out.println(f2);System.out.println(f3);System.out.println(f4);//文件分隔符(Unix中是/,Windows中是\),路径分隔符(Unix中是:,Windows中是;)System.out.println(File.separator+File.pathSeparator);}}
2.File对象的方法之获取

import java.io.File;import java.text.DateFormat;import java.util.Date;public class IO_19_File_Methods {public static void main(String[] args) {File f = new File("a.txt");//获取名称System.out.println(f.getName());//获取绝对路径System.out.println(f.getAbsolutePath());//获取相对路径,即当前文件夹System.out.println(f.getPath());//获取所占总空间,虚拟机可用空间,可用空间System.out.println(f.getTotalSpace()+","+f.getUsableSpace()+","+f.getFreeSpace());//获取长度System.out.println(f.length());//获取上次修改时间Date date = new Date(f.lastModified());DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG);System.out.println(df.format(date));}}
3.File对象的方法之创建和删除

IO_20_File_Methods2.java

import java.io.File;import java.io.IOException;public class IO_20_File_Methods2 {public static void main(String[] args) throws IOException {//1.文件的创建和删除File f = new File("a.txt");//createNewFile()创建一个文件,成功返回true,已存在返回falseSystem.out.println(f.createNewFile());//detele()删除文件System.out.println(f.delete());//2.一个目录(文件夹)的创建和删除File dir = new File("aaa");//mkdir()创建目录(文件夹),成功返回true,已存在返回falseSystem.out.println(dir.mkdir());//delete()删除一个空目录(文件夹),不走回收站,如果文件夹不为空,则无法删除.System.out.println(dir.delete());//2.多级目录的创建和删除//mkdirs()创建多级目录File dir2 = new File("aa/bb/cc/dd/de");//创建多级目录System.out.println(dir2.mkdirs());//删除目录的最后一个文件夹System.out.println(dir2.delete());}}
4.File对象的方法之判断,重命名,ListRoots,

IO_21_File_Methods3.java

import java.io.File;public class IO_21_File_Methods3 {public static void main(String[] args) {//文件File方法之判断File f = new File("a.txt");f.mkdir();//f.createNewFile();//判断文件是否存在,最后先判断是否存在,再判断文件类型是文件还是目录System.out.println(f.exists());//判断是否是文件System.out.println(f.isFile());//判断是否是目录System.out.println(f.isDirectory());//重命名File f1 = new File("b.txt");//在同一个文件夹中则重命名,将b.txt命名为bbb.txtSystem.out.println(f1.renameTo(new File("bbb.txt")));//在不同文件夹中则剪切,将b.txt剪切到d:\\bbb.txtSystem.out.println(f1.renameTo(new File("d:\\bbb.txt")));//listRoots列出可用系统根目录,静态方法File[] listRoots = File.listRoots();for (File file : listRoots) {System.out.println(file);}//list列出该目录下所有文件和文件夹的名称,包括隐藏文件.若访问系统级目录会出异常.目录为空则创建的数组长度为0.File f2 = new File("c:\\");//必须是目录,不能是文件String[] names = f2.list();for (String name : names) {System.out.println(name);}}}
list方法练习:过滤器

输出d盘下所有扩展名为.txt的文件

IO_22_File_Method_list.java

import java.io.File;import java.io.FilenameFilter;public class IO_22_File_Method_list implements FilenameFilter{private String suffix;//后缀public IO_22_File_Method_list(String suffix) {super();this.suffix = suffix;}public static void main(String[] args) {File f = new File("d:\\");//list(FilenameFileter filter)创建接口,实现accept方法,方法中写过滤条件.String[] names = f.list(new IO_22_File_Method_list(".txt"));for (String name : names) {System.out.println(name);}}@Override//对文件路径和文件名进行过滤public boolean accept(File dir, String name) {return name.endsWith(suffix);}}


过滤隐藏文件:使用FileFilter接口

IO_23_File_Method_list2.java

import java.io.File;import java.io.FileFilter;public class IO_23_File_Method_list2 implements FileFilter{public static void main(String[] args) {File f = new File("c:\\");File[] files = f.listFiles(new IO_23_File_Method_list2());for (File file : files) {System.out.println(file);}}@Overridepublic boolean accept(File name) {return !name.isHidden();}}

Properties对象

IO_24_Properties.java

import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import java.util.Properties;import java.util.Set;public class IO_24_Properties {public static void main(String[] args) throws IOException {/* Map  |--HashTable     |--Properties Properties集合:用于操作以键值对形式存在的配置文件. 特点:1.该集合中的键和值都是字符类型的     2.集合中数据可以保存在流中,从流读取*/Properties p = new Properties();//存储元素p.setProperty("jhz", "19920811");p.setProperty("ztq", "19920221");p.setProperty("ddd", "19920421");//修改元素p.setProperty("ddd", "19990101");//遍历元素->使用stringPropertyNames方法返回key的set集合.Set<String> propertyNames = p.stringPropertyNames();for (String name : propertyNames) {System.out.println(name+p.getProperty(name));}//list方法,一般用于调试//p = System.getProperties();p.list(System.out);//将p放入输出流中//从输出流持久化数据到文件中,第一个参数的是使用的输出流,第二个参数是描述,默认使用ISO-8859-1,描述信息不要写中文OutputStream os = new FileOutputStream("info.txt");p.store(os, "name,birthday");}}
IO_25_Properties2.java

import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.util.Properties;/** * 读取配置文件中jhz的登录次数,并+1后重新保存进配置文件. * @author Administrator * */public class IO_25_Properties2 {public static void main(String[] args) throws IOException {Properties p = new Properties();FileInputStream fis = new FileInputStream("info.txt");//从输出流中读取属性列表ISO8859-1p.load(fis);//读取并将登录次数加1String property = p.getProperty("jhz");int value = Integer.parseInt(property)+1;p.setProperty("jhz",value+"");FileOutputStream fos = new FileOutputStream("info.txt");p.store(fos, "name,Logintimes");fis.close();fos.close();}}
PrintStream打印流:可以直接操作输入流和文件

提供了多种不同数据的print方法,并可以保持数据的原有形式,不抛异常.

当想保持数据原样写入时使用PrintStream最方便

构造函数

PrintStream(String s);

PrintStream(File f);

PrintStream(OutputStream os);

write(int i):此方法向输出流写入一个字节,要写入的是i的八个低位,24个高位将被忽略. 所以i=97和i=609输出的都是a.

print(各种参数):原样打印


IO_26_PrintStream.java

import java.io.IOException;import java.io.PrintStream;public class IO_26_PrintStream {public static void main(String[] args) throws IOException {PrintStream ps = new PrintStream("a.txt");ps.write(609);ps.write(97);ps.print(97);ps.print("aaa");ps.print(1.256);ps.close();//打印结果aa97aaa1.256}}

PrintWriter:打印流

构造函数:

PrintWriter(String s):

PrintWriter(File f):

PrintWriter(OutputStream os):

PrintWriter(Writer w):


IO_27_PrintWriter.java

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;public class IO_27_PrintWriter {public static void main(String[] args) throws IOException {//为true则自动刷新,不用调用flushBufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));PrintWriter pw = new PrintWriter(System.out,true);String line=null;while(!"over".equals(line=bufr.readLine())){pw.println(line);}pw.close();}}


SequenceStream序列流.对多个流进行合并

SequenceInputStream:

SequenceInputStream(Enumeration<?>InputStream):

read(byte[] b):


IO_28_SequenceInputStream_Enum.java

import java.io.BufferedOutputStream;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 IO_28_SequenceInputStream_Enum {/** * 将1.txt,2.txt,3.txt中的数据写入4.txt中 * Vector的elements方法可以得到枚举. * @param args * @throws IOException */public static void main(String[] args) throws IOException {Vector<FileInputStream> inputStreams = new Vector<FileInputStream>();inputStreams.add(new FileInputStream("1.txt"));inputStreams.add(new FileInputStream("2.txt"));inputStreams.add(new FileInputStream("3.txt"));Enumeration<FileInputStream> en = inputStreams.elements();//SequenceInputStream参数是枚举类型,通过vector.elements获得.SequenceInputStream sis = new SequenceInputStream(en);BufferedOutputStream bufw = new BufferedOutputStream(new FileOutputStream("4.txt"));byte[] b = new byte[1024];int len = 0;while((len=sis.read(b))!=-1){bufw.write(b, 0, len);bufw.flush();}sis.close();bufw.close();}}
IO_29_SequenceInputStream_Enum2.java

import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.SequenceInputStream;import java.util.ArrayList;import java.util.Collections;import java.util.Enumeration;public class IO_29_SequenceInputStream_Enum2 {public static void main(String[] args) throws IOException {/** * Vector效率较低,可以使用ArrayList,使用Collections的Enumeration方法获得该集合(ArrayList)的枚举 */ArrayList<InputStream> al = new ArrayList<InputStream>();al.add(new FileInputStream("1.txt"));al.add(new FileInputStream("2.txt"));al.add(new FileInputStream("3.txt"));Enumeration<InputStream> en = Collections.enumeration(al);SequenceInputStream sis = new SequenceInputStream(en);FileOutputStream fos = new FileOutputStream("4.txt");int len = 0;byte[] b = new byte[1024];while((len = sis.read(b))!=-1){fos.write(b,0,len);}sis.close();fos.close();}}

应用:文件切割器.输入流一个,输出流在每次循环时指定切割成的文件名即可.

IO_30_FileCutter.java

import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.util.Properties;public class IO_30_FileCutter {public static void main(String[] args) throws IOException {//参数为切割的的文件路径fileCutter(new File("1.txt"));}private static void fileCutter(File file) throws IOException {//切割的文件fileFileInputStream fis = new FileInputStream(file);//按1M为单位切割.byte[] b = new byte[1024];//保存在哪个文件夹下,不存在该文件夹则创建File dir = new File("c:\\Filecutter");if(!dir.exists()){dir.mkdir();}int len=0;//计数器,用于按顺序记录切割的每一份,便于之后合并.int count = 1;FileOutputStream fos = null;while((len=fis.read(b))!=-1){//使用new File(File parent,String child)构造指定切割到的文件夹,保存在C:\Filecutter下;fos = new FileOutputStream(new File(dir,(count++)+".part"));fos.write(b,0,len);}//建立配置文件,以保存切割信息(原文件名,切割份数等),保存在C:\Filecutter下Properties p = new Properties();fos = new FileOutputStream(new File(dir,(count)+".properties"));p.setProperty("fileName", file.getName());p.setProperty("fileParts", count-1+"");p.store(fos, "file properties info");//关闭流fis.close();fos.close();}}


文件合并--使用SequenceInputStream

IO_31_File_Merge.java

import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.FilenameFilter;import java.io.IOException;import java.io.InputStream;import java.io.SequenceInputStream;import java.util.ArrayList;import java.util.Collections;import java.util.Enumeration;import java.util.Properties;public class IO_31_File_Merge implements FilenameFilter{private static String suffix;public IO_31_File_Merge(String suffix) {super();this.suffix = suffix;}public static void main(String[] args) throws IOException {FileMerge(new File("c:\\Filecutter"));   }private static void FileMerge(File file) throws IOException {String[] list = file.list(new IO_31_File_Merge(".properties"));String property = list[0];FileInputStream fis = new FileInputStream(file+"\\"+property);Properties p = new Properties();p.load(fis);String fileName = p.getProperty("fileName");int fileParts = Integer.parseInt(p.getProperty("fileParts"));ArrayList<InputStream> al = new ArrayList<InputStream>();for (int i = 1; i <= fileParts; i++) {al.add(new FileInputStream(new File(file,i+".part")));}Enumeration<InputStream> en = Collections.enumeration(al);SequenceInputStream sis = new SequenceInputStream(en);FileOutputStream fos = new FileOutputStream(new File(file,fileName)); byte[] b = new byte[1024];int len = 0;while((len=sis.read(b))!=-1){fos.write(b,0,len);}sis.close();fos.close();}@Overridepublic boolean accept(File dir, String name) {return name.endsWith(suffix);}}
对象的序列化 ObjectOutputStream.writeObject()

对象的反序列化 ObjectInputStream.readObject()

序列化是流功能的拓展,所以接收一个InputStream和OutputStream对象.正如缓冲流和转换流,也需要接收对象,都是其他流结合使用的.

IO_32_serializable.java

import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;public class IO_32_serializable{public static void main(String[] args) throws IOException, ClassNotFoundException{serialize(new IO_33_bean(1,"lj","haha"));oppoSerialize("obj.object");}private static void oppoSerialize(String file) throws IOException, ClassNotFoundException {//对象的反序列化.读取使用ObjectOutputStream已经保存在硬盘上的对象ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));IO_33_bean person = (IO_33_bean) ois.readObject();System.out.println(person.getId());//1System.out.println(person.getName());//ljSystem.out.println(person.getPassword());//nullois.close();}private static void serialize(IO_33_bean person) throws IOException {//对象的序列化:将对象存储到硬盘上延长它的生命周期.该对象必须先实现Serializable接口//使用ObjectOutputStream类的writeObject方法存储. 存储文件的扩展名为.objectObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.object"));oos.writeObject(person);oos.close();}}


需要序列化的对象对应的类---数据库对象和具有特殊数据的对象可以使用序列化保存.并不是所有对象都可以被序列化,如Socket对象就不行

IO_33_bean.java

import java.io.Serializable;public class IO_33_bean implements Serializable{/** * 序列化强烈建议加入UID,以判断.object文件与类文件是不是同一个.只要id一样,就可以反序列化, * 否则可能出现InvalidClassException异常,该id的访问修饰符ACCESS MODIFIER可以为任意. * 静态属性不在堆中,不能进行序列化.不想被序列化的属性可以用transient标识为瞬态的,则不被存储. */private static final long serialVersionUID = 1L;private int id;private String name;private transient String password;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public static long getSerialversionuid() {return serialVersionUID;}public IO_33_bean(int id, String name, String password) {super();this.id = id;this.name = name;this.password = password;}}
随机访问文件对象RandomAccessFile

IO_34_RandomAccessFile.java

import java.io.IOException;import java.io.RandomAccessFile;public class IO_34_RandomAccessFile {/*RandomAccessFile * 1.不是既能读,又能写.其实内部封装了字节输入输出流. * 2.内部维护了一个byte数组,并用一个指针,通过seek方法设置指针位置.通过getFilePointer方法获取指针位置. * 3.与流对象存取不同,它可以从任意位置存取,多线程方式有些操作就是用的该类,应用比如视频断点续传. */public static void main(String[] args) throws IOException {readFile();writeFile();}private static void writeFile() throws IOException {RandomAccessFile raf = new RandomAccessFile("random.txt", "rw");raf.write("张三".getBytes());//2个中文占4个字节raf.writeInt(99);//使用4个字节存储int对象System.out.println(raf.getFilePointer());//8raf.seek(2*8);//从第16个字节开始写raf.write("李刚".getBytes());raf.writeInt(100);//记事本解析为:张三   c        李刚   d//数据c和d没错,因为记事本用GBK解析了raf.close();}private static void readFile() throws IOException {RandomAccessFile raf = new RandomAccessFile("random.txt", "rw");byte[] b = new byte[8];raf.read(b);System.out.println(new String(b));//张三   cSystem.out.println(raf.getFilePointer());//8raf.seek(16);raf.read(b);System.out.println(new String(b));//李刚   d}}
管道流--常用于多线程--输出的内容只能有自己获取

IO_35_PipedInputStream_PipedOutputStream.java

import java.io.IOException;import java.io.PipedInputStream;import java.io.PipedOutputStream;public class IO_35_PipedInputStream_PipedOutputStream {/** * 管道流,输出流写的数据只能输入流读.需要连接输入流和输出流.使用PipedInputStream的connect方法 * 一般使用多线程执行,否则可能造成死锁. */public static void main(String[] args) throws IOException {PipedOutputStream pos = new PipedOutputStream();PipedInputStream pis = new PipedInputStream();pis.connect(pos);Input input = new Input(pis);Output output = new Output(pos);Thread t1 = new Thread(input);Thread t2 = new Thread(output);t1.start();t2.start();}}class Input implements Runnable{private PipedInputStream pis;public Input(PipedInputStream pis) {this.pis = pis;}@Overridepublic void run() {byte[] b = new byte[1024];try {int len = pis.read(b);System.out.println(new String(b,0,len));//泥濠啊大哥} catch (IOException e) {e.printStackTrace();}}}class Output implements Runnable{private PipedOutputStream pos;public Output(PipedOutputStream pos) {this.pos = pos;}@Overridepublic void run() {try {pos.write("泥濠啊大哥".getBytes());} catch (IOException e) {e.printStackTrace();}}}
DataInputStream,DataOutputStream操作基本数据类型,构造函数接收流字节参数

在存取基本数据类型时使用.

IO_36_DataInputStream_DateOutputStream.java

import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class IO_36_DataInputStream_DateOutputStream {public static void main(String[] args) throws IOException {read();write();}private static void write() throws IOException {DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));dos.writeUTF("66666哈哈");dos.writeInt(999);}private static void read() throws IOException {DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));byte[] b = new byte[1024];int len = dis.read(b);System.out.println(new String(b,0,len));//wirteUTF存储的只有readUTF可以取出来dis.close();}}

操作数组的流:源或者目的是[内存]时使用该流.

操作字节数组ByteArrayInputStream,ByteArrayOutputStream

操作字符数组ChaArrayReader,CharArrayWriter,  

操作字符串数组StringReader,StringWriter


IO_37_ByteArrayInputStream_ByteArrayOutputStream.java

import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;public class IO_37_ByteArrayInputStream_ByteArrayOutputStream {public static void main(String[] args) {ByteArrayInputStream bis = new ByteArrayInputStream("哈哈".getBytes());//ByteOutputStream内部维护了一个数组,缓冲区随输入的写入自动增长,使用toString方法可以将缓冲区里的内容转换为字符串.ByteArrayOutputStream bos = new ByteArrayOutputStream();int i = 0;while((i=bis.read())!=-1){bos.write(i);}System.out.println(bos.toString());//哈哈}}










0 0
原创粉丝点击