java中把一组有序的数据序列称为流,根据操作类型可以分为输入流和输出流。
程序从输入流中读取数据,从输出流中写入数据。
文件:是相关记录或者是放在一起数据集合。
File类仅仅用来描述File对象的属性,他并不说明数据是如何存储的。
例如:
import java.io.File;
import java.io.IOException;
public class FileDemo {
public static void main(String[] args) throws IOException {
//查看文件属性
File f1 = new File("c:\\myDoc", "hello.txt");
System.out.println("文件名:" + f1.getName());
System.out.println("路径:" + f1.getPath());
System.out.println("绝对路径:" + f1.getAbsolutePath());
System.out.println(f1.exists() ? "文件存在" : "文件不存在");
System.out.println(f1.isDirectory() ? "文件是目录" :"文件不是目录");
System.out.println(f1.isFile() ? "文件是普通文件" :"文件可能是命名管道");
if (f1.canRead()){
System.out.println("可以读取此文件");
}else {
System.out.println("不能读取此文件");
}
if (f1.canWrite()){
System.out.println("可以写入到此文件");
}else {
System.out.println("不能写入此文件");
}
System.out.println("此文件最后修改时间是2000年1月1日后的" +f1.lastModified() + "秒");
//创建和删除文件
FileDemo fm=new FileDemo();
File f = new File("c:\\myDoc\\test.txt");
fm.create(f);
fm.delete(f1);
File dir = new File("c:\\myDoc");
fm.listDir(dir);
}
//创建文件
public void create(File file) throws IOException{
if(!file.exists()){
file.createNewFile();
}
}
//删除文件
public void delete(File file){
if(file.exists()){
file.delete();
}
}
//查看目录信息
public void listDir(File dir){
File[] lists=dir.listFiles();
//打印当前目录dir的所有子目录和文件
String info="目录信息为:"+dir.getName()+"\\";
for(int i=0;i<lists.length;i++){
info+=lists[i].getName()+"\\";
}
System.out.print(info);
}
}
流是指一连串流动的字符,以先进先出的方式发送或接受数据的通道,一个流是一个输入设备或者输出设备的抽象表示。
按照流的方向划分,分为输入流和输出流,输入流只能从中读取信息,而不能从中写入数据;输出流只能从中写入信息而不能从中读出信息。
输出流以OutputStream和Writer为基类,输入流以InputStream和Read为基类。
按照所操作数据单元不同分为字符流和字节流。
字节流操作的最小数据单元是8位的字节,字符流操作的最小数据单元是16位的字符。
字节流以OutputStream和ImputStream为基类,字符流以Writer和Reader为基类。一般情况下字节流建议用于二进制数据,而字符流用于文本。
结合按照流方向划分可分为:字节输入流(以InputStream为基类),字节输出流(以OutputStream为基类),字符输入流(以Reader为基类),字符输出流(以Writer为基类)。
无论是输出流还是输入流,最后都要执行关闭流的操作。因为输入输入流不属于内存资源,如果不关闭,则资源将会一直被占用,同时无法对该文件进行下一步操作。
FileInputStream文件输入流,他的作用是将文件中的数据输入到内存中,也就是读取文件。他是字节输入流InputStream的子类。
FileOutputStream文件输出流,他的作用是把内存中的数据输出到文件中,他是字节输出流OutputStream的一个子类。
public class FileInputStreamDemo {
public static void main(String[] args) {
try {
FileInputStream fis = new FileInputStream(new File("f:\\新建文本文档.txt"));
int data;
System.out.println("可读取的字节数:"+fis.available());
System.out.println("读取到的字节为:");
while((data = fis.read())!=-1)
System.out.print(data+" ");
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class FileOutputStreamDemo {
public static void main(String[] args) {
String str = "要想文件中写入的内容!";
byte[] bytes = str.getBytes();<pre name="code" class="java"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="white-space:pre"> </span> try {</span>
FileOutputStream fos = new FileOutputStream(new File("f:\\新建文本文档.txt"));fos.write(bytes);fos.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}
BufferedReader带有缓冲区,他可以先把一批数据读到缓冲区,接下来的操作都是从缓冲区中获取数据。
为了提高下来BufferedReader通常与InputStreamReader(直接子类为FileReader)连用。
BufferWriter与OutputStreamWriter(直接子类为FileWriter)连用。
例如:
public class BufferedReaderDemo {
public static void main(String[] args) {
FileReader fr;
try {
fr = new FileReader(new File("f:\\新建文本文档.txt"));
BufferedReader br = new BufferedReader(fr);
String s = br.readLine();
System.out.println(s);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class BufferedWriterDemo {
public static void main(String[] args) {
try {
FileWriter fw = new FileWriter("f:\\a.txt");
BufferedWriter bw = new BufferedWriter(fw);
String s = "BufferedWriterDemo";
bw.write(s);
bw.flush();
bw.close();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
DataInputStream和DataOutputStream搭配使用可以按照与平台无关的方式从流中读取基本数据。
具体使用方法如下:
public class DataInputStreamDemo {
public static void main(String[] args) throws Exception {
FileInputStream fis = new FileInputStream(new File("bin\\server.class"));
DataInputStream dis = new DataInputStream(fis);
FileOutputStream fos = new FileOutputStream(new File("bin\\temp.class"));
DataOutputStream dos = new DataOutputStream(fos);
int temp;
while((temp = dis.read())!=-1){
dos.write(temp);
}
dos.close();
fos.close();
dis.close();
fis.close();
}
}
public class WriteAndRead {
public static void main(String[] args) {
try {
FileOutputStream fos = new FileOutputStream(new File("f:\\ab.doc"));
BufferedOutputStream bos = new BufferedOutputStream(fos);
DataOutputStream dos = new DataOutputStream(bos);
dos.writeBoolean(false);
dos.writeByte(1);
dos.writeChar('a');
dos.writeUTF("写入字符串!");
dos.writeDouble(1.23);
dos.close();
dos.close();
fos.close();
FileInputStream fis = new FileInputStream(new File("f:\\ab.doc"));
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
System.out.println(dis.readBoolean());
System.out.println(dis.readByte());
System.out.println(dis.readChar());
System.out.println(dis.readUTF());
System.out.println(dis.readDouble());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
下面看一个复制文件的小例子:
public class CopyTest {
public static void main(String[] args) {
File inFile = new File("c:\\awx.txt");
File outFile = new File("f:\\copy.txt");
BufferedWriter bw = null;
BufferedReader br = null;
System.out.println("开始复制!");
FileReader fr;
try {
fr = new FileReader(inFile);
br = new BufferedReader(fr);
FileWriter fw = new FileWriter(outFile);
bw = new BufferedWriter(fw);
String line;
while((line = br.readLine())!=null){
bw.write(line);
bw.newLine();
}
System.out.println("复制完成!");
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("未找到目标文件!");
} catch (IOException e) {
e.printStackTrace();
System.out.println("输入输出流异常!");
}finally{
try {
br.close();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
序列化,将一个java对象借助I/O流的形式,实现数据的传输或保存。
简单的说,序列化就是将对象的状态存储到特定的存储介质中的过程,也可以说是,将对象状态转换为可保存状态或可传输状态。
序列化过程中将对象的公有成员,私有成员包括类名,都转换成字节流,然后再把字节流写入数据流,存储到存储介质。
序列化机制允许将实现序列化的java对象转化成字节序列,这些字节序列可以被保存到磁盘或者在网络中传输。
序列化机制使得对象可以脱离程序而独立存在。
java中要求实现了java.io.Serializable这个接口的类的对象才能被序列化。
对象序列化的步骤:
1、创建对象输出流ObjectOutputStream
2、通过对象输出流的writeObject方法写对象,也就是输出可序列化的对象。
对象反序列化的步骤:
1、创建一个对象输入流ObjectInputStream
2、通过对象输入流的readObject方法读取对象
注意:
1、反序列化过程不需要使用构造器生成对象。
2、按顺序反序列化对象恢复对象。
3、父类Serizable或存在无参构造方法。
使用transient来禁止序列化某些敏感信息。
例如:
public class Teacher implements Serializable {
private static final long serialVersionUID = -3937694213354916786L;
private String name;
private int age;
private String gender;
private transient String password;
public Teacher(String name,int age,String gender,String password){
this.name = name;
this.age = age;
this.gender = gender;
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
public class TSerizableDemo {
public static void main(String[] args) {
ObjectInputStream ois = null;
ObjectOutputStream oos = null;
try {
ois = new ObjectInputStream(new FileInputStream(new File("e:\\serizable.txt")));
oos = new ObjectOutputStream(new FileOutputStream(new File("e:\\serizable.txt")));
Teacher tea = new Teacher("张", 34, "男", "1234");
oos.writeObject(tea);
Teacher teacher = (Teacher) ois.readObject();
System.out.println(teacher.getName());
System.out.println(teacher.getAge());
System.out.println(teacher.getGender());
System.out.println(teacher.getPassword());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}