输入流与输出流

来源:互联网 发布:nba历届全明星mvp数据 编辑:程序博客网 时间:2024/05/21 07:12
这里的输入与输出针对的都是程序,程序的输入与输出
(输入流)InputStream:
字节流:FileInputStream 、System.in         ——FileInputStream中有available()方法可获得文件的字节数
缓冲字节流:BufferedInputStream
字符流:FileReader、PrintReader
缓冲字符流:BufferedReader                ——存在readLine()方法可按行进行读取
字节流转化字节流输入桥梁:InputStreamReader
输出流)OutputStream:
字节流:FileOutputStream、System.out      ——FileOutputStream中有available()方法可获得文件的字节数
缓冲字节流:BufferedOutputStream
字符流:FileWriter、PrintWriter
缓冲字符流:BufferedWriter    ——存在readLine()方法可按行进行读取
字节流转化为字符流输出桥梁:OutputStreamWriter
文件过滤器:(接口)
FilenameFilter、FileFilter,
接口方法accept()中可以自行定义过滤规则;FilenameFilter的效率要高于FileFilter;
常用 dir.listFiles(new FilenameFilter())或者是dir.listFiles(FileFilter()) 两种使用前都要注意现在接口中实现自定义过滤规则。
打印流:(字符流)PrintWriter、PrintReader
特点:1、提供了打印方法可以对各种数据类型值进行打印。并保持数据的形式
2、它不抛出IOException
3、可以打印到文件中去、也可以打印到别的流中去。
4、write()方法只写二进制的最低八位。

序列流SequenceInputStream
它能将多个流进行序列化读取,它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止,需要注意的就是,当传入两个输入流的时候直接传参数即可,但是当需要传入多个流时,它的构造方法要求,先要将多个流封装成Enumeration<E>对象,然后将Enumeration对象当参数传入序列流的构造方法,常用的 封装Enumeration<E>方法是,先创建一个ArrayList()容器,然后将流对象添加到容器中,最后用Collections.enumeration(arr)方法将ArrayList转换成Enumeration<E>类型。

对象流:ObjectOutputStream、ObjectInputStream
通过在流中使用文件可以实现对象的持久存储,注意用ObjectOutputStream只能将实现序列化(实现serializable接口)的对象写入到流中,使用ObjectInputStream读取对象时,会自动将对象反序列化;注意:这里仅仅是吧对象的字节码写入到了硬盘中,如果没有class文件,是无法读出其对象的。

随机写入文件RandomAccessFile :这里的随机指的是自己可以操作写入的起始位置;
自身具备读写方法,而且可以操作基本数据类型;通过skipBytes(int x),和seek(int x)来达到随机写入文件的目的,

管道流(PipedStream):PipedInputStream、PipedOutputStream  
可以直接输入和输出连接直接调用read()or write()方法;但值得注意的是 管道输入流与管道输出流是连接使用的,一般用connect()方法进行连接,通常,数据由某个线程从 PipedInputStream 对象读取,并由其他线程将其写入到相应的 PipedOutputStream。不建议对这两个对象尝试使用单个线程,因为这样可能死锁线程;

操作数组的流:
字节数组:ByteArrayInputStream、ByteArrayOutputStream
字符数组:CharArrayReader、CharArrayWriter
字符串数组:StringReader、StringWriter
当需要把数据存到内存中去,或者是从内存中读取出来时,就用这两个流,这两个流的操作数据类型都不太大;

这些流的使用都是相互关联的:缓冲字节流——字节流(参数:文件名)、缓冲字符流——字符流(参数:文件名)、缓冲字符流——字节流转化字符流桥梁——字节流(参数:文件名)、对象流——File字节流(参数:文件名)

字符串用str.getBytes()可以得到该字符串的字节码;一个汉字占两个字节
所有的流用完后均需要关闭close();
除了字节流外的流的flush()方法均有作用;
字符流就是字节流+编码表,只不过是字符流的编码表是默认的,因此当需要用到指定编码表时就不能使用字符流;
字节流加入指定编码表的方法就是在参数中,文件名后跟上一个“UTF-8”/“GBK”即可;

这是一个比较常用的复制文件的方法:(其余都类似)

public static void input() throws IOException {
FileInputStream fis=new FileInputStream("d:\\1.avi");
BufferedInputStream bis=new BufferedInputStream(fis);
FileOutputStream fos=new FileOutputStream("D:\\2.avi");
BufferedOutputStream bos=new BufferedOutputStream(fos);
byte []a=new byte[1024];//方法一
int num;//返回的数组个数
while((num=bis.read(a))!=-1){
bos.write(a);
bos.flush();
}
//byte []a =new byte[fis.available()];//方法二
//bos.write(a);


//int num;//方法三
//while((num=bis.read())!=-1){
//bos.write(num);
//}
bos.close();
bis.close();


通过字节输入流在键盘上录入时:
1、 InputStrame in=System.in 
2、录入换行时,输入流保存的是两个字节码\r\n,它的值分别是:13、10
3、录入字节流读取的时候只能通过循环一个字节一个字节的读取,因此注意当输入换行时\r\n字节码的避让
4、录入信息的时候不能够自行结束,需要自定义结束方式(例如:当输入over的时候结束,然后在通过加入if判断语句来实现它)
事例:将输入的字符转换成大写的字符串

InputStream a = System.in;;
StringBuilder str =new StringBuilder();
int num;
while(( num=a.read())!=-1){
if(num=='\r')
continue;
if(num=='\n'){
String temp=str.toString();
System.out.println(temp.toUpperCase());
str.delete(0, str.length());
if("over".equals(temp)){
break;
}
}else{
str.append((char)num);
}
}
a.close();
}



综合练习:实现一个文件切割器,能够将文件分成切割成小文件,进行保存。要求,存在配置文件,保存切割前文件名和切割后的文件个数

package com.king.splitfile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Properties;

public class SplitFile {
public static void main(String []args) throws IOException{
File aim=new File("D:\\1.jpg");
int length=1024*1024;
File dest=new File("D:\\splitFile");
if(!dest.exists()){
dest.mkdir();
}
splitFile(aim, length, dest);
}
/**
* 创建方法实现对文件的分割传入参数:源文件,分割大小,目的地目录
* @param file
* @param length
* @param dest
* @throws IOException
*/

public static void splitFile(File file,int length,File dest) throws IOException {
FileInputStream fis=new FileInputStream(file);
//ArrayList<FileOutputStream> arr=new ArrayList<FileOutputStream>();
FileOutputStream fos;
byte[] size=new byte[length];
int num=0;
int count=0;
while((num=fis.read(size))!=-1){
fos=new FileOutputStream(new File(dest,count+".part"));
fos.write(size);
fos.close();
count++;
}
fis.close();

Properties pop=new Properties(); //创建配置信息,用来储存分割前的名字
pop.setProperty("name", file.getName());
pop.setProperty("part", count+"");
pop.store(new FileOutputStream(new File(dest,"split.properties")), "");

}


}


实现一个文件合并器,能够将切割的文件合并成原来的文件。

package com.king.splitfile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Properties;

import com.king.splitfile.util.SuffixFilter;

public class MergeFile {

public static void main(String[] args) throws IOException {
File aim=new File("D:\\splitFile");
File dest =new File("D:\\splitFile");
if(!dest.exists()){
dest.mkdir();
}
mergeFile(aim, dest);

}

public static void mergeFile(File aim,File dest) throws IOException {
ArrayList<FileInputStream> arr=new ArrayList<FileInputStream>();//创建容器存放连接切割文件的流
FileInputStream fis = null;//连接配置文件的流
SuffixFilter sf=new SuffixFilter(".part");//文件名筛选器
//运用迭代将目标目录进行分类连接
File []list=aim.listFiles(sf);

for(int i=0;i<list.length;i++){
arr.add(new FileInputStream(list[i]));
}

File[] pro=aim.listFiles(new SuffixFilter(".properties"));
fis=new FileInputStream(pro[0]);

//加载配置文件
Properties pop=new Properties();
pop.load(fis);
int part=Integer.parseInt(pop.getProperty("part"));
//检查分割文件与配置文件中的数量是否相符
if(part!=arr.size()){
System.out.println("分割文件数量不对!!");
}else{
//将连接不同文件的分割流加入到SequenceInputStream流中
Enumeration<FileInputStream> en=Collections.enumeration(arr);

SequenceInputStream sis=new SequenceInputStream(en);
//将流写出到合并文件中去
FileOutputStream fos=new FileOutputStream(new File(dest,pop.getProperty("name")));
byte [] b=new byte[1024];
int num=0;
while((num=sis.read(b))!=-1){
fos.write(b,0,b.length);
fos.flush();
}
sis.close();
fos.close();

}
fis.close();
}


}







0 0
原创粉丝点击