Java内存分析

jmap -histo 26890 | more

jstat -gcutil 340[pid] 10000[interval]

这个命令是每个10秒钟输出一次jvm的gc信息


S0 S1 E O P YGC YGCT FGC FGCT GCT

54.62 0.00 42.87 43.52 86.24 1792 5.093 33 7.670 12.763

S0:新生代的susvivor0区,空间使用率为5462%

S1:新生代的susvivor1区,空间使用率为0.00%(因为还没有执行第二次minor收集)

E:eden区,空间使用率42.87%

O:旧生代,空间使用率43.52%

P:持久带,空间使用率86.24%

YGC:minor gc执行次数1792次

YGCT:minor gc耗费的时间5.093毫秒

FGC:full gc执行次数33

FGCT:full gc耗费的时间7.670毫秒

GCT:gc耗费的总时间12.763毫秒

confluence wiki 安装破解汉化

说明:此文在confluence-wiki-5.6.5版本亲测通过
附件:http://pan.baidu.com/s/1sjulMBr (包括了wiki的程序以及破解汉化需要的所有文件)


一、附件文件说明

1.atlassian-confluence-5.6.5.tar.gz    confluence wiki官方程序

2.mysql-connector-java-5.1.25-bin.jar    如果使用mysql需要此驱动

3.confluence5.x-crack.zip    破解工具

4.atlassian-extras-2.4.jar    破解需要的jar包

5.Confluence-Language-STD-CN.jar    汉化包

二、安装官方程序

1.tar -zxvf atlassian-confluence-5.6.5.tar.gz

2.vi atlassian-confluence/WEB-INFO/class/confluence-init.properties;修改confluence.home参数为自定一个目录,便于升级管理,license信息也在这个目录。

3.cd atlassian-confluence/bin && ./atlassian-confluence-start.sh(具体名字忘记了)
说明:当然我们可以自己装个tomcat,然后把atlassian-confluence下的confluence目录拿出来,然后配置下tomcat的server.xml(我就是这么做的)

4.启动成功后,浏览器打开,在出来的页面选右边这个选项,然后就进入要求输入license key的界面。这样我们官方程序以及安装成功

三、破解

1.解压附件中的confluence5.x-crack.zip,不用理会里面的atlassian-extras-2.4.jar,这个应该是其它版本用的。

2.我们直接进入iNViSiBLE,根据自己的系统运行keygen.sh或keygen.bat(需要有java运行环境)

3.在出来的程序界面中随便输入name,Server ID为《二、安装官方程序》第四步中的Server ID

4.点击path,选择附件中的atlassian-extras-2.4.jar,此时会生成一个新的atlassian-extras-2.4.jar,原来的jar变为了atlassian-extras-2.4.bak,将atlassian-extras-2.4.jar再重命名为atlassian-extras-3.2.jar,至此,我们最终需要的破解文件atlassian-extras-3.2.jar准备好了

5.点击gen,生成的key复制下,等下需要用到

6.进入confluence服务器的atlassian-confluence/confluence/WEB-INF/lib包下,把那6个atlassian-extras开头的jar包全部删掉,替换为我们刚刚生成好的atlassian-extras-3.2.jar。另外需要注意,如果使用mysql需要吧附件中的mysql-connector-java-5.1.25-bin.jar也放到这个目录里

7.重启confluence

8.重启后进入《二、安装官方程序》第四步界面,需要填入key,这个就是上面第五步中复制的key。

9.复制后下一步进入选择数据库连接。根据自己情况选择。貌似暂时不支持CentOS7 Mariadb,反正这里我搞了挺久,后来还是换成了Postgresql数据库。

10.OK,其它就一步步下去很简单了

四、注意点

1.由于我使用的是CentOS7,已经不再支持Mysql数据库,取而代之的是Mysql的一个分组Mariadb,找了很多文档说不支持Mariadb什么的,但是试了下,表倒是创建了几张出来,但是由于其它原因没有成功,后来也就放弃了尝试,直接换成了postgresql。

2.confluence-wiki对系统内存要求比较高,建议内存2G+,我用的2G,装完后只剩了几百兆的内存了。512G、1G的内存在配置完数据库连接后的下一步容易卡死,然后Tomcat报内存溢出

JavaFx疑难杂症汇总

1.webview有些地方中文乱码

原因为不支持宋体,吧css中的宋体给为微软雅黑就好

2.xp下页面被放大,鼠标漂移问题

导致该问题主要是由于启用了3D硬件加速,通过设置系统参数-Dprism.order=j2d解决,注意需要在main中也加入

3.xp下会导致蓝屏问题

在win7下打包的exe在xp下运行会发生这种情况,可以在xp下打包,这样支持xp和win7平台

Java开发exe程序

1.使用JavaFX技术
2.使用NetBeans IDE 7.4,通过build.xml生成exe和jar文件

<?xml version="1.0" encoding="UTF-8"?><!-- You may freely edit this file. See commented blocks below for --><!-- some examples of how to customize the build. --><!-- (If you delete it and reopen the project it will be recreated.) --><!-- By default, only the Clean and Build commands use this build script. --><project name="HelloWorld" default="default" basedir="." xmlns:fx="javafx:com.sun.javafx.tools.ant">
    <description>Builds, tests, and runs the project HelloWorld.</description>
    <import file="nbproject/build-impl.xml"/>
    <!--

    There exist several targets which are by default empty and which can be 
    used for execution of your tasks. These targets are usually executed 
    before and after some main targets. Those of them relevant for JavaFX project are: 

      -pre-init:                 called before initialization of project properties
      -post-init:                called after initialization of project properties
      -pre-compile:              called before javac compilation
      -post-compile:             called after javac compilation
      -pre-compile-test:         called before javac compilation of JUnit tests
      -post-compile-test:        called after javac compilation of JUnit tests
      -pre-jfx-jar:              called before FX SDK specific <fx:jar> task
      -post-jfx-jar:             called after FX SDK specific <fx:jar> task
      -pre-jfx-deploy:           called before FX SDK specific <fx:deploy> task
      -post-jfx-deploy:          called after FX SDK specific <fx:deploy> task
      -pre-jfx-native:           called just after -pre-jfx-deploy if <fx:deploy> runs in native packaging mode
      -post-jfx-native:          called just after -post-jfx-deploy if <fx:deploy> runs in native packaging mode
      -post-clean:               called after cleaning build products

    (Targets beginning with '-' are not intended to be called on their own.)

    Example of inserting a HTML postprocessor after javaFX SDK deployment:

        <target name="-post-jfx-deploy">
            <basename property="jfx.deployment.base" file="${jfx.deployment.jar}" suffix=".jar"/>
            <property name="jfx.deployment.html" location="${jfx.deployment.dir}${file.separator}${jfx.deployment.base}.html"/>
            <custompostprocess>
                <fileset dir="${jfx.deployment.html}"/>
            </custompostprocess>
        </target>

    Example of calling an Ant task from JavaFX SDK. Note that access to JavaFX SDK Ant tasks must be
    initialized; to ensure this is done add the dependence on -check-jfx-sdk-version target:

        <target name="-post-jfx-jar" depends="-check-jfx-sdk-version">
            <echo message="Calling jar task from JavaFX SDK"/>
            <fx:jar ...>
                ...
            </fx:jar>
        </target>

    For more details about JavaFX SDK Ant tasks go to

http://docs.oracle.com/javafx/2/deployment/jfxpub-deployment.htm

    For list of available properties check the files
    nbproject/build-impl.xml and nbproject/jfx-impl.xml.

    -->
    
    <target name="-post-jfx-deploy">
       <fx:deploy width="${javafx.run.width}" height="${javafx.run.height}" 
                  nativeBundles="all"
                  outdir="${basedir}/${dist.dir}" outfile="${application.title}">
          <fx:application name="${application.title}" 
                          mainClass="${javafx.main.class}"/>
          <fx:resources>
              <fx:fileset dir="${basedir}/${dist.dir}"
                          includes="*.jar"/>
          </fx:resources>
          <fx:info title="${application.title}" 
                   vendor="${application.vendor}"/>
        </fx:deploy>          
     </target>
</project>

HelloWorld.java



import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
 
 
public class HelloWorld extends Application {
    private Scene scene;
    @Override public void start(Stage stage) {
        // create the scene
        stage.setTitle("Web View");
        scene = new Scene(new Browser(),1280,800, Color.web("#666970"));
        stage.setScene(scene);
        //scene.getStylesheets().add("webviewsample/BrowserToolbar.css");        
        stage.show();
    }
 
    public static void main(String[] args){
        launch(args);
    }
}
class Browser extends Region {
 
    final WebView browser = new WebView();
    final WebEngine webEngine = browser.getEngine();
     
    public Browser() {
        //apply the styles
        getStyleClass().add("browser");
        // load the web page
        webEngine.load("http://chrome.360.cn/test/html5/index.html");
        //add the web view to the scene
        getChildren().add(browser);
 
    }
    private Node createSpacer() {
        Region spacer = new Region();
        HBox.setHgrow(spacer, Priority.ALWAYS);
        return spacer;
    }
 
    @Override protected void layoutChildren() {
        double w = getWidth();
        double h = getHeight();
        layoutInArea(browser,0,0,w,h,0, HPos.CENTER, VPos.CENTER);
    }
 
    @Override protected double computePrefWidth(double height) {
        return 750;
    }
 
    @Override protected double computePrefHeight(double width) {
        return 500;
    }
}

3.生成后使用Inno Setup Compiler打包成安装程序,需要include NetBeansProjects\HelloWorld\dist\bundles\HelloWorld下的文件
包括jre运行环境和jar配置

DONE!

安装passport和discuz云桌面部署过程中遇到问题总结

1.MQ同步:如果数据库被锁住不能更新消息到MQ服务器。

2.MQ同步工具:注意连接数据库字符串的的encode需要和数据库的一致,查看数据库编码可以通过show variables like ‘character%';否则会导致中文乱码而同步是吧

3.MYSQL:mysql安装后默认是只允许本地localhost来连接数据库。如果mysql和应用不在同台服务器,需要个mysql远程连接的权限。及时在同台机子,不用localhost连接也需要给权限。可以通过grant all PRIVILEGES on discuz.* to ted@’123.123.123.123′ identified by ‘123456’; 123.123.123.123表示允许连接的ip或则域名,如果用%代替,则表示完全开放。

quartz 时间配置规则

很久没用弄QUARTZ了,它的规则都忘记了,今天用到就找了篇别人的文章,这里记录下

格式: [秒] [分] [小时] [日] [月] [周] [年]

序号 说明 是否必填 允许填写的值 允许的通配符
1 0-59 , – * /
2 0-59 , – * /
3 小时 0-23 , – * /
4 1-31 , – * ? / L W
5 1-12 or JAN-DEC , – * /
6 1-7 or SUN-SAT , – * ? / L #
7 empty 或 1970-2099 , – * /

通配符说明:
* 表示所有值. 例如:在分的字段上设置 “*”,表示每一分钟都会触发。
? 表示不指定值。使用的场景为不需要关心当前设置这个字段的值。例如:要在每月的10号触发一个操作,但不关心是周几,所以需要周位置的那个字段设置 为”?” 具体设置为 0 0 0 10 * ?
- 表示区间。例如 在小时上设置 “10-12″,表示 10,11,12点都会触发。
, 表示指定多个值,例如在周字段上设置 “MON,WED,FRI” 表示周一,周三和周五触发
/ 用于递增触发。如在秒上面设置”5/15″ 表示从5秒开始,每增15秒触发(5,20,35,50)。 在月字段上设置’1/3’所示每月1号开始,每隔三天触发一次。
L 表示最后的意思。在日字段设置上,表示当月的最后一天(依据当前月份,如果是二月还会依据是否是润年[leap]), 在周字段上表示星期六,相当于”7″或”SAT”。如果在”L”前加上数字,则表示该数据的最后一个。例如在周字段上设置”6L”这样的格式,则表示“本 月最后一个星期五”
W 表示离指定日期的最近那个工作日(周一至周五). 例如在日字段上设置”15W”,表示离每月15号最近的那个工作日触发。如果15号正好是周六,则找最近的周五(14号)触发, 如果15号是周未,则找最近的下周一(16号)触发.如果15号正好在工作日(周一至周五),则就在该天触发。如果指定格式为 “1W”,它则表示每月1号往后最近的工作日触发。如果1号正是周六,则将在3号下周一触发。(注,”W”前只能设置具体的数字,不允许区间”-“).

小提示 ‘L’和 ‘W’可以一组合使用。如果在日字段上设置”LW”,则表示在本月的最后一个工作日触发(一般指发工资 )

# 序号(表示每月的第几个周几),例如在周字段上设置”6#3″表示在每月的第三个周六.注意如果指定”#5″,正好第五周没有周六,则不会触发该配置(用 在母亲节和父亲节再合适不过了)

小提示 周字段的设置,若使用英文字母是不区分大小写的 MON 与mon相同.

常用示例:

0 0 12 * * ? 每天12点触发
0 15 10 ? * * 每天10点15分触发
0 15 10 * * ? 每天10点15分触发
0 15 10 * * ? * 每天10点15分触发
0 15 10 * * ? 2005 2005年每天10点15分触发
0 * 14 * * ? 每天下午的 2点到2点59分每分触发
0 0/5 14 * * ? 每天下午的 2点到2点59分(整点开始,每隔5分触发)
0 0/5 14,18 * * ? 每天下午的 2点到2点59分(整点开始,每隔5分触发)
每天下午的 18点到18点59分(整点开始,每隔5分触发)
0 0-5 14 * * ? 每天下午的 2点到2点05分每分触发
0 10,44 14 ? 3 WED 3月分每周三下午的 2点10分和2点44分触发
0 15 10 ? * MON-FRI 从周一到周五每天上午的10点15分触发
0 15 10 15 * ? 每月15号上午10点15分触发
0 15 10 L * ? 每月最后一天的10点15分触发
0 15 10 ? * 6L 每月最后一周的星期五的10点15分触发
0 15 10 ? * 6L 2002-2005 从2002年到2005年每月最后一周的星期五的10点15分触发
0 15 10 ? * 6#3 每月的第三周的星期五开始触发
0 0 12 1/5 * ? 每月的第一个中午开始每隔5天触发一次
0 11 11 11 11 ? 每年的11月11号 11点11分触发(光棍节)

 

JSON与JAVA数据的转换

JSON-lib这个Java类包用于把bean,map和XML转换成JSON并能够把JSON转回成bean和DynaBean。

下载地址:http://json-lib.sourceforge.net/
还要需要的第3方包:
org.apache.commons(3.2以上版本)
org.apache.oro
net.sf.ezmorph(ezmorph-1.0.4.jar)
nu.xom

1、List

Java代码
  1. boolean[] boolArray = new boolean[]{true,false,true};
  2. JSONArray jsonArray1 = JSONArray.fromObject( boolArray );
  3. System.out.println( jsonArray1 );
  4. // prints [true,false,true]
  5. List list = new ArrayList();
  6. list.add( “first” );
  7. list.add( “second” );
  8. JSONArray jsonArray2 = JSONArray.fromObject( list );
  9. System.out.println( jsonArray2 );
  10. // prints [“first”,”second”]
  11. JSONArray jsonArray3 = JSONArray.fromObject( “[‘json’,’is’,’easy’]” );
  12. System.out.println( jsonArray3 );
  13. // prints [“json”,”is”,”easy”]

2、Map

Java代码
  1. Map map = new HashMap();
  2. map.put( “name”“json” );
  3. map.put( “bool”, Boolean.TRUE );
  4. map.put( “int”new Integer(1) );
  5. map.put( “arr”new String[]{“a”,“b”} );
  6. map.put( “func”“function(i){ return this.arr[i]; }” );
  7. JSONObject json = JSONObject.fromObject( map );
  8. System.out.println( json );
  9. //{“func”:function(i){ return this.arr[i]; },”arr”:[“a”,”b”],”int”:1,”name”:”json”,”bool”:true}

3、BEAN

Java代码
  1. /**
  2. * Bean.java
  3. private String name = “json”;
  4. private int pojoId = 1;
  5. private char[] options = new char[]{‘a’,’f’};
  6. private String func1 = “function(i){ return this.options[i]; }”;
  7. private JSONFunction func2 = new JSONFunction(new String[]{“i”},”return this.options[i];”);
  8. */
  9. JSONObject jsonObject = JSONObject.fromObject( new JsonBean() );
  10. System.out.println( jsonObject );
  11. //{“func1″:function(i){ return this.options[i]; },”pojoId”:1,”name”:”json”,”options”:[“a”,”f”],”func2″:function(i){ return this.options[i]; }}

4、BEANS

Java代码
  1. /**
  2. * private int row ;
  3. private int col ;
  4. private String value ;
  5. *
  6. */
  7. List list = new ArrayList();
  8. JsonBean2 jb1 = new JsonBean2();
  9. jb1.setCol(1);
  10. jb1.setRow(1);
  11. jb1.setValue(“xx”);
  12. JsonBean2 jb2 = new JsonBean2();
  13. jb2.setCol(2);
  14. jb2.setRow(2);
  15. jb2.setValue(“”);
  16. list.add(jb1);
  17. list.add(jb2);
  18. JSONArray ja = JSONArray.fromObject(list);
  19. System.out.println( ja.toString() );
  20. //[{“value”:”xx”,”row”:1,”col”:1},{“value”:””,”row”:2,”col”:2}]

5、String to bean

Java代码
  1. String json = “{name=\”json\”,bool:true,int:1,double:2.2,func:function(a){ return a; },array:[1,2]}”;
  2. JSONObject jsonObject = JSONObject.fromString(json);
  3. Object bean = JSONObject.toBean( jsonObject );
  4. assertEquals( jsonObject.get( “name” ), PropertyUtils.getProperty( bean, “name” ) );
  5. assertEquals( jsonObject.get( “bool” ), PropertyUtils.getProperty( bean, “bool” ) );
  6. assertEquals( jsonObject.get( “int” ), PropertyUtils.getProperty( bean, “int” ) );
  7. assertEquals( jsonObject.get( “double” ), PropertyUtils.getProperty( bean, “double” ) );
  8. assertEquals( jsonObject.get( “func” ), PropertyUtils.getProperty( bean, “func” ) );
  9. List expected = JSONArray.toList( jsonObject.getJSONArray( “array” ) );
  10. assertEquals( expected, (List) PropertyUtils.getProperty( bean, “array” ) );
Java代码
  1. String json = “{\”value\”:\”xx\”,\”row\”:1,\”col\”:1}”;
  2. JSONObject jsonObject = JSONObject.fromString(json);
  3. JsonBean2 bean = (JsonBean2) JSONObject.toBean( jsonObject, JsonBean2.class );
  4. assertEquals( jsonObject.get( “col” ),new Integer( bean.getCol())   );
  5. assertEquals( jsonObject.get( “row” ), new Integer( bean.getRow() ) );
  6. assertEquals( jsonObject.get( “value” ), bean.getValue() );

6 json to xml
1)
JSONObject json = new JSONObject( true );
String xml = XMLSerializer.write( json );

<o null=”true”>

2)
JSONObject json = JSONObject.fromObject(“{\”name\”:\”json\”,\”bool\”:true,\”int\”:1}”);
String xml = XMLSerializer.write( json );
<o>
<name type=”string”>json</name>
<bool type=”boolean”>true</bool>
<int type=”number”>1</int>
</o>
<o>
<name type=”string”>json</name>
<bool type=”boolean”>true</bool>
<int type=”number”>1</int>
</o>
3)
JSONArray json = JSONArray.fromObject(“[1,2,3]”);
String xml = XMLSerializer.write( json );
<a>
<e type=”number”>1</e>
<e type=”number”>2</e>
<e type=”number”>3</e>
</a>

7 、xml to json
<a>
<e type=”function” params=”i,j”>
return matrix[i][j];
</e>
</a>
<a>
<e type=”function” params=”i,j”>
return matrix[i][j];
</e>
</a>

JSONArray json = (JSONArray) XMLSerializer.read( xml );
System.out.println( json );
// prints [function(i,j){ return matrix[i][j]; }]

 

对象的序列化和反序列化

当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。

把Java对象转换为字节序列的过程称为对象的序列化

把字节序列恢复为Java对象的过程称为对象的反序列化

对象的序列化主要有两种用途:

1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;

2) 在网络上传送对象的字节序列。

一. JDK类库中的序列化API

java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。

java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。、

只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以采用默认的序列化方式 。

对象序列化包括如下步骤:

1) 创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;

2) 通过对象输出流的writeObject()方法写对象。

对象反序列化的步骤如下:

1) 创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;

2) 通过对象输入流的readObject()方法读取对象。

下面让我们来看一个对应的例子,类的内容如下:

import java.io.*;

import java.util.Date;

/**

* 对象的序列化和反序列化测试类.

* @author <a href=”mailto:xiexingxing1121@126.com”>AmigoXie</a>

* @version 1.0

* Creation date: 2007-9-15 – 下午21:45:48

*/

public class ObjectSaver {

/**

* @param args

* @author <a href=”mailto:xiexingxing1121@126.com”>AmigoXie</a>

* Creation date: 2007-9-15 – 下午21:45:37

*/

public static void main(String[] args) throws Exception {

ObjectOutputStream out = new ObjectOutputStream

(new FileOutputStream(“D:””objectFile.obj”));

//序列化对象

Customer customer = new Customer(“阿蜜果”, 24);

out.writeObject(“你好!”);

out.writeObject(new Date());

out.writeObject(customer);

out.writeInt(123); //写入基本类型数据

out.close();

//反序列化对象

ObjectInputStream in = new ObjectInputStream

(new FileInputStream(“D:””objectFile.obj”));

System.out.println(“obj1=” + (String) in.readObject());

System.out.println(“obj2=” + (Date) in.readObject());

Customer obj3 = (Customer) in.readObject();

System.out.println(“obj3=” + obj3);

int obj4 = in.readInt();

System.out.println(“obj4=” + obj4);

in.close();

}

}

class Customer implements Serializable {

private String name;

private int age;

public Customer(String name, int age) {

this.name = name;

this.age = age;

}

public String toString() {

return “name=” + name + “, age=” + age;

}

}

输出结果如下:

obj1=你好!

obj2=Sat Sep 15 22:02:21 CST 2007

obj3=name=阿蜜果, age=24

obj4=123

因此例比较简单,在此不再详述。

二.实现Serializable接口

ObjectOutputStream只能对Serializable接口的类的对象进行序列化。默认情况下,ObjectOutputStream按照默认方式序列化,这种序列化方式仅仅对对象的非transient的实例变量进行序列化,而不会序列化对象的transient的实例变量,也不会序列化静态变量。

当ObjectOutputStream按照默认方式反序列化时,具有如下特点:

1)              如果在内存中对象所属的类还没有被加载,那么会先加载并初始化这个类。如果在classpath中不存在相应的类文件,那么会抛出ClassNotFoundException;

2)              在反序列化时不会调用类的任何构造方法。

如果用户希望控制类的序列化方式,可以在可序列化类中提供以下形式的writeObject()和readObject()方法。

private void writeObject(java.io.ObjectOutputStream out) throws IOException

private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;

当ObjectOutputStream对一个Customer对象进行序列化时,如果该对象具有writeObject()方法,那么就会执行这一方法,否则就按默认方式序列化。在该对象的writeObjectt()方法中,可以先调用ObjectOutputStream的defaultWriteObject()方法,使得对象输出流先执行默认的序列化操作。同理可得出反序列化的情况,不过这次是defaultReadObject()方法。

有些对象中包含一些敏感信息,这些信息不宜对外公开。如果按照默认方式对它们序列化,那么它们的序列化数据在网络上传输时,可能会被不法份子窃取。对于这类信息,可以对它们进行加密后再序列化,在反序列化时则需要解密,再恢复为原来的信息。

默认的序列化方式会序列化整个对象图,这需要递归遍历对象图。如果对象图很复杂,递归遍历操作需要消耗很多的空间和时间,它的内部数据结构为双向列表。

在应用时,如果对某些成员变量都改为transient类型,将节省空间和时间,提高序列化的性能。

三. 实现Externalizable接口

Externalizable接口继承自Serializable接口,如果一个类实现了Externalizable接口,那么将完全由这个类控制自身的序列化行为。Externalizable接口声明了两个方法:

public void writeExternal(ObjectOutput out) throws IOException

public void readExternal(ObjectInput in) throws IOException , ClassNotFoundException

前者负责序列化操作,后者负责反序列化操作。

在对实现了Externalizable接口的类的对象进行反序列化时,会先调用类的不带参数的构造方法,这是有别于默认反序列方式的。如果把类的不带参数的构造方法删除,或者把该构造方法的访问权限设置为private、默认或protected级别,会抛出java.io.InvalidException: no valid constructor异常。

四. 可序列化类的不同版本的序列化兼容性

凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量:

private static final long serialVersionUID;

以上serialVersionUID的取值是Java运行时环境根据类的内部细节自动生成的。如果对类的源代码作了修改,再重新编译,新生成的类文件的serialVersionUID的取值有可能也会发生变化。

类的serialVersionUID的默认值完全依赖于Java编译器的实现,对于同一个类,用不同的Java编译器编译,有可能会导致不同的serialVersionUID,也有可能相同。为了提高哦啊serialVersionUID的独立性和确定性,强烈建议在一个可序列化类中显示的定义serialVersionUID,为它赋予明确的值。显式地定义serialVersionUID有两种用途:

1)              在某些场合,希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有相同的serialVersionUID;

2)              在某些场合,不希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有不同的serialVersionUID。

 

JAVA IO流小结

回调(又称为callback):可以理解为一个接口提供一些方法给其他类用,但同时其他类在调用它时,它又调用其他类给它的条件(重写)。

单独一个随机访问文件类: RondomAccessFile类允许随机访问文件同时拥有读和写的功能。
其中方法: close(),read(),writer(),seek(),getFilePointer()这需要注意:这是在有seek()前提下。
流:

一.I/O 流(java 如何实现与外界数据的交流)

流定义:

任何有能力产出数据的数据源对象或者有能力接收数据的数据源对象。他屏蔽了实际的I/O设备处理数据的细节.

1.Input/Output:指跨越出了JVM 的边界,与外界数据的源头或者目标数据源进行数据交换。

2.流的分类

按流向分为输入流和输出流;

按传输单位分为字节流(Stream)结尾的和字符流(Reader和Writer);

按功能还可以分为节点流和过滤流。

节点流:负责数据源和程序之间建立连接;(相当于裸枪)

过滤流:用于给节点增加功能。(相当于功能零部件)

过滤流的构造方式是以其他流位参数构造(这样的设计模式称为装饰模式)。

注:I/O流是一类很宝贵的资源,使用完后必须调用close()方法关闭流并释放资源。在关闭流时只用关闭最外层的流。

3.File 类(java.io.*)可表示一个文件,也有可能是一个目录(在JAVA 中文件和目录都属于这个类中,而且区分不是非常的明显

4.Java.io 下的方法是对磁盘上的文件进行磁盘操作,但是无法读取文件的内容。
注意:创建一个文件对象和创建一个文件在JAVA 中是两个不同的概念。前者是在虚拟机中创建了一个文件,但却并没有将它真正地创建到OS 的文件系统中,随着虚拟机的关闭,这个创建的对象也就消失了。
而创建一个文件才是在系统中真正地建立一个文件。

二.File类:

我们猛看起来像是文件,其实他也可以指代一个文件集,当作为文件集时我们可以对此调用List方法。

这个类的常用构造有:File(“路径”),File(“前边路径”,“后边路径”)File(File,“路径”)

这个类的常用方法:exists(),delete(),getName(),getPath(),isDirectory(),isFile(),length(),
listFile(FileFilter),主要用来过滤文件这里有(可以用来嵌套内部类)mkdir(),mkdirs(),toString(),
FileFilter接口只有accept方法,其返回值为Boolean型,可以在其里边写一些正则表达式来对文件进行筛选。这里需要注意的是传入accept的参数必须是final类型(匿名内部类的要求),这样他才能使用该类范围之外的队像。

顺便讲讲:内部类优点 高聚拢性,缺点在于不易阅读,谨慎使用。

三. 字节流:

InputStream/OutputStream 所有输入输入流的父类,是抽象类。

子类有:

FileInputStream/FileOutputStream(节点流)(注意FileInputStream(path名,boolean)Boolean为true 表示拼接)

DataInputStream/DataOutputStream 数据输入流允许应用程序以与”机器无关方式”从底层输入流中读取基本 Java 数据类型 (8种基本类型,加一种String)读入写出时类型必须一致

BufferedInputStream/BufferedOutputStream 字节缓冲流 用于给节点流增加一个缓冲的功能。(典型的牺牲空间换时间)

1.字节输入流:io包中的InputStream为所有字节输入流的父类。

Int read();读入一个字节(每次一个);

可先使用new byte[]=数组,调用read(byte[] b)

read (byte[])返回值可以表示有效数;read (byte[])返回值为-1 表示结束。

2.在流中close()方法由程序员控制。因为输入输出流已经超越了JVM的边界,所以有时可能无法回收资源。

原则:凡是跨出虚拟机边界的资源都要求程序员自己关闭,不要指望垃圾回收。

四、字节流的字符编码:

字符编码把字符转换成数字存储到计算机中,按ASCii 将字母映射为整数。
把数字从计算机转换成相应的字符的过程称为解码。
乱码的根源在于编解码方式不统一。在世界上任何一种编码方式中都会向上兼容ASCII码。所以英文没有乱码。
编码方式的分类:
ASCII(数字、英文):1 个字符占一个字节(所有的编码集都兼容ASCII)
ISO8859-1(欧洲):1 个字符占一个字节
GB-2312/GBK:1 个字符占两个字节。GB代表国家标准。
GBK是在GB-2312上增加的一类新的编码方式,也是现在最常用的汉字编码方式。
Unicode: 1 个字符占两个字节(网络传输速度慢)
UTF-8:变长字节,对于英文一个字节,汉字三个字节。
原则:保证编解码方式的统一,才能不至于出现错误。
I/O学习种常范的两个错误 1。忘了加flush2.没有加换行。

五。字符流

Reader/Writer所有字符流的父类

其子类有

InputStreamReader/OutputStreamWriter 称为从字节流到字符流的桥转换类。这个类可以设定字符转换方式

FileReader/FileWriter (FileInputStream/FileOutputStream和InputStreamReader/OutputStreamWriter)的组合,只能是本地默认编码

Bufferedreader/BufferedWriter 字符缓冲流,其特有方法readLine()读取一个文本行,newLine()表示Writer到下一个文本行

六 。
一.对象序列化
1. 定义:把一个对象通过I/O流写到文件(持久性介质)上的过程叫做对象的序列化。
2. 序列化接口:Serializable
此接口没有任何的方法,这样的接口称为标记接口。
3. 不是所有对象都能序列化的,只有实现了Serializable的类,他的实例对象才是可序列化的。
4. 在Java种定义了一套序列化规范,对象的编码和解码方式都是已经定义好的。
5. class ObjectOutputStream 和ObjectInputStream也是过滤流,使节点流直接获得输出对象。
ganbin@tarena.com.cn
最有用的方法:
(1)writeObject(Object b)
(2)readObject();该方法返回的是读到的一个对象,但是需要我们注意的是,该方法不会以返回null表示读到文件末尾。
而是当读到文件末尾时会抛出一个IOException;
6. 序列化一个对象并不一定会序列化该对象的父类对象
7. 瞬间属性(临时属性)不参与序列化过程。
8. 所有属性必须都是可序列化的,特别是当有些属性本身也是对象的时候,要尤其注意这一点。序列化的集合就要求集合中的每一个元素都是可序列化的。
9. 用两次序列化把两个对象写到文件中去(以追加的方式),
和用一次序列化把两个对象写进文件的大小是不一样的。
因为每次追加时都会要在文件中加入一个开始标记和结束标记。所以对于对象的序列化不能以追加的方式写到文件中。

URL有空格问题处理

URL mUrl = getClass().getClassLoader().getResource(subDir)

File file = new File(mUrl.getPath());

返回有空格的地址时候去出现问题的。

 

处理方法:

URI mUri =  getClass().getClassLoader().getResource(subDir).toURI();

File file = new File(mUri.getPath());

这样需要对URISyntaxException异常进行处理