编程语言编年史

!Alt none

Boost Serialization (转载)

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// demo.cpp
//
// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)


#include <cstddef> // NULL
#include <iomanip>
#include <iostream>
#include <fstream>
#include <string>

#include <boost/archive/tmpdir.hpp>

#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>

#include <boost/serialization/base_object.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/assume_abstract.hpp>

/////////////////////////////////////////////////////////////
// The intent of this program is to serve as a tutorial for
// users of the serialization package.  An attempt has been made
// to illustrate most of the facilities of the package.  
//
// The intent is to create an example suffciently complete to
// illustrate the usage and utility of the package while
// including a minimum of other code. 
//
// This illustration models the bus system of a small city.
// This includes, multiple bus stops,  bus routes and schedules.
// There are different kinds of stops.  Bus stops in general will
// will appear on multiple routes.  A schedule will include
// muliple trips on the same route.

/////////////////////////////////////////////////////////////
// gps coordinate
//
// llustrates serialization for a simple type
//
class gps_position
{
    friend std::ostream & operator<<(std::ostream &os, const gps_position &gp);
    friend class boost::serialization::access;
    int degrees;
    int minutes;
    float seconds;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int /* file_version */){
        ar & degrees & minutes & seconds;
    }
public:
    // every serializable class needs a constructor
    gps_position(){};
    gps_position(int _d, int _m, float _s) : 
        degrees(_d), minutes(_m), seconds(_s)
    {}
};
std::ostream & operator<<(std::ostream &os, const gps_position &gp)
{
    return os << ' ' << gp.degrees << (unsigned char)186 << gp.minutes << '\'' << gp.seconds << '"';
}

/////////////////////////////////////////////////////////////
// One bus stop
//
// illustrates serialization of serializable members
//

class bus_stop
{
    friend class boost::serialization::access;
    friend std::ostream & operator<<(std::ostream &os, const bus_stop &gp);
    virtual std::string description() const = 0;
    gps_position latitude;
    gps_position longitude;
    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar & latitude;
        ar & longitude;
    }
protected:
    bus_stop(const gps_position & _lat, const gps_position & _long) :
        latitude(_lat), longitude(_long)
    {}
public:
    bus_stop(){}
    virtual ~bus_stop(){}
};

BOOST_SERIALIZATION_ASSUME_ABSTRACT(bus_stop)

std::ostream & operator<<(std::ostream &os, const bus_stop &bs)
{
    return os << bs.latitude << bs.longitude << ' ' << bs.description();
}

/////////////////////////////////////////////////////////////
// Several kinds of bus stops
//
// illustrates serialization of derived types
//
class bus_stop_corner : public bus_stop
{
    friend class boost::serialization::access;
    std::string street1;
    std::string street2;
    virtual std::string description() const
    {
        return street1 + " and " + street2;
    }
    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        // save/load base class information
        ar & boost::serialization::base_object<bus_stop>(*this);
        ar & street1 & street2;
    }

public:
    bus_stop_corner(){}
    bus_stop_corner(const gps_position & _lat, const gps_position & _long,
        const std::string & _s1, const std::string & _s2
    ) :
        bus_stop(_lat, _long), street1(_s1), street2(_s2)
    {
    }
};

class bus_stop_destination : public bus_stop
{
    friend class boost::serialization::access;
    std::string name;
    virtual std::string description() const
    {
        return name;
    }
    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar & boost::serialization::base_object<bus_stop>(*this) & name;
    }
public:
    
    bus_stop_destination(){}
    bus_stop_destination(
        const gps_position & _lat, const gps_position & _long, const std::string & _name
    ) :
        bus_stop(_lat, _long), name(_name)
    {
    }
};

/////////////////////////////////////////////////////////////
// a bus route is a collection of bus stops
//
// illustrates serialization of STL collection templates.
//
// illustrates serialzation of polymorphic pointer (bus stop *);
//
// illustrates storage and recovery of shared pointers is correct
// and efficient.  That is objects pointed to by more than one
// pointer are stored only once.  In such cases only one such
// object is restored and pointers are restored to point to it
//
class bus_route
{
    friend class boost::serialization::access;
    friend std::ostream & operator<<(std::ostream &os, const bus_route &br);
    typedef bus_stop * bus_stop_pointer;
    std::list<bus_stop_pointer> stops;
    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        // in this program, these classes are never serialized directly but rather
        // through a pointer to the base class bus_stop. So we need a way to be
        // sure that the archive contains information about these derived classes.
        //ar.template register_type<bus_stop_corner>();
        ar.register_type(static_cast<bus_stop_corner *>(NULL));
        //ar.template register_type<bus_stop_destination>();
        ar.register_type(static_cast<bus_stop_destination *>(NULL));
        // serialization of stl collections is already defined
        // in the header
        ar & stops;
    }
public:
    bus_route(){}
    void append(bus_stop *_bs)
    {
        stops.insert(stops.end(), _bs);
    }
};
std::ostream & operator<<(std::ostream &os, const bus_route &br)
{
    std::list<bus_stop *>::const_iterator it;
    // note: we're displaying the pointer to permit verification
    // that duplicated pointers are properly restored.
    for(it = br.stops.begin(); it != br.stops.end(); it++){
        os << '\n' << std::hex << "0x" << *it << std::dec << ' ' << **it;
    }
    return os;
}

/////////////////////////////////////////////////////////////
// a bus schedule is a collection of routes each with a starting time
//
// Illustrates serialization of STL objects(pair) in a non-intrusive way.
// See definition of operator<< <pair<F, S> >(ar, pair) and others in
// serialization.hpp
// 
// illustrates nesting of serializable classes
//
// illustrates use of version number to automatically grandfather older
// versions of the same class.

class bus_schedule
{
public:
    // note: this structure was made public. because the friend declarations
    // didn't seem to work as expected.
    struct trip_info
    {
        template<class Archive>
        void serialize(Archive &ar, const unsigned int file_version)
        {
            // in versions 2 or later
            if(file_version >= 2)
                // read the drivers name
                ar & driver;
            // all versions have the follwing info
            ar & hour & minute;
        }

        // starting time
        int hour;
        int minute;
        // only after system shipped was the driver's name added to the class
        std::string driver;

        trip_info(){}
        trip_info(int _h, int _m, const std::string &_d) :
            hour(_h), minute(_m), driver(_d)
        {}
    };
private:
    friend class boost::serialization::access;
    friend std::ostream & operator<<(std::ostream &os, const bus_schedule &bs);
    friend std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti);
    std::list<std::pair<trip_info, bus_route *> > schedule;
    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar & schedule;
    }
public:
    void append(const std::string &_d, int _h, int _m, bus_route *_br)
    {
        schedule.insert(schedule.end(), std::make_pair(trip_info(_h, _m, _d), _br));
    }
    bus_schedule(){}
};
BOOST_CLASS_VERSION(bus_schedule::trip_info, 2)

std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti)
{
    return os << '\n' << ti.hour << ':' << ti.minute << ' ' << ti.driver << ' ';
}
std::ostream & operator<<(std::ostream &os, const bus_schedule &bs)
{
    std::list<std::pair<bus_schedule::trip_info, bus_route *> >::const_iterator it;
    for(it = bs.schedule.begin(); it != bs.schedule.end(); it++){
        os << it->first << *(it->second);
    }
    return os;
}

void save_schedule(const bus_schedule &s, const char * filename){
    // make an archive
    std::ofstream ofs(filename);
    boost::archive::text_oarchive oa(ofs);
    oa << s;
}

void
restore_schedule(bus_schedule &s, const char * filename)
{
    // open the archive
    std::ifstream ifs(filename);
    boost::archive::text_iarchive ia(ifs);

    // restore the schedule from the archive
    ia >> s;
}

int main(int argc, char *argv[])
{   
    // make the schedule
    bus_schedule original_schedule;

    // fill in the data
    // make a few stops
    bus_stop *bs0 = new bus_stop_corner(
        gps_position(34, 135, 52.560f),
        gps_position(134, 22, 78.30f),
        "24th Street", "10th Avenue"
    );
    bus_stop *bs1 = new bus_stop_corner(
        gps_position(35, 137, 23.456f),
        gps_position(133, 35, 54.12f),
        "State street", "Cathedral Vista Lane"
    );
    bus_stop *bs2 = new bus_stop_destination(
        gps_position(35, 136, 15.456f),
        gps_position(133, 32, 15.300f),
        "White House"
    );
    bus_stop *bs3 = new bus_stop_destination(
        gps_position(35, 134, 48.789f),
        gps_position(133, 32, 16.230f),
        "Lincoln Memorial"
    );

    // make a  routes
    bus_route route0;
    route0.append(bs0);
    route0.append(bs1);
    route0.append(bs2);

    // add trips to schedule
    original_schedule.append("bob", 6, 24, &route0);
    original_schedule.append("bob", 9, 57, &route0);
    original_schedule.append("alice", 11, 02, &route0);

    // make aother routes
    bus_route route1;
    route1.append(bs3);
    route1.append(bs2);
    route1.append(bs1);

    // add trips to schedule
    original_schedule.append("ted", 7, 17, &route1);
    original_schedule.append("ted", 9, 38, &route1);
    original_schedule.append("alice", 11, 47, &route1);

    // display the complete schedule
    std::cout << "original schedule";
    std::cout << original_schedule;
    
    std::string filename(boost::archive::tmpdir());
    filename += "/demofile.txt";

    // save the schedule
    save_schedule(original_schedule, filename.c_str());

    // ... some time later
    // make  a new schedule
    bus_schedule new_schedule;

    restore_schedule(new_schedule, filename.c_str());

    // and display
    std::cout << "\nrestored schedule";
    std::cout << new_schedule;
    // should be the same as the old one. (except for the pointer values)

    delete bs0;
    delete bs1;
    delete bs2;
    delete bs3;
    return 0;
}
g++ -Wall -g -o demo demo.cpp -lboost_serialization

ref: http://www.boost.org/doc/libs/1_45_0/libs/serialization/doc/tutorial.html

Android JNI方法签名规则

JNI中对Java方法的签名格式为:(参数)返回值类型 其中参数部分的编码如下:

I : Integer
B : Byte
S : Short
C : Char
V : Void
LJava_Class; : Java中非基本类型
... ...

一个例子:

(LJava/lang/String;I)V

上面的方法签名表示该方法接受String和Integer两个参数,返回Void。

Java语言中对象的部分序列化

public class TestExternalizable implements Externalizable {

	//只对下面2个变量序列化
	int No;
	String name;
	
	//下面的变量没有被序列化
	int age = 0;

	public TestExternalizable() {
		// 在恢复Externalizable对象的时候,默认构造函数会被调用,这一点跟恢复一个Serializable对象不同
		System.out.println("Default Constructor");
	}

	public TestExternalizable(int No, String name, int age) {

		System.out.println("Other Constructor");
		this.name = name;
		this.No = No;
		this.age = age;
	}

	@Override
	public String toString() {
		return "No: " + No + ", Name: " + name + ", age: " + age;
	}

	//序列化数据时调用的函数
	@Override
	public void writeExternal(ObjectOutput out) throws IOException {
		out.writeInt(No);
		out.writeObject(name);
	}

	//恢复数据时调用的函数。需要保证恢复的数据跟序列化时一致
	@Override
	public void readExternal(ObjectInput in) throws IOException,
			ClassNotFoundException {

		No = in.readInt();
		name = (String) in.readObject();
	}

	public static void main(String[] args) {

		TestExternalizable te = new TestExternalizable(10, "lnmcc", 18);
		System.out.println(te.toString());

		try {
			//将一个Externalizable对象保存到一个文件
			ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("out.dat"));
			out.writeObject(te);
			//刷新并关闭流
			out.close();

			//从文件恢复一个Externalizable对象
			ObjectInputStream in = new ObjectInputStream(new FileInputStream("out.dat"));
			te = (TestExternalizable) in.readObject();
			System.out.println(te.toString());
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

输出:

Other Constructor
No: 10, Name: lnmcc, age: 18
Default Constructor
No: 10, Name: lnmcc, age: 0

结果显示:

  1. 反序列化一个Externalizable对象的时候会调用类的默认构造函数。
  2. No和Name字段成功恢复,age字段由于没有被序列化,为默认值。

Java基本IO操作

public class IODemo {

	public static void main(String[] args) {
		try {
			// 1a.Reading input by lines
			BufferedReader in = new BufferedReader(new FileReader(args[0]));
			String s, s2 = new String();
			while ((s = in.readLine()) != null) {
				s2 += s + "\n";
			}
			in.close();

			// 1b.Reading standard input
			BufferedReader stdin = new BufferedReader(new InputStreamReader(
					System.in));
			System.out.println("Enter a line: ");
			System.out.println(stdin.readLine());

			// 2.Input from memory
			StringReader in2 = new StringReader(s2);
			int c;
			while ((c = in2.read()) != -1) {
				System.out.print((char) c);
			}

			// 3. Formatted memory input
			try {
				DataInputStream in3 = new DataInputStream(
						new StringBufferInputStream(s2));
				while (true) {
					System.out.print((char) in3.readByte());
				}
			} catch (EOFException e) {
				System.out.println("End of stream");
			}

			// 4. Line number reading & file output
			try {
				LineNumberReader li = new LineNumberReader(new StringReader(s2));
				BufferedReader in4 = new BufferedReader(li);
				PrintWriter out1 = new PrintWriter(new BufferedWriter(
						new FileWriter("IODemo.out")));
				while ((s = in4.readLine()) != null) {
					out1.println("Line " + li.getLineNumber() + " " + s);
				}
				out1.close();

			} catch (EOFException e) {
				System.out.println("End of stream");
			}

			// 5. Storing & recovering data
			try {
				DataOutputStream out2 = new DataOutputStream(
						new BufferedOutputStream(new FileOutputStream(
								"Data.txt")));
				out2.writeDouble(3.1415926);
				out2.writeBytes("It is a pi");
				out2.close();

				DataInputStream in5 = new DataInputStream(
						new BufferedInputStream(new FileInputStream("Data.txt")));
				BufferedReader in5br = new BufferedReader(
						new InputStreamReader(in5));
				System.out.println(in5.readDouble());
				System.out.println(in5br.readLine());
			} catch (EOFException e) {
				System.out.println("End of stream");
			}

		} catch (FileNotFoundException e) {
			System.out.println("File Not Found: " + args[1]);
		} catch (IOException e) {
			System.out.println("IO Exception");
		}
	}
}