[Java开发之路](9)对象序列化与反序列化
1. 对象序列化
当然,我们也能够通过将信息写入文件或者数据库,可是假设能将一个对象声明为是"持久性"的,并为我们处理掉全部的细节,这将会显得十分方便。
这意味着序列化机制能自己主动弥补不同操作系统之间的差异。
一是Java的远程方法调用(RMI),它使存活于其它计算机上的对象使用起来就像存活于本机上一样。
当向远程对象发送消息时,须要通过对象序列化来传输參数和返回值。二是Java Beans。使用一个bean时。普通情况下是在设计阶段对它的状态信息进行配置。这样的状态信息必须保存下来,并在程序启动时进行后期恢复(这样的详细工作就是由对象序列化完毕的)。
这时,仅仅需调用writeObject()就可以将对象序列化,并将其发送给 OutputStream(对象序列化是基于字节的,因要使用InputStream和OutputStream继承层次结构)。
要反向进行该过程(将一个序列化还原为一个对象),须要将一个InputStream封装在ObjectInputStream内,然后调用readObject()。和往常一样。我们最后获得的是一个引用,它指向一个向上转型的Object,所以必须向下转型才干直接设置它们。
package com.qunar.bean;
import java.io.Serializable;
/**
* 学生实体类
* @author sjf0115
*
*/
public class Student implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
// 姓名
private String name;
// 学号
private String ID;
// 年龄
private int age;
// 学校
private String school;
/**
* @param name
* @param iD
* @param age
* @param school
*/
public Student(String name, String id, int age, String school) {
super();
this.name = name;
ID = id;
this.age = age;
this.school = school;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getID() {
return ID;
}
public void setID(String iD) {
ID = iD;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
@Override
public String toString() {
return "姓名:" + name + " 学号:" + ID + " 年龄:" + age + " 学校:" + school;
}
}
package com.qunar.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import com.qunar.bean.Student;
public class SeriaCode {
public static void main(String[] args) {
// 对象序列化数据保存位置
String path = "D:\\seria.dat";
try {
// 创建FileOutputStream对象
FileOutputStream fileOutputStream = new FileOutputStream(path);
// 创建ObjectOutputStream对象
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
// 序列化对象
Student student = new Student("xiaosi","130346",25,"西安电子科技大学");
// 进行对象序列化 Student对象要实现序列化接口
objectOutputStream.writeObject(student);
objectOutputStream.flush();
objectOutputStream.close();
// 创建FileInputStream对象
FileInputStream fileInputStream = new FileInputStream(path);
// 创建ObjectInputStream对象
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
// 反序列化为对象
Student stu = (Student)objectInputStream.readObject();
objectInputStream.close();
System.out.println("Stu->"+stu);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
package com.qunar.io.serial;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
public class SerialCode2 {
public static void main(String[] args) {
try {
// 创建FileInputStream对象
FileInputStream fileInputStream = new FileInputStream("seria.dat");
// 创建ObjectInputStream对象
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
// 反序列化为对象
Object object = objectInputStream.readObject();
objectInputStream.close();
System.out.println(object.getClass());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
java.lang.ClassNotFoundException: com.qunar.io.Student
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at java.io.ObjectInputStream.resolveClass(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at com.qunar.io.serial.SerialCode2.main(SerialCode2.java:17)
|
这两个方法会在序列化和反序列化还原过程中自己主动调用。以便运行一些特殊操作。
package com.qunar.io;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
public class Fruit implements Externalizable{
public Fruit(){
System.out.println("Fruit constructor...");
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
System.out.println("Fruit writeExternal...");
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
System.out.println("Fruit readExternal...");
}
}
package com.qunar.io;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
public class Fruit2 implements Externalizable{
Fruit2(){
System.out.println("Fruit2 constuctor...");
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
System.out.println("Fruit writeExternal...");
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
System.out.println("Fruit readExternal...");
}
}
package com.qunar.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class FruitSerialCode {
public static void main(String[] args) {
try {
// 创建FileOutputStream对象
FileOutputStream fileOutputStream = new FileOutputStream("fruit.out");
// 创建ObjectOutputStream对象
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
// 序列化对象
Fruit fruit = new Fruit();
Fruit2 fruit2 = new Fruit2();
// 进行对象序列化 Fruit对象要实现序列化接口
System.out.println("writeObject...");
objectOutputStream.writeObject(fruit);
objectOutputStream.writeObject(fruit2);
objectOutputStream.flush();
objectOutputStream.close();
// 创建FileInputStream对象
FileInputStream fileInputStream = new FileInputStream("fruit.out");
// 创建ObjectInputStream对象
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
// 反序列化为对象
System.out.println("readFruit...");
fruit = (Fruit)objectInputStream.readObject();
System.out.println("readFruit2...");
fruit2 = (Fruit2)objectInputStream.readObject();
objectInputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Fruit constructor...
Fruit2 constuctor...
writeObject...
Fruit writeExternal...
Fruit writeExternal...
readFruit...
Fruit constructor...
Fruit readExternal...
readFruit2...
java.io.InvalidClassException: com.qunar.io.Fruit2; no valid constructor
at java.io.ObjectStreamClass$ExceptionInfo.newInvalidClassException(Unknown Source)
at java.io.ObjectStreamClass.checkDeserialize(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at com.qunar.io.FruitSerialCode.main(FruitSerialCode.java:36)
|
上例中没有反序列化后Fruit2对象。而且导致了一个异常。主要是Fruit的构造函数是public的,而Fruit2的构造函数却不是,这样就会在反序列时抛出异常。
对于一个Serializable对象。对象全然以它存储的二进制位为基础,而不用调用构造函数。而对于一个Externalizable对象,全部普通的构造函数都会被调用(包含在字段定义时的初始化)。然后调用readExternal()。
全部默认的构造函数都会被调用。才干使Externalizable对象产生正确的行为。 |
package com.qunar.io;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
public class Fruit implements Externalizable{
private String name;
private int num;
// 必须有默认构造函数 反序列时使用
public Fruit(){
System.out.println("Fruit default constructor...");
}
/**
* @param name
* @param num
*/
public Fruit(String name, int num) {
System.out.println("Fruit constructor...");
this.name = name;
this.num = num;
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
System.out.println("Fruit writeExternal...");
// 必须做例如以下操作
out.writeObject(name);
out.writeInt(num);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
System.out.println("Fruit readExternal...");
// 必须做例如以下操作
name = (String)in.readObject();
num = in.readInt();
}
@Override
public String toString() {
return "name:" + name + " num:" + num;
}
}
package com.qunar.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class FruitSerialCode {
public static void main(String[] args) {
try {
// 创建FileOutputStream对象
FileOutputStream fileOutputStream = new FileOutputStream("fruit.out");
// 创建ObjectOutputStream对象
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
// 序列化对象
Fruit fruit = new Fruit("苹果",20);
// 进行对象序列化 Fruit对象要实现序列化接口
System.out.println("writeObject...");
objectOutputStream.writeObject(fruit);
objectOutputStream.flush();
objectOutputStream.close();
// 创建FileInputStream对象
FileInputStream fileInputStream = new FileInputStream("fruit.out");
// 创建ObjectInputStream对象
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
// 反序列化为对象
System.out.println("readFruit...");
fruit = (Fruit)objectInputStream.readObject();
System.out.println("Fruit->[" + fruit + "]");
objectInputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Fruit constructor...
writeObject...
Fruit writeExternal...
readFruit...
Fruit default constructor...
Fruit readExternal...
Fruit->[name:苹果 num:20]
|
Fruit constructor...
writeObject...
Fruit writeExternal...
readFruit...
Fruit default constructor...
Fruit readExternal...
Fruit->[name:null num:0]
|
为了进行控制,使用transientkeyword关闭序列化操作,它的意思"不用麻烦你序列化或者反序列化数据,我自己会处理的"。
package com.qunar.io;
import java.io.Serializable;
import java.util.Date;
public class Login implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private Date date = new Date();
private String userName;
// 防止被序列化transient
private transient String password;
/**
* @param date
* @param userName
* @param password
*/
public Login(String userName, String password) {
super();
this.userName = userName;
this.password = password;
}
@Override
public String toString() {
return "Date:" + date + " UserName:" + userName + " Password:" + password;
}
}
package com.qunar.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class LoginSerialCode {
public static void main(String[] args) {
try {
// 创建FileOutputStream对象
FileOutputStream fileOutputStream = new FileOutputStream("login.out");
// 创建ObjectOutputStream对象
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
// 序列化对象
Login login = new Login("xiaosi", "123");
// 进行对象序列化 Fruit对象要实现序列化接口
System.out.println("writeObject...");
objectOutputStream.writeObject(login);
objectOutputStream.flush();
objectOutputStream.close();
// 创建FileInputStream对象
FileInputStream fileInputStream = new FileInputStream("login.out");
// 创建ObjectInputStream对象
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
// 反序列化为对象
System.out.println("readFruit...");
login = (Login)objectInputStream.readObject();
System.out.println("LoginInfo->[" + login + "]");
objectInputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
writeObject...
readFruit...
LoginInfo->[Date:Thu Dec 31 00:16:13 CST 2015 UserName:xiaosi Password:null]
|
同一时候我们发现date字段被存储在磁盘而且从磁盘上恢复出来,而不是又一次生成。
这样一旦进行序列化和反序列化,就会自己主动的分别调用这两个方法,来取代默认的序列化机制。
package com.qunar.io;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;
public class Login implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private Date date = new Date();
private String userName;
// 防止被序列化transient
private transient String password;
/**
* @param date
* @param userName
* @param password
*/
public Login(String userName, String password) {
super();
this.userName = userName;
this.password = password;
}
// 必须有
private void writeObject(ObjectOutputStream stream) throws IOException{
// 默认的序列化
stream.defaultWriteObject();
// 手动完毕序列化
stream.writeObject(password);
}
// 必须有
private void readObject(ObjectInputStream stream) throws ClassNotFoundException, IOException{
// 默认的反序列化
stream.defaultReadObject();
// 手动完毕反序列化
password = (String)stream.readObject();
}
@Override
public String toString() {
return "Date:" + date + " UserName:" + userName + " Password:" + password;
}
}
package com.qunar.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class LoginSerialCode {
public static void main(String[] args) {
try {
// 创建FileOutputStream对象
FileOutputStream fileOutputStream = new FileOutputStream("login.out");
// 创建ObjectOutputStream对象
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
// 序列化对象
Login login = new Login("xiaosi", "123");
// 进行对象序列化 Fruit对象要实现序列化接口
System.out.println("writeObject...");
objectOutputStream.writeObject(login);
objectOutputStream.flush();
objectOutputStream.close();
// 创建FileInputStream对象
FileInputStream fileInputStream = new FileInputStream("login.out");
// 创建ObjectInputStream对象
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
// 反序列化为对象
System.out.println("readFruit...");
login = (Login)objectInputStream.readObject();
System.out.println("LoginInfo->[" + login + "]");
objectInputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
writeObject...
readFruit...
LoginInfo->[Date:Fri Jan 01 15:57:53 CST 2016 UserName:xiaosi Password:123]
|
在这个样例中。password字段是transient字段,用来证明非transient字段是由defaultWriteObject()方法保存,而transient字段是必须在程序中明白保存和恢复。
package com.qunar.io;
import java.io.Serializable;
public class House implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private String location;
/**
* @param name
* @param location
*/
public House(String name, String location) {
super();
this.name = name;
this.location = location;
}
}
package com.qunar.io;
import java.io.Serializable;
public class Animal implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private House house;
/**
* 构造函数
* @param name
* @param house
*/
public Animal(String name, House house) {
super();
this.name = name;
this.house = house;
}
@Override
public String toString() {
return name + " " + house;
}
}
package com.qunar.io;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
public class AnimalSerialCode {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
House house = new House("水立方","北京海淀区");
List<Animal> animals = new ArrayList<Animal>();
animals.add(new Animal("狗", house));
animals.add(new Animal("鸡", house));
animals.add(new Animal("羊", house));
System.out.println("Animals->" + animals);
try {
ByteArrayOutputStream buf = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(buf);
// 序列化
objectOutputStream.writeObject(animals);
objectOutputStream.writeObject(animals);
ByteArrayOutputStream buf2 = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream2 = new ObjectOutputStream(buf2);
// 序列化
objectOutputStream2.writeObject(animals);
ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(buf.toByteArray()));
List<Animal> ani1 = (List<Animal>)objectInputStream.readObject();
List<Animal> ani2 = (List<Animal>)objectInputStream.readObject();
ObjectInputStream objectInputStream2 = new ObjectInputStream(new ByteArrayInputStream(buf2.toByteArray()));
List<Animal> ani3 = (List<Animal>)objectInputStream2.readObject();
System.out.println("Animals1->"+ani1);
System.out.println("Animals2->"+ani2);
System.out.println("Animals3->"+ani3);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Animals->[狗 com.qunar.io.House@1b15692, 鸡 com.qunar.io.House@1b15692, 羊 com.qunar.io.House@1b15692]
Animals1->[狗 com.qunar.io.House@1aaf0b3, 鸡 com.qunar.io.House@1aaf0b3, 羊 com.qunar.io.House@1aaf0b3]
Animals2->[狗 com.qunar.io.House@1aaf0b3, 鸡 com.qunar.io.House@1aaf0b3, 羊 com.qunar.io.House@1aaf0b3]
Animals3->[狗 com.qunar.io.House@1a082e2, 鸡 com.qunar.io.House@1a082e2, 羊 com.qunar.io.House@1a082e2]
|
在这个样例中,Animal对象包括House类型字段。我们创建Animals列表并将其两次序列化,分别送至不同的流。当期被反序列化还原被打印时。我们能够看到:每次执行时对象将会处在不同的内存地址。
[Java开发之路](9)对象序列化与反序列化的更多相关文章
- java 对象序列化与反序列化
Java序列化与反序列化是什么? 为什么需要序列化与反序列化? 如何实现Java序列化与反序列化? 本文围绕这些问题进行了探讨. 1.Java序列化与反序列化 Java序列化是指把Java对象转换为 ...
- Java Io 对象序列化和反序列化
Java 支持将任何对象进行序列化操作,序列化后的对象文件便可通过流进行网络传输. 1. 对象序列化就是将对象转换成字节序列,反之叫对象的反序列化 2. 序列化流ObjectOut ...
- Java对象序列化与反序列化一 JSON
Java对象序列化与反序列化一 JSON 1. 依赖库 jackson-all-1.6.1.jar 2. 代码 public class Student { private String nam ...
- Java之对象序列化和反序列化
一.对象序列化和反序列化存在的意义: 当你创建对象,只要你需要,他就一直存在,但当程序结束,对象就会消失,但是存在某种情况,如何让程序在不允许的状态,仍然保持该对象的信息.并在下次程序运行的时候使用该 ...
- Java 序列化 对象序列化和反序列化
Java 序列化 对象序列化和反序列化 @author ixenos 对象序列化是什么 1.对象序列化就是把一个对象的状态转化成一个字节流. 我们可以把这样的字节流存储为一个文件,作为对这个对象的复制 ...
- Java IO详解(六)------序列化与反序列化(对象流)
File 类的介绍:http://www.cnblogs.com/ysocean/p/6851878.html Java IO 流的分类介绍:http://www.cnblogs.com/ysocea ...
- Java对象序列化和反序列化的工具方法
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import ja ...
- Java对象序列化与反序列化
对象序列化的目标是将对象保存在磁盘中或者在网络中进行传输.实现的机制是允许将对象转为与平台无关的二进制流. java中对象的序列化机制是将允许对象转为字节序列.这些字节序列可以使Java对象脱离程序存 ...
- Java基础(二十九)Java IO(6)对象序列化(Object Serialization)
参考之前整理过的Java序列化与反序列化:https://www.cnblogs.com/BigJunOba/p/9127414.html 使用对象输入输出流可以实现对象序列化与反序列化,可以直接存取 ...
- C#对象序列化与反序列化zz
C#对象序列化与反序列化(转载自:http://www.cnblogs.com/LiZhiW/p/3622365.html) 1. 对象序列化的介绍........................ ...
随机推荐
- 44.AngularJS Bootstrap
转自:https://www.cnblogs.com/best/tag/Angular/ Bootstrap 你可以在你的 AngularJS 应用中加入 Twitter Bootstrap,你可以在 ...
- vs2015发布项目到虚拟主机组策略阻止csc.exe程序问题
这个问题之前碰到过一次,这次又碰到,就记录一下解决方法. 这个问题的产生的原因,据说是虚拟主机没有权限执行exe文件造成的,如果是独立服务器的话发布就不会出现这个问题. 使用VS2015发布web项目 ...
- 使用Java操作Redis(一)
Redis是一款基于key-value的数据库服务器,安装完成后我们可以通过redis-cli使用Redis提供的命令完成各种操作.redis-cli实际上就是一款客户端,和redis-server建 ...
- JDK5新特性:可变参数方法
JDK1.5增加可变参方法,其定义格式为: 访问修饰符 返回值类型 方法标识符(参数类型 参数标识符1,参数类型 参数标识符2,参数类型...参数标识符){} 如可能要定义一个求和功能的方法,但求和的 ...
- GoldenGate 1403错误解决方法
OGG oracle goldengate 1403错误解决方法 1. 错误描述WARNING OGG-01154 Oracle GoldenGate Delivery for Oracle, re ...
- echarts 总结:
options配置项: title: 图表标题的配置 tooltip: 鼠标悬浮的提示 toolbox: 工具栏 series: 数据项,是每一个个的数据对象,可以根据type配置每一项数据的图例. ...
- [USACO07MAR]每月的费用Monthly Expense
题目:POJ3273.洛谷P2884. 题目大意:有n个数,要分成m份,每份的和要尽可能小,求这个情况下和最大的一份的和. 解题思路:二分答案,对每个答案进行贪心判断,如果最后得出份数>m,则说 ...
- mysql主从同步错误恢复
Mysql主从同步集群在生成环境使用过程中,如果主从服务器之间网络通信条件差或者数据库数据量非常大,容易导致MYSQL主从同步延迟. MYSQL主从产生延迟之后,一旦主库宕机,会导致部分数据没有及时同 ...
- Centos7(阿里云服务器)安装Anaconda的详细步骤与心得
在本地安装Anaconda的各个版本的文章已经很多,但是感觉不是很详细,因此,在此发发自己在Centos7(阿里云服务器)安装Anaconda的心得和步骤: 注:需要注意的地方会用不同颜色区别. 1. ...
- screen---管理会话
Screen是一款由GNU计划开发的用于命令行终端切换的自由软件.用户可以通过该软件同时连接多个本地或远程的命令行会话,并在其间自由切换.GNU Screen可以看作是窗口管理器的命令行界面版本.它提 ...