最近,将java基础视频IO流的部分看完了,于是我在这里总结一下,学习IO流的基础知识。
javaIO流的选取规则
这篇文章涉及的主要内容如下:
File
Properties
PrintWriter 与 PrintStream (打印流)
SequenceInputStream(序列流)
分割mp3的小程序
ObjectInputStream与ObjectOutputStream
RandomAccessFile
DataInputStream 与 DataOutputStream
ByteArrayInputStream 与 ByteArrayOutputStream
File的简单总结:
1,构造方法
//构造方法一
File f1 = new File("xxx.txt");
//构造方法二
File f = new File("c://");
File f2 = new File(f1, "xxx.txt");
//构造方法三
File f3 = new File("c://", "xxx.txt");
2,相关简单方法
//和输出流不一样,如果没有则创建的 ,如果有不会创建
File file = new File("file.text");
//创建文件
boolean b = file.createNewFile();
File file_1 = new File("c:\\a\\b");
//用于创建多级目录
file_1.mkdirs();
System.out.println(b);
// file.mkdir(); 创建单级目录
File f4 = new File("xxx.txt");
f4.isDirectory();//判断是否为文件夹
f4.isFile();//判断是否为文件
File f5 = new File("c://");
File[] files = f5.listFiles();//返回在"c://"目录下,所有的文件和文件夹
String[] fileName = f5.list();//返回在"c://"目录下,所有的文件和文件夹
3,文件过滤器,需要实现两个接口 FileFilter 和 FilenameFilter
相关例子如下:
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
class SuffixNameFilter implements FilenameFilter{
private String suffix = null;
public SuffixNameFilter(String suffix) {
super();
this.suffix = suffix;
}
//用于过滤后缀名
@Override
public boolean accept(File dir, String name) {
return name.endsWith(suffix);
}
}
class Filter implements FileFilter{
//用于过滤掉隐藏文件
@Override
public boolean accept(File pathname) {
return pathname.isHidden();
}
}
public class FileDemo {
public static void main(String[] args) {
File f = new File("c://");
//用于过滤掉隐藏文件
File[] files = f.listFiles(new Filter());
for(File file : files) {
System.out.println(file.getName());
}
//用于过滤后缀名
String[] fileName = f.list(new SuffixNameFilter(".txt"));
for(String name : fileName) {
System.out.println(name);
}
}
}
4,深度遍历在某目录下的所有文件(递归)
import java.io.File;
public class FileDemo {
public static void main(String[] args) {
File f = new File("E:\\大二上学期作业");
depth(f);
}
private static void depth(File f) {
// TODO Auto-generated method stub
File[] files = f.listFiles();
if(files == null)
return ;
for(File file : files) {
if(file.isFile())
System.out.println(file.getAbsolutePath());
else {
depth(file);
}
}
}
}
Properties的简单总结:
Map
|–Hashtable
|–Properties:
Properties集合:
特点:
1,该集合中的键和值都是字符串类型。
2,集合中的数据可以保存到流中,或者从流获取。
通常该集合用于操作以键值对形式存在的配置文件。
1,存储元素,读取元素
//存储元素
prop.setProperty("cxf", "20");
prop.setProperty("qwe", "20");
prop.setProperty("asd", "20");
//读取元素
Set<String> keys = prop.stringPropertyNames();
Iterator<String> it = keys.iterator();
while(it.hasNext()) {
String key = it.next();
String value = prop.getProperty(key);
System.out.println(key+"::"+value);
}
2,propeties与流相结合(持久性)
Properties prop = new Properties();
prop.setProperty("cxf", "20");
prop.setProperty("qwe", "20");
prop.setProperty("asd", "20");
//通常用于调试
//在控制台上显示prop里面包含的内容
prop.list(System.out);
BufferedWriter bufw = new BufferedWriter(new FileWriter("XXX.txt"));
//将prop的键值对信息保存在硬盘上
prop.store(bufw, null);
Properties prop_1 = new Properties();
BufferedReader bufr = new BufferedReader(new FileReader("xxx.txt"));
//将硬盘的信息读取到prop_1当中
prop_1.load(bufr);
PrintWriter 与 PrintStream(打印流)的简单总结:
相关举例:
PrintStream:
import java.io.IOException;
import java.io.PrintStream;
public class PrintStreamDemo {
public static void main(String args[]) throws IOException {
/*
* PrintStream:
* 1,提供了打印方法可以对多种数据类型值进行打印。并保持数据的表示形式。
* 2,它不抛IOException.
*
* 构造函数,接收三种类型的值:
* 1,字符串路径。
* 2,File对象。
* 3,字节输出流。
*/
PrintStream out = new PrintStream("print3.text");
//out.write(257); //先变成二进制数,然后取二进制数的后八位。
out.println(45646); //原理是现将数字转换成字符窜然后在存放在里面。
out.close();
}
}
PrintWriter:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class PrintWriterDemo {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
/*
* PrintWriter:字符打印流。
* 构造函数参数:
* 1,字符串路径。
* 2,File对象。
* 3,字节输出流。
* 4,字符输出流。
*
*/
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out,true);
String line = null;
while((line = bufr.readLine()) != null) {
if(line.equals("over"))
break;
out.println(line);
}
bufr.close();
out.close();
}
}
SequenceInputStream的简单总结:
就是:可以将几个流连在一起,共同操作:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
public class SequenceDemo {
public static void main(String[] args) throws IOException {
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
al.add(new FileInputStream("1.txt"));
al.add(new FileInputStream("2.txt"));
al.add(new FileInputStream("3.txt"));
al.add(new FileInputStream("4.txt"));
//将集合转换为枚举
Enumeration<FileInputStream> en = Collections.enumeration(al);
SequenceInputStream sis = new SequenceInputStream(en);
byte[] buf = new byte[1024];
int len = 0;
while((len = sis.read(buf)) != -1) {
System.out.println(new String(buf,0,len));
}
sis.close();
}
}
接着我们做一个有意思的小东西,将一个mp3文件分割成几个我们指定类型的文件然后将其保存在一个文件夹中,然后我们在将分割的文件重新组合起来形成mp3,并将其保存在指定路径下。
创建SplitFile类:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
public class SplitFile {
final static int SIZE = 1024 * 1024;
public static void main(String[] args) throws IOException {
File f = new File("c://aa.mp3");
split(f);
}
private static void split(File f) throws IOException {
File dir = new File("g://partfiles");
if(!dir.exists())
dir.mkdirs();
//读取文件
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f));
//保存文件
BufferedOutputStream bos = null;
//定义 1M的空间
byte[] buf = new byte[SIZE];
int count = 0;
int len = 0;
while((len = bis.read(buf)) != -1) {
bos = new BufferedOutputStream(new FileOutputStream(new File(dir,(++count)+".part")));
bos.write(buf, 0, len);
bos.close();
}
//设置配置文件
bos = new BufferedOutputStream(new FileOutputStream(new File(dir,"info.properties")));
Properties prop = new Properties();
prop.setProperty("filename", f.getName());
prop.setProperty("count", String.valueOf(count));
prop.store(bos, null);
bos.close();
bis.close();
}
}
创建MergeFile类:
import java.io.BufferedOutputStream;
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;
public class MergeFile {
final static int SIZE = 1024 * 1024;
public static void main(String[] args) throws IOException {
File f = new File("g://partfiles");
merge(f);
}
private static void merge(File f) throws IOException {
File[] files = f.listFiles(new SuffixFilter(".properties"));
if(files == null)
throw new RuntimeException("properties文件不存在");
FileInputStream fis = new FileInputStream(files[0]);
Properties prop = new Properties();
prop.load(fis);
fis.close();
String filename = prop.getProperty("filename");
int count = Integer.parseInt(prop.getProperty("count"));
files = f.listFiles(new SuffixFilter(".part"));
if(count != files.length)
throw new RuntimeException("分割后的文件数目不对");
for(int i= 1;i<= count;i++) {
if(!files[i-1].getName().contains(String.valueOf(i))) {
throw new RuntimeException("缺少第"+i+"个文件");
}
}
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
for(int i=1;i<=count;i++) {
al.add(new FileInputStream(files[i-1]));
}
Enumeration<FileInputStream> en = Collections.enumeration(al);
SequenceInputStream sis = new SequenceInputStream(en);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(f,filename)));
byte[] buf = new byte[SIZE];
int len = 0;
while((len = sis.read(buf)) != -1) {
bos.write(buf, 0, len);
}
sis.close();
bos.close();
}
}
创建SuffixFilter类:
import java.io.File;
import java.io.FilenameFilter;
public class SuffixFilter implements FilenameFilter {
private String suffix = null;
public SuffixFilter(String suffix) {
super();
this.suffix = suffix;
}
@Override
public boolean accept(File dir, String name) {
// TODO Auto-generated method stub
return name.endsWith(suffix);
}
}
ObjectInputStream与ObjectOutputStream的简单总结:
要想类能够序列化,那么每个类需要实现接口Serializable
Serializable的作用:
Serializable用于给被序列化的类加入ID号
用于判断类和对象是否是同一个版本。
如果想让非静态数据不被序列化可使用关键字transient
代码:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
class Person implements Serializable{
/**
* 设置版本ID
*/
private static final long serialVersionUID = 789565465461321l;
String name = null;
String age = null;
public Person(String name, String age) {
super();
this.name = name;
this.age = age;
}
public String toString() {
return name+":::"+age;
}
}
public class ObjectStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
writeObject();
readObject();
}
private static void readObject() throws IOException, ClassNotFoundException {
//装饰设计模式
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));
Person p = (Person)ois.readObject();
System.out.println(p.toString());
ois.close();
}
private static void writeObject() throws IOException{
//装饰设计模式
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));
Person p = new Person("cxf","20");
oos.writeObject(p);
oos.close();
}
}
RandomAccessFile的简单总结:
特点:
1,该对象即能读,又能写。
2,该对象内部维护了一个byte数组,并通过指针可以操作数组中的元素,
3,可以通过getFilePointer方法获取指针的位置,和通过seek方法设置指针的位置。
4,其实该对象就是将字节输入流和输出流进行了封装。
5,该对象的源或者目的只能是文件。通过构造函数就可以看出。
import java.io.IOException;
import java.io.RandomAccessFile;
public class RandomAccessFileDemo {
public static void main(String[] args) throws IOException {
write();
read();
}
private static void read() throws IOException {
//设置为可读
RandomAccessFile raf = new RandomAccessFile("ranacc.txt","r");
//用于返回指针的位置
System.out.println(raf.getFilePointer());
//指针移动6的位置
raf.seek(1*6);
System.out.println(raf.getFilePointer());
byte[] buf = new byte[20];
int len = 0;
while((len = raf.read(buf)) != -1) {
System.out.print(new String(buf,0,len));
}
raf.close();
}
private static void write() throws IOException {
//如果文件不存在,则创建,如果文件存在,不创建
//设置为可读可写
RandomAccessFile raf = new RandomAccessFile("ranacc.txt","rw");
raf.write("陈薪帆".getBytes());
raf.write("阿萨德".getBytes());
raf.close();
}
}
DataInputStream 与 DataOutputStream的简单总结:
DataInputStream 与 DataOutputStream 主要用于操作基本数据类型
当我们想操作基本数据类型时,考虑装饰设计模式去进行处理。
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class DataStreamDemo {
public static void main(String[] args) throws IOException {
write();
read();
}
private static void read() throws IOException {
// TODO Auto-generated method stub
DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
String line = dis.readUTF();
System.out.println(line);
dis.close();
}
private static void write() throws IOException {
DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
//这里使用的是UTF-8修改版
dos.writeUTF("你好世界");
dos.close();
}
}
ByteArrayInputStream 与 ByteArrayOutputStream的简单总结:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
public class ByteArrayStreamDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
/*
* 用于操作内存,用于操作字节数组
*/
ByteArrayInputStream bis = new ByteArrayInputStream("asdasdasdasd".getBytes());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int ch = 0;
while((ch = bis.read()) != -1) {
bos.write(ch);
}
System.out.println(bos.toString());
}
}