1.Java中如何实现序列化,有什么意义?
(1)序列化是一种处理Java对象流的机制。Java对象流是将对象进行流化。序列化可以将流化后的对象进行读写操作,除此以外还可以将流化后的对象存储在磁盘中或者在网络上传输,当需要从该Java对象流中读出对象时,就成为反序列化,可以将对象流其还原为Java对象。序列化是为了解决对象流读写操作时可能出现的问题(如果不进行序列化,则会导致数据存在乱序问题)
(2)实现对象的序列化和反序列化的前提有以下几点:
①必须实现可序列化接口Serializable
②序列化类中需要提供属性public static final long serialVersionUID;
③序列化类中的属性也必须是可序列化的。
④static transient修饰的属性不能被序列化
(3)使用ObjectInputStream中的writeObject()方法将可序列化Java对象文件写出(保存其状态)
使用ObjectOutputStream中的readObject方法将序列化的对象读出并还原
(4)序列化除了能够实现对象的持久化之外,还可以用于对象的深度克隆。
Transient
1>在变量声明前加上Transient 关键字,可以阻止该变量被序列化到文件中,在被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null。
2>服务器端给客户端发送序列化对象数据,对象中有一些数据是敏感的,比如密码字符串 等,希望对该密码字段在序列化时,进行加密,而客户端如果拥有解密的密钥,只有在 客户端进行反序列化时,才可以对密码进行读取,这样可以一定程度保证序列化对象的 数据安全。
public class Person implements Serializable {
public static final long serialVersionUID = 1233311238422L;
private String name;
private int age;
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
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;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
public class ObjectInputOutputStreamTest {
/*
* 序列化过程:将内存中的Java对象保存到磁盘或通过网络传输出去
* 使用ObjectOutputStream实现
* */
@Test
public void testObjectOutputStream(){
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("E:\\Workpace\\JavaIO\\src\\object.dat"));
oos.writeObject(new String("helloWorld"));
oos.flush();//刷新操作
oos.writeObject(new Person("张三",12));
oos.flush();//刷新操作
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(oos != null){
try {
oos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
@Test
public void testObjectInputStream(){
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("E:\\Workpace\\JavaIO\\src\\object.dat"));
String str = (String)ois.readObject();
System.out.print(str);
Person person = (Person)ois.readObject();
System.out.print(person);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(ois != null){
try {
ois.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
2.Java中有几种类型的流?
(1)Java中的所有流都是通过继承以下四个基类:InputStream OutputStream Reader Writer.其中用于字节流的输入输出的是InputStream OutputStream。用于字符流输入输出的是Reader Writer。
(2)关于Java I/O需要注意的有两点:
一是两种对称性(输入输出的对称性,二是字节流和字符流的对称性)
二是两种设计模式:适配器模式和装横模式
(3)实现文件拷贝
public class BufferedTest {
@Test
public void test1(){
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
File srcFile = new File("E:\\Workpace\\JavaIO\\src\\QQ图片20191224174151.jpg");
File destFile = new File("E:\\Workpace\\JavaIO\\src\\study.jpg");
FileInputStream fis = new FileInputStream("srcFile");
FileOutputStream fos = new FileOutputStream("destFile");
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
byte[] buffer = new byte[1024];
int len;
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(bis != null){
try {
bis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(bos != null){
try {
bos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
3.写一个方法,输入一个文件名何一个字符串,统计这个字符串在这个文件中出现的次数。
public class CountWord {
public static void main(String args[]){
File file = new File("E:\\Workpace\\JavaIO\\src\\hello.txt");
int count = CountWordInFile(file,"hel");
System.out.println(count);
}
public static int CountWordInFile(File file,String word){
int counter = 0;
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(file));
String line = null;
while((line = br.readLine()) != null){
int index = -1;
while(line.length()>= word.length() && ((index = line.indexOf(word))>=0)){
counter ++;
line = line.substring(index+word.length());
}
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(br != null){
try {
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return counter;
}
}
4.用Java代码列出一个目录下所有的文件
如果只是对当前文件夹下的文件,则代码如下:
import java.io.File;
class Test12 {
public static void main(String[] args) {
File f = new File("/Users/Hao/Downloads");
for(File temp : f.listFiles()) {
if(temp.isFile()) {
System.out.println(temp.getName());
}
}
}
}