2008-11-26

Java中的MD5的使用

  一般来说定长度输出只需要用hash方法就可以了,不过有时候需要用md5的值来进行一些特别的处理工作,所以要用到它,自己写md5比较麻烦,所以可以用java.security包里面的东西。以下是网上搜到的一个范例:


  1. public class HashUtils {
  2. /**
  3. * 文件SHA-1 Hash值生成器
  4. *
  5. * @param in
  6. * @return
  7. * @throws Exception
  8. */
  9. public static String generateFileSHA1(String fileUrl) throws Exception {
  10. InputStream in = new BufferedInputStream(new FileInputStream(fileUrl));
  11. MessageDigest md = MessageDigest.getInstance("SHA-1");
  12. byte[] buffer = new byte[8192];
  13. int length = -1;
  14. while ((length = in.read(buffer)) != -1) {
  15. md.update(buffer, 0, length);
  16. }
  17. return StringBytesTransformUtils.bytesToHexString(md.digest());
  18. }
  19. /**
  20. * 文件MD5 Hash值生成器
  21. *
  22. * @param fileUrl
  23. * @return
  24. * @throws Exception
  25. */
  26. public static String generateFileMD5(String fileUrl) throws Exception {
  27. InputStream in = new BufferedInputStream(new FileInputStream(fileUrl));
  28. MessageDigest md = MessageDigest.getInstance("MD5");
  29. byte[] buffer = new byte[8192];
  30. int length = -1;
  31. while ((length = in.read(buffer)) != -1) {
  32. md.update(buffer, 0, length);
  33. }
  34. return StringBytesTransformUtils.bytesToHexString(md.digest());
  35. }
  36. }

2008-11-23

Solaris下php+curl编译

  由于需要重新规划服务器的管理,所以,我们需要按照一定要求重新编译PHP。
在Solaris下编译php需要以下软件包的支持:

gcc
make
flex
bison
m4
autoconf
automake
perl
gzip
tar
GNU sed

此外,根据需求我还增加了这些软件包:

libiconv
libidn
openssl-0.9.8i
curl
expat
fontconfig
freetype
gd
libiconv
jpeg
mysql
libpng
sasl
libxml2
zlib
xpm

我的编译参数是这样:

./configure --prefix=/usr/php --with-mysql=/usr/mysql/ --with-mysqli=/opt/Webservices/mysql/bin/mysql_config --with-apxs2=/usr/httpd/bin/apxs --with-apache=/usr/httpd/ --enable-fastcgi --with-zilb=shared --with-gd=shared --with-curl=shared --with-curlwrappers=shared --with-libxml-dir=/usr/local/ --with-openssl-dir=/usr/local/ssl/ --enable-ftp --with-jpeg-dir=/usr/local/ -with-png-dir=/usr/local/ --with-xpm-dir=/usr/local/ --with-freetype-dir=/usr/local/ --enable-gd-native-ttf --enable-zip

在网上搜到with-mysqli和enable-embedded-mysqlii同时用会出错,所以我就没有测试了
这样编译完成后记得make test通过了就ok。接下来就可以了。
如果你希望不重新编译php就添加curl模块则看下面这段文章
在Wordpress中启用插件Flickr Photo Album for WordPress时,需要系统支持cURL。大多数资料里都是比较简单的方法,即在编译php时加上cURL支持但由于我的系统里已经安装有php,并且有一些其他配置,重新安装太麻烦于是找到了这篇《linux php 扩展库编译》,验证通过,转载以记录一下以php curl 扩展库编译为例。
假如原先编译的php目录在/oracle/php4目录下;apache在/oracle/apache2目录下;php源代码在/home/wugw目录下。如果实际目录与假定的目录不一致,则在下面的命令中做调整。
1. 找到当前运行的php版本的源代码目录,如 php-4.4.7。进入curl扩展库目录。$cd /home/wugw/php-4.4.7/ext/curl
2. 调用phpize程序生成编译配置文件。$/oracle/php4/bin/phpize
3. 编译扩展库,分别执行下面的configure和make命令。$./configure –with-php-config=/oracle/php4/bin/php-config
##configure这一步执行通过后,再执行make命令,如果configure执行不通过,则查找错误原因。$make
##make成功执行后,生成的扩展库文件在当前目录的 modules 子目录下,如 /home/wugw/php-4.4.7/ext/curl/modules/curl.so
4. 配置php.ini文件##将编译好的扩展库文件复制到apache2 modules目录下。$cp /home/wugw/php-4.4.7/ext/curl/modules/curl.so /oracle/apache2/modules/.
##找到php.ini文件所在目录位置,然后编辑。可以通过查看phpinfo信息来确定php.ini文件位置。##在php.ini文件中找到设置扩展目录的位置,然后将扩展路径设置到apache2 modules目录下extension_dir = “/oracle/apache2/modules/”
##在php.ini的设置扩展库位置,设置要添加的扩展库。extension=curl.so
##以后如果还要添加别的扩展库的话,则只需先将php扩展库编译好,然后copy到apache2 modules目录下,##然后再在这个位置,另取一行将编译后的扩展库文件名加上即可
5. 重启apache,查看phpinfo信息,即可看到刚才添加进去的curl扩展库。

2008-11-17

apache的两种虚拟主机配置

  Apache有两种配置虚拟主机的方法,一种是基于IP的,一种是基于域名的。一下是官方文档中的说明:
  术语"虚拟主机"是指在一个机器上运行多个网站(比如:www.company1.com和www.company2.com)。如果每个网站拥有不同的IP地址,则虚拟主机可以是"基于IP"的;如果只有一个IP地址,也可以是"基于主机名"的,其实现对最终用户是透明的。
Apache是率先支持基于IP的虚拟主机的服务器之一。1.1及其更新版本同时支持基于IP和基于主机名的虚拟主机,今后,不同的虚拟主机有时会被称为"基于主机"或"非IP虚拟主机"。


基于域名的虚拟主机和基于IP的虚拟主机比较
  基于IP的虚拟主机使用连接的IP地址来决定相应的虚拟主机。这样,你就需要为每个虚拟主机分配一个独立的IP地址。而基于域名的虚拟主机是根据客户端提交的HTTP头中标识主机名的部分决定的。使用这种技术,很多虚拟主机可以共享同一个IP地址。
  基于域名的虚拟主机相对比较简单,因为你只需要配置你的DNS服务器将每个主机名映射到正确的IP地址,然后配置Apache HTTP服务器,令其辨识不同的主机名就可以了。基于域名的服务器也可以缓解IP地址不足的问题。所以,如果没有特殊原因使你必须使用基于IP的虚拟主机,您最好还是使用基于域名的虚拟主机。下列情况下,你可能会想要使用基于IP的虚拟主机:

  • 一些古董级的客户端与基于域名的虚拟主机不兼容。为了与基于域名的虚拟主机兼容,客户端必须发送"Host"头。HTTP/1.1规范中对此做了要求。而所有现在常见的仅支持HTTP/1.0的旧版本浏览器都以附加的方式实现了这个要求。如果你又想支持这些老浏览器,又想使用基于域名的虚拟主机。我们提供了一个技术方案,你可以在本文末尾看到它。
  • SSL协议先天特性决定了基于域名的虚拟主机无法成为SSL安全服务器。
  • 一些操作系统和网络设备实现的带宽管理技术无法在多个主机共享一个IP的情况下区别它们。

因为我只需要配置基于域名的虚拟主机,所以就只参考了这部分内容,其余部分可以参考文档:http://eduunix.ccut.edu.cn/index2/man/apache2/vhosts/index.html

  为了使用基于域名的虚拟主机,你必须指定服务器IP地址(和可能的端口)来使主机接受请求,这个可以用NameVirtualHost指令来进行配置。如果服务器上所有的IP地址都会用到,你可以用"*"作为NameVirtualHost的参数。如果你打算使用多端口(如运行SSL)你必须在参数中指定一个端口号,比如"*:80"。请注意,在NameVirtualHost指令中指定IP地址并不会使服务器自动侦听那个IP地址。请参阅设置Apache使用的地址和端口一章获取更多详情。另外,这里设定的IP地址必须对应服务器上的一个网络接口。
  下一步就是为每个虚拟主机建立段。的参数与NameVirtualHost的参数必须是一样的(比如说,一个IP地址或"*"代表的所有地址)。在每个段中,至少要有一个ServerName指令来指定伺服哪个主机和一个DocumentRoot指令来说明这个主机的内容位于文件系统的什么地方。

取消中心主机(Mainhost)
如果你想在现有的web服务器上增加虚拟主机,你必须也为现存的主机建造一个定义块。这个虚拟主机中ServerName和DocumentRoot所包含的内容应该与全局的ServerName和DocumentRoot保持一致。还要把这个虚拟主机放在配置文件的最前面,来让它扮演默认主机的角色。

  比如说,假设你正在为域名www.domain.tld提供服务,而你又想在同一个IP地址上增加一个名叫www.otherdomain.tld的虚拟主机,你只需在httpd.conf中加入以下内容:
NameVirtualHost *:80ServerName www.domain.tldServerAlias domain.tld *.domain.tldDocumentRoot /www/domainServerName www.otherdomain.tldDocumentRoot /www/otherdomain
当然,你可以用一个固定的IP地址来代替NameVirtualHost指令中的"*"号,以达到一些特定的目的。比如说,你可能会希望在一个IP地址上运行一个基于域名的虚拟主机,而在另外一个IP地址上运行一个基于IP的或是另外一套基于域名的虚拟主机。
很多服务器希望自己能通过不只一个域名被访问。我们可以把ServerAlias指令放入小节中来解决这个问题。比如说在上面的第一个配置段中ServerAlias指令中列出的名字就是用户可以用来访问同一个web站点的其它名字:
ServerAlias domain.tld *.domain.tld
这样,所有对域domain.tld的访问请求都将由虚拟主机www.domain.tld处理。通配符标记"*"和"?"可以用于域名的匹配。当然你不能仅仅搞个名字然后把它放到ServerNameServerAlias里就算完了。你必须先在你的DNS服务器上进行配置,将这些名字和您服务器上的一个IP地址建立映射关系。
最后,你可以把其他一些指令放入段中,以更好的配置一个虚拟主机。大部分指令都可以放入这些段中以改变相应虚拟主机配置。如果您想了解一个特定的指令是否可以这样运用,请参见指令的作用域。主服务器(main server)范围内的配置指令(在所有配置段之外的指令)仅在它们没有被虚拟主机的配置覆盖时才起作用。
这样,当一个请求到达的时候,服务器会首先检查它是否使用了一个能和NameVirtualHost相匹配的IP地址。如果能够匹配,它就会查找每个与这个IP地址相对应的段,并尝试找出一个与请求的主机名相同的ServerNameServerAlias配置项。如果找到了,它就会使用这个服务器。否则,将使用符合这个IP地址的第一个列出的虚拟主机。
综上所述,第一个列出的虚拟主机充当了默认虚拟主机的角色。当一个IP地址与NameVirtualHost指令中的配置相符的时候,主服务器中的DocumentRoot将永远不会被用到。所以,如果你想创建一段特殊的配置用于处理不对应任何一个虚拟主机的请求的话,你只要简单的把这段配置放到段中,并把它放到配置文件的最前面就可以了。,

我配置的例子:



NameVirtualHost 10.2.3.4:80
<VirtualHost 10.2.3.4:80>

NameVirtualHost 10.2.3.4:80
<VirtualHost 10.2.3.4:80>
DocumentRoot /home/testroot
ServerName test.test.test.com
ErrorLog logs/test.test.test.com_err_log
TransferLog logs/test.test.test.com_access_log
</VirtualHost>

<VirtualHost 10.2.3.4:80>
DocumentRoot /home/testroot/bbs
ServerName tttt.test.test.com
ErrorLog logs/tttt.test.test.com_err_log
TransferLog logs/tttt.test.test.com_access_log
</VirtualHost>

2008-11-15

Solaris10 05/08 在服务器上安装的管理 Part.2

  昨天手工之后没有检查,结果今天刚开始配置就遇到问题了,tar不支持gzip,没有make等等,原来安装的时候选了核心组件版本,结果现在很多包都要装过。

  还是老规矩直接上http://www.sunfreeware.com/去下载包,安装就直接用:

pkgadd -d filename

安装好。装好后记得要修改一下系统变量:

vi /etc/profile

添加下面蓝色的

#ident "@(#)profile 1.19 01/03/13 SMI" /* SVr4.0 1.3 */
# The profile that all logins get before using their own .profile.
trap "" 2 3

export LOGNAME PATH

PATH=/usr/local/bin:/usr/local/sbin: /usr/bin:/usr/sbin:/usr/ccs/bin;

expotr PATH


改完以后登录的用户的path都变成上面设置的了,不过如果你su到root的话。他的path却还是/usr/bin /usr/sbin,难度root账户的path设置无效了吗?不是,其实是这样:


如果以root用户身份登录或者用 su - 命令进行切换,则修改 home目录下.profile是管用的. 如果是简单的 用 su 进行切换, 则系统保留除 PATH之外的所有环境变量, PATH被设为 /etc/default/su 中的 SUPATH ,缺省时为/usr/sbin:/usr/bin
所以,如果要让PATH还是你设置的那个你就需要用su -命令来switch user。

此外,一个一定要注意的地方是,默认gun的那些包安装都会把执行文件装到/usr/local/bin下面,而sun自带的相同名称的软件都会放到/usr/bin下面,所以,要谨防因为调用错了程序而导致的奇怪问题。因为我一般都用gun版本的,所以只要保证path里面/usr/local/bin在后者之前即可。

之后编译安装mysql,这里,我遇到的问题是出现了libstdc++.so.6 找不到文件的错误,其实就是make的时候它搜寻的是/usr/lib/libstdc++.so.6但是在Solaris里面,这个文件在/usr/local/libstdc++.so.6,所以只需要做一个软连接就搞定了。

安装完之后,为了能够使用SMF来管理mysql的启动,需要做这些:
在/var/svc/manifest/network目录建立文件mysql.xml内容



<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">

<!-- MySQL Manifest - cuddletech, benr, August 28th, 2005 -->

<service_bundle type='manifest' name='cuddletech:mysql'>

<service
name='application/mysql'
type='service'
version='4'>

<create_default_instance enabled='false'/>

<single_instance/>

<dependency name='fs-local'
grouping='require_all'
restart_on='none'
type='service'>
<service_fmri value='svc:/system/filesystem/local'/>
</dependency>

<exec_method
type='method'
name='start'
exec='/etc/sfw/mysql/mysql.server start'
timeout_seconds='60' />

<exec_method
type='method'
name='stop'
exec='/usr/sfw/bin/mysqladmin shutdown'
timeout_seconds='60' />

<exec_method
type='method'
name='refresh'
exec='/usr/sfw/bin/mysqladmin refresh'
timeout_seconds='60' />

<stability value='Unstable' />

<template>
<common_name>
<loctext xml:lang='C'>MySQL Server</loctext>
</common_name>
<documentation>
<doc_link name='mysql.org'
uri='http://dev.mysql.com/doc/mysql/en/index.html' />
</documentation>
</template>
</service>

</service_bundle>


之后使用svccfg验证并导入配置文件
#svccfg validate /var/svc/manifest/network/mysql.xml
#svccfg import /var/svc/manifest/network/mysql.xml
这样就ok了。
基本的配置mysql:
获得配置文件:
cp /opt/mysql/share/mysql/my-large.cnf /etc/my.cnf
之后初始化数据库:
/opt/mysql/bin/mysql_install_db --user=mysql
之后启动数据库:
/opt/mysql/bin/mysqld_safe --user=mysql &
测试关闭数据库:
/usr/sfw/bin/mysqladm -u root shutdown
如果要使数据库的编码改为utf8
那么
vi /etc/my.cnf
在[client]后面添加一行
default-character-set=utf8
在[mysqld]之后添加同样的一行。
default-character-set=utf8
之后启动以后mysql -uroot
show variables like 'character%';
会显示如下结果
+--------------------------+----------------------------+
Variable_name Value
+--------------------------+----------------------------+
character_set_client utf8
character_set_connection utf8
character_set_database utf8
character_set_filesystem binary
character_set_results utf8
character_set_server utf8
character_set_system utf8
character_sets_dir /usr/share/mysql/charsets/
+--------------------------+----------------------------+
不过可惜的是,这样加使用mysqladmin就会提示
/usr/sfw/bin/mysqladmin: unknown variable 'default-character-set=utf8'
暂时没有去找新的方法。

接下来安装apache,参考之前的一篇文章。装好之后同样为了整合到SMF,这样做:

vi /var/svc/manifest/network/apache2.xml



<?xml version="1.0"?>

<!-- Copyright 2004 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. ident "@(#)http-apache.xml 1.2 04/11/11 SMI" -->

<service_bundle name="SUNWapchr:apache" type="manifest">

<service name="network/http" type="service" version="1">

<!-- Because we may have multiple instances of network/http provided by different implementations, we keep dependencies and methods within the instance. -->

<instance name="apache" enabled="false">
<dependency name="physical" type="service" restart_on="error" grouping="optional_all">
<service_fmri value="svc:/network/physical:default">
</dependency>

<exec_method name="start" type="method" timeout_seconds="60" exec="/etc/init.d/apache start">

<exec_method name="stop" type="method" timeout_seconds="60" exec="/etc/init.d/apache stop">

<exec_method name="refresh" type="method" timeout_seconds="60" exec="/etc/init.d/apache restart">

<property_group name="httpd" type="application">
<stability value="Evolving">
<propval name="ssl" type="boolean" value="false">
</property_group>

<property_group name="startd" type="framework">
<!-- sub-process core dumps shouldn't restart session -->
<propval name="ignore_error" type="astring" value="core,signal">
</property_group>

</instance>

<stability value="Evolving">

<template>
<common_name>
<loctext lang="C">
Apache HTTP server
</loctext>
</common_name>
<documentation>
<manpage title="apache" section="1M">
<doc_link name="apache.org" uri="http://httpd.apache.org">
</documentation>
</template>
</service>

</service_bundle>



之后导入svccfg:
# svccfg validate /var/svc/manifest/network/apache2.xml
# svccfg import /var/svc/manifest/network/apache2.xml

2008-11-14

Solaris10 命令行下卸载StarSuit

  因为装了些没用的东西,所以现在要卸载,在命令行下,要做到这个,我们需要做一些工作:
这是官方给的说明文件:
De-Installation
Do not delete the StarOffice files from the file system. We strongly recommend to use the StarOffice Java setupor the pkgrm tool to de-install StarOffice. The Solaris package repository would become inconsistent when youremove the StarOffice files via rm -r .

  • Become root if necessary
    su -
  • Create a file 'so_packages' with all StarOffice related Solaris packages
    pkginfo -x cut -f1 -d " " grep staroffice > /tmp/so_packages
  • For a silent installation of StarOffice it is necessary to create an admin file. This avoids recurringqueries at the installation.
    echo action=nocheck > /tmp/admin
    echo conflict=nocheck >> /tmp/admin
    echo rdepend=nocheck >> /tmp/admin
  • Remove all packages listed in the file
    pkgrm -a /tmp/admin -n `cat /tmp/so_packages`
  • There are a number of packages in the StarOffice installation set does not use the term 'staroffice'.These packages including a font server (SUNWfreetype2) and an Ababas D database server(SUNWadabas). To remove these packages :
    pkgrm SUNWfreetype2 SUNWadabas
    Depending on your Java environment you have to deinstall following three packages which includingthe Java Runtime Environment which was installed by the StarOffice installer. De-Installing thesepackages could damage you Java environment.
    pkgrm SUNWj5rt SUNWj5man SUNWj5cfg

Solaris10 05/08 在服务器上安装的管理 Part.1

  之前一直使用01/08版的,这次为了直接支持ZFS boot特地弄了个05/08版的,结果变化还真不少,而且能在核心机房的时间不多,所以还是需要一些配置的。
  安装过程之中设置好网络,装好后立马把SSH配置调整好,之后立马添加普通用户:
useradd -u 22222 -g adm -d /export/home/testuser -m -s /usr/bin/bash testuser
  这样一来就可以远程用SSH登录了,记得修改一下root账户的默认shell
vi /etc/passwd
  之后收起光盘走人了。。。。

DNS配置
  回到自己的机器上,SSH过去,好了,现在我们开始修改吧。首先,有时候你会发现,虽然在安装过程中指定了DNS服务器,但是在实际装好后DNS用的/etc/resolv.conf这个文件更本不存在。据说这是Solaris 2系列历史上遗留下来的毛病,即安装过程中你可以指定 DNS服务器 和 默认路由,但他不会自动保存。必须在安装完成系统之后手工建立和设定/etc/resolv.conf 和 /etc/defaultrouter 两个文件。不过我这里倒是有后者。
  要使DNS生效,还需要一番配置,首先是resolv.conf文件:
vi /etc/resolv.conf
--------------------------content to be added--------------------------------
; Sample resolv.conf file for the machine polaris
domain doc.com
; try local name server
nameserver 127.0.0.1
; if local name server down, try these servers
nameserver 123.45.6.1
nameserver 111.22.3.5
; sort the addresses returned by gethostbyname(3c)
sortlist
130.155.160.0/255.255.240.0
130.155.0.0
--------------------------------------------------------------------------

以上内容是从docs.sun.com转来的范例,注意domain后面的域名必须马上回车不允许任何空白字符出现。一般如果只需制定dns服务器的话只用nameserver。
编辑完后保存,下一步,编辑/etc/nsswitch.conf找到host这一行改成这样:
hosts: files dns
当然,根据使用的名字服务不同官方给出的配置是这样的:
-----------------------------------------------------------------------------
Specify DNS as a source of hosts information.
DNS can be the only source or an additional source for the hosts information. Locate the hosts line and use DNS in one of the ways shown below:
hosts: files dns
or
hosts: nisplus dns [NOTFOUND=return] files
or
hosts: dns nisplus [NOTFOUND=return] files
Do not use the above syntax for NIS clients, since they will be forced to search for unresolved names twice in DNS.
----------------------------------------------------------------------

最后启动服务:
svcadm enable network/dns/client
这样就可以使用DNS了。
Solaris解析域名的顺序是这样的:

  1. 查询/etc/nsswitch.conf以确定解析顺序,因为之前我们制定的是file dns ,所以先根据本地配置来查询,之后才是dns服务器,因此接下来
  2. 查询/etc/hosts如果没有再下来
  3. 从/etc/resolv.conf查询dns服务器和搜索顺序。之后提交请求。

接下来,由于我发现系统的时间不对。于是同步一下,有两种方法:
rdate time-a.nist.gov
ntpdate time-a.nist.gov


接下来处理一下服务,因为之前我害怕有软件包没有装好,之后还得回来装,所以就安装了entire版本的。现在需要去除一些服务。
online         10:33:13 svc:/application/graphical-login/cde-login:default
online 19:30:36 svc:/network/cde-spc:default
online 10:33:39 svc:/network/rpc/cde-ttdbserver:tcp
online 10:33:39 svc:/network/rpc/cde-calendar-manager:default
online 10:33:41 svc:/application/cde-printinfo:default

第一个cde-login是cde登录的服务,我们只用console,所以关了。
第二个的解释是:The CDE Subprocess Control Service is a network daemon that accepts requests from clients to execute commands and launch applications remotely.貌似它会打开6112端口,我试着关闭了,不影响ssh,所以也disable。
第三个是ToolTalk database server,tooltalk是xstart的一个组件,而这个server干下面这些活
  1. ToolTalk objects specs.
  2. ToolTalk session IDs of sessions with clients that have joined a file using the tt_file_join call.
  3. File-scoped messages that are queued because the message disposition is TT_QUEUED and a handler that can handle the message has not yet been started.

所以也禁用了。

第五个看了就知道没用。

第六个是CDE Print Viewer,The CDE Print Viewer program provides a graphical interface that displays the status of print queues and print jobs。所以也禁用了。

为什么要禁用这些?原因很简单,第一我不用gui 第二,你google一下就会发现这些服务都有漏洞报告,虽然比较早,但是也未必就被修复了。

要管理这些服务在Solaris里面非常方便,直接使用SMF管理。
inetadm :提供观察或配置由 inetd 控制的服务的功能
svcadm :提供执行常见服务管理任务(如启用、禁用或重新启动服务实例)的功能
svccfg :提供显示和处理服务配置系统信息库内容的功能
svcprop :从服务配置系统信息库中检索属性值,并采用适用于 shell 脚本的输出格式
svcs :提供服务配置系统信息库中所有服务实例的服务状态的详细视图

这样稍微处理了一下之后系统就干净了。可以开始接下来的工作了。

2008-11-12

一篇关于raidz配置的文章

  WHEN TO (AND NOT TO) USE RAID-Z


RAID-Z is the technology used by ZFS to implement a data-protection scheme
which is less costly than mirroring in terms of block
overhead.

Here, I'd like to go over, from a theoretical standpoint, the
performance implication of using RAID-Z. The goal of this technology
is to allow a storage subsystem to be able to deliver the stored data
in the face of one or more disk failures. This is accomplished by
joining multiple disks into a N-way RAID-Z group. Multiple RAID-Z
groups can be dynamically striped to form a larger storage pool.

To store file data onto a RAID-Z group, ZFS will spread a filesystem
(FS) block onto the N devices that make up the group. So for each FS
block, (N - 1) devices will hold file data and 1 device will hold
parity information. This information would eventually be used to
reconstruct (or resilver) data in the face of any device failure. We
thus have 1 / N of the available disk blocks that are used to store
the parity information. A 10-disk RAID-Z group has 9/10th of the
blocks effectively available to applications.

A common alternative for data protection, is the use of mirroring. In
this technology, a filesystem block is stored onto 2 (or more) mirror
copies. Here again, the system will survive single disk failure (or
more with N-way mirroring). So 2-way mirror actually delivers similar
data-protection at the expense of providing applications access to
only one half of the disk blocks.

Now let's look at this from the performance angle in particular that
of delivered filesystem blocks per second (FSBPS). A N-way RAID-Z
group achieves it's protection by spreading a ZFS block onto the N
underlying devices. That means that a single ZFS block I/O must be
converted to N device I/Os. To be more precise, in order to acces an
ZFS block, we need N device I/Os for Output and (N - 1) device I/Os for
input as the parity data need not generally be read-in.

Now after a request for a ZFS block has been spread this way, the IO
scheduling code will take control of all the device IOs that needs to
be issued. At this stage, the ZFS code is capable of aggregating
adjacent physical I/Os into fewer ones. Because of the ZFS
Copy-On-Write (COW) design, we actually do expect this reduction in
number of device level I/Os to work extremely well for just about any
write intensive workloads. We also expect it to help streaming input
loads significantly. The situation of random inputs is one that needs
special attention when considering RAID-Z.

Effectively, as a first approximation, an N-disk RAID-Z group will
behave as a single device in terms of delivered random input
IOPS. Thus a 10-disk group of devices each capable of 200-IOPS, will
globally act as a 200-IOPS capable RAID-Z group. This is the price to
pay to achieve proper data protection without the 2X block overhead
associated with mirroring.

With 2-way mirroring, each FS block output must be sent to 2 devices.
Half of the available IOPS are thus lost to mirroring. However, for
Inputs each side of a mirror can service read calls independently from
one another since each side holds the full information. Given a
proper software implementation that balances the inputs between sides
of a mirror, the FS blocks delivered by a mirrored group is actually
no less than what a simple non-protected RAID-0 stripe would give.

So looking at random access input load, the number of FS blocks per
second (FSBPS), Given N devices to be grouped either in RAID-Z, 2-way
mirrored or simply striped (a.k.a RAID-0, no data protection !), the
equation would be (where dev represents the capacity in terms of
blocks of IOPS of a single device):

Random
Blocks Available FS Blocks / sec
---------------- --------------
RAID-Z (N - 1) * dev 1 * dev
Mirror (N / 2) * dev N * dev
Stripe N * dev N * dev


Now lets take 100 disks of 100 GB, each each capable of 200 IOPS and
look at different possible configurations; In the table below the
configuration labeled:

"Z 5 x (19+1)"

refers to a dynamic striping of 5 RAID-Z groups, each group made of 20
disks (19 data disk + 1 parity). M refers to a 2-way mirror and S to a
simple dynamic stripe.


Random
Config Blocks Available FS Blocks /sec
------------ ---------------- ---------
Z 1 x (99+1) 9900 GB 200
Z 2 x (49+1) 9800 GB 400
Z 5 x (19+1) 9500 GB 1000
Z 10 x (9+1) 9000 GB 2000
Z 20 x (4+1) 8000 GB 4000
Z 33 x (2+1) 6600 GB 6600

M 2 x (50) 5000 GB 20000
S 1 x (100) 10000 GB 20000


So RAID-Z gives you at most 2X the number of blocks that mirroring
provides but hits you with much fewer delivered IOPS. That means
that, as the number of devices in a group N increases, the expected
gain over mirroring (disk blocks) is bounded (to at most 2X) but the
expected cost in IOPS is not bounded (cost in the range of [N/2, N]
fewer IOPS).

Note that for wide RAID-Z configurations, ZFS takes into account the
sector size of devices (typically 512 Bytes) and dynamically adjust
the effective number of columns in a stripe. So even if you request a
99+1 configuration, the actual data will probably be stored on much
fewer data columns than that. Hopefully this article will contribute
to steering deployments away from those types of configuration.

In conclusion, when preserving IOPS capacity is important, the size of
RAID-Z groups should be restrained to smaller sizes and one must
accept some level of disk block overhead.

When performance matters most, mirroring should be highly favored. If
mirroring is considered too costly but performance is nevertheless
required, one could proceed like this:

Given N devices each capable of X IOPS.

Given a target of delivered Y FS blocks per second
for the storage pool.

Build your storage using dynamically striped RAID-Z groups of
(Y / X) devices.

For instance:

Given 50 devices each capable of 200 IOPS.

Given a target of delivered 1000 FS blocks per second
for the storage pool.

Build your storage using dynamically striped RAID-Z groups of
(1000 / 200) = 5 devices.

In that system we then would have 20% block overhead lost to maintain
RAID-Z level parity.

RAID-Z is a great technology not only when disk blocks are your most
precious resources but also when your available IOPS far exceed your
expected needs. But beware that if you get your hands on fewer very
large disks, the IOPS capacity can easily become your most precious
resource. Under those conditions, mirroring should be strongly favored
or alternatively a dynamic stripe of RAID-Z groups each made up of a
small number of devices.


ZFS混合存储池特性浅析

  我对磁盘阵列相关的东西不是很熟,但是可惜的是前天正好遇到这个问题,亟需解决,无奈之下思考起了解决方案,但是可惜的是,我的查询zfs和raidz的一些情况的时候要不找到它的原理说明,要不找到配置方法,但是总觉得差什么,就是没办法把整个过程联通起来,最后发现,这些资料都缺乏对整体架构的解释。无奈的在unix-center中求助也没人回答,不过今天正好有人发了一帖倒解决的我的问题,下文即转自此帖:http://www.unix-center.net/bbs/viewthread.php?tid=7053&extra=page%3D1

------------------------------------------
ZFS混合存储池特性浅析

  被称作“史上最后一个文件系统” 的ZFS,作为Solaris 10和OpenSolaris的新特性引进后,吸引了开源社区里无数人的关注,Linux之父Linus Torvalds公开表示对Solaris软件的ZFS(Zettabyte文件系统)特别感兴趣,苹果公司也宣称Mac OSX采用ZFS文件系统。从OpenSolaris 2008.05发布版开始,SUN在ZFS中引进了对Intel® High-Performance Solid State Drives (SSDs)的支持,提供混合存储池(Hybrid Storage Pools),本文将对此进行介绍。

1. 什么是SSD?
  SSD即固态硬盘(solid state disk),SSD由控制单元和存储单元(FLASH芯片)组成,简单的说就是用固态电子存储芯片阵列而制成的硬盘。闪存设备记忆数据不需要电源,而且读写数据的速度非常快,就像 DRAM一样。随着全球电价上涨,以及海量数据存取速度的需求,SSD越来越被看好。
  以下是SSD、HDD的存取速度、单位造价和耗电量的对比,IOPS 即Input/Output Operations PerSecond。

  • SSD:7000 write IOPS, 35000 read IOPS, $2/GB ,15-20w
  • HDD:180 write IOPS, 320 read IOPS ,$30/GB,2.5w
2. 改进存储系统的动机
  计算机系统设计的黄金法则——加快经常性事件(make the common case fast),道理十分明显,使经常性事件的处理速度加快能明显提高整个系统的性能。遵循大师们提出的这一准则,RISC、RAID等大批技术横空出世。前辈们屡试不爽的准则,在ZFS的创新过程中,又一次得到成功验证。
  从下图可以看出,随着多核技术的发展,特别是服务器端多核技术的广泛应用,磁盘存取速度的增长远远跟不上处理器处理速度的增长,整个系统的性能越来越拖累于慢速的磁盘。同时服务器端海里数据存取,产生的大量磁盘操作已经成了经常性事件。磁盘访问已经成为系统的瓶颈,而且数据中心大量磁盘产生的电费也是一笔不菲的成本。


SUN的ZFS+SSD解决方案

解决上述问题有以下一些方案

  • 增加内存缓存一些数据来提高数据存取性能,但是存储容量的增长速度远高于内存容量的增长,并且代价十分高昂。
  • 利用闪存比DRAM便宜且存取速度相当,将闪存设备作为另一层级的存储器引进数据中心。但这会出现转换成本或操作成本,使数据中心产生新的成本开支,面临新的管理纷争。
  可见以上方案均不是很合理,那么如何实现高性能、低能耗、对用户和操作者透明的解决方案呢?答案就是SUN ZFS+SSD混合存储池。

  ZFS+SSD的体系结构如下图,在系统中,使用少量高速SSD作为内存与磁盘的缓存,将经常使用的数据放到快速的缓存,加快了访问速度,同时保留了HDD的大容量存储能力。同时ZFS对SSD进行了无缝整合,可以把SSD 作为文件系统的二级缓存(L2 ARC)以及ZIL(ZFS Intent Log),自动优化系统充分利用快速SSD提供系统读写吞吐率。


ZFS+SSD的体系结构

  1. Read/Write Cache Pool:ZFS利用主存和SSD作为自动伸缩缓存(Adaptive Replacement Cache),并能检测访问模式
  2. ZIL(ZFS Intent Log) Pool:ZFS一般使用NVRAM,SSD(Solid State Disk)作为 ZIL存储池。ZFS是事务型文件系统,对于同步写操作,ZFS为系统中每一个ZFS文件系统维护一个ZIL。同步写操作的数据会先写入ZIL,并且会把磁盘的write cache的数据同步到磁盘上,然后应用的写操作返回。当文件提交命令发生时,ZFS会把ZIL里该文件的数据同步到磁盘上。
  3. DISK Pool:ZFS利用disk pool为文件系统自动分配HDD空间
3. 总结
ZFS文件系统是对传统文件系统的一次革命性的创新设计,ZFS解决了文件系统的完整性、安全性和可伸缩性以及管理困难等重要难题。ZFS文件系统是世界上第一个128位的文件系统,其存储容量和文件数量几乎只受硬件的限制,增加了混合存储池后ZFS功能将更强大,心动了吧,赶紧去装个OpenSolaris体验下吧!
参考文献:

[1] Solaris zfssolutionbrief
http://www.sun.com/software/solaris/pdf/solariszfs_solutionbrief.pdf
[2] Sun Intel flash pitch April 08, Bill Moore
[3] http://blogs.sun.com/jonathan_zh/date/20080620, Jonathan(Sun CEO)

2008-11-07

学习DOM

  虽然大概已经了解了DOM,不过对我来说org.w3c.dom的奇怪扫描方式让我对其易使用性大有疑惑,所以还是必须要学习一下DOM。
  这篇文章是在学习DOM的过程中整理出来的资料:

  DOM 文档是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档并且构造层次结构,然后才能做其他事情。由于它是基于信息层次的,因而 DOM 被认为是基于树基于对象的。
  XML 文件的基本组成部分包括:

  • XML 声明:基本的声明 将这个文件定义为 XML 文档。在声明中指定一种字符编码的情况并不鲜见,如下所示。通过这种方式,不管该 XML 文件使用的语言或字符编码是什么,只要解析器理解特定的编码,它就能够正确地读取该 XML 文件。
  • DOCTYPE 声明:XML 是人机之间交换信息的便利手段,但是要使它能够顺利地工作,必须要有一个公共的词汇表。可选的 DOCTYPE 声明可用于指定一个应该用来与此文件做比较的文档(在本例中为 orders.dtd),以确保不会产生任何混淆或丢失信息(例如,丢失一个 userid 或错误拼写某个元素名称)。以这种方式处理过的文档称为有效的文档。成功的有效性检查并不是 XML 所必需的,后面的例子实际上从文档中省略了 DOCTYPE 声明。
  • 数据本身:XML 文档中的数据必须包含在单个根元素内,比如下面的 orders 元素。要使 XML 文档得到处理,它必须是格式良好的(well-formed)


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ORDERS SYSTEM "orders.dtd">

<orders>

<order>
<customerid limit="1000">12341</customerid>
<status>pending</status>
<item instock="Y" itemid="SA15">
<name>Silver Show Saddle, 16 inch</name>
<price>825.00</price>
<qty>1</qty>
</item>
<item instock="N" itemid="C49">
<name>Premium Cinch</name>
<price>49.00</price>
<qty>1</qty>
</item>
</order>
<order>
<customerid limit="150">251222</customerid>
<status>pending</status>
<item instock="Y" itemid="WB78">
<name>Winter Blanket (78 inch)</name>
<price>20</price>
<qty>10</qty>
</item>
</order>

</orders>

  DOM 本质上是节点的集合。 由于一个文档中可能包含不同类型的信息,因此要定义不同类型的节点。
  

基本的节点类型:文档、原始、属性和文本

XML 中最常见的节点类型包括:

  • 元素:元素是 XML 的基本构造模块。通常,元素拥有子元素、文本节点,或两者的组合。元素节点也是能够拥有属性的唯一节点类型。
  • 属性:属性节点包含关于元素节点的信息,但是并不实际认为是元素的孩子,比如在下面的例子中: <customerid limit="1000">12341</customerid>
  • 文本:文本节点就是名副其实的文本。它可以由更多信息组成,也可以只包含空白。
  • 文档:文档节点是文档中其他所有节点的父亲。
-----------------------------------------
接下来是处理XML文档的说明了:

将文件解析为document

  为了使用 XML 文件中的信息,必须解析文件以创建一个 Document 对象

  Document 对象是一个接口,因而不能直接将它实例化;一般情况下,应用程序会相应使用一个工厂。准确的过程因实现而异,但是基本思想是相同的。(同样,Level 3 标准化了这个任务。)在这个例子 Java 环境中,解析文件是一个三步过程:

  1. 创建 DocumentBuilderFactory。 DocumentBuilderFactory 对象创建 DocumentBuilder。
  2. 创建 DocumentBuilder。 DocumentBuilder 执行实际的解析以创建 Document 对象。
  3. 解析文件以创建 Document 对象。

现在您可以开始构建应用程序了。

一个例子:

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import org.w3c.dom.Document;

public class OrderProcessor {
public static void main (String args[]) {
File docFile = new File("orders.xml");
Document doc = null;
try {

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
doc = db.parse(docFile);

} catch (Exception e) {
System.out.print("Problem parsing the file: "+e.getMessage());
}
}
}

  这里应用程序创建了 DocumentBuilderFactory,然后再使用它来创建 DocumentBuilder。 最后,DocumentBuilder 解析文件以创建 Document。

解析器设置:

  使用 DocumentBuilder 创建解析器的优点之一在于能够控制 DocumentBuilderFactory 创建的解析器上的各种设置。例如,可以设置解析器验证文档:


Java 的 DOM Level 2 实现允许通过以下方法控制解析器的参数:

  • setCoalescing():决定解析器是否要将 CDATA 节点转换为文本,以及是否要和周围的文本节点合并(如果适用的话)。其默认值为 false。
  • setExpandEntityReferences(): 确定是否要展开外部实体引用。如果为 true,外部数据将插入文档。其默认值为 true 。(请参阅参考资料以了解关于使用外部实体的技巧。)
  • setIgnoringComments():确定是否要忽略文件中的注释。其默认值为 false。
  • setIgnoringElementContentWhitespace():确定是否要忽略元素内容中的空白(类似于浏览器对待 HTML 的方式)。其默认值为 false。
  • setNamespaceAware():确定解析器是否要注意名称空间信息。其默认值为 false。
  • setValidating():默认情况下,解析器不验证文档。将这个参数设置为 true 可打开验证功能。

单步调试文档:

  获取根元素:

  一旦解析了文档并创建了一个 Document,应用程序就能单步调试该结构以审核、查找或显示信息。这种导航功能是将要在 Document 上执行的许多操作的基础。

 对文档的单步调试首先从根元素开始。格式良好的文档仅有一个根元素,也称为 DocumentElement。应用程序首先检索这个元素。



import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import org.w3c.dom.Document;

import org.w3c.dom.Element;


public class OrderProcessor {
...
System.exit(1);
}

//STEP 1: Get the root element

Element root = doc.getDocumentElement();
System.out.println("The root element is " + root.getNodeName());

 //STEP 2: Get the children
 NodeList children = root.getChildNodes();
 System.out.println("There are "+children.getLength()
+" nodes in this document.");


//STEP 3: Step through the children
for (Node child = root.getFirstChild();
child != null;
child = child.getNextSibling())
{
System.out.println(start.getNodeName()+" = "
+start.getNodeValue());
}


}
}

获取节点的子节点:

  一旦应用程序确定了根元素,它就把根元素的子节点的列表作为一个 NodeList 来检索。NodeList 类是一系列的项,应用程序将逐个迭代这些项。 在本例中,为简洁起见,应用程序通过仅显示有多少元素出现在结果 NodeList中,从而获取子节点和验证检索结果。

  注意这里的文档仅有两个元素,但是 NodeList 包含五个子节点,包括包含换行的三个文本节点 ―― 还要注意节点和元素在 DOM 中不是等价的。


使用 getFirstChild() 和 getNextSibling():

  父子和兄弟关系提供了迭代某个节点的所有孩子的替代方法,它在某些场合下可能更为适宜,比如在这些关系和孩子的出现顺序对理解数据至关重要的时候。

  在 Step 3 中,for 循环首先从根元素的第一个子节点开始。 应用程序迭代第一个孩子的所有兄弟,直至已全部对它们求值。

  每次应用程序执行该循环,它都要检索一个 Node 对象,输出其名称和值。注意 orders 的五个孩子包括 order 元素和三个文本节点。还要注意元素具有一个 null 值,而不是预期的文本。包含实际内容作为其值的,是作为元素的孩子的文本节点。

  还可以通过使用递归来获取所有节点.此外,需要注意的是,在dom中,属性不是任何节点的子节点。用w3c school提供的图示可以理解:

  当你实际使用dom扫描器去获取document的时候,你会发现它会将element之间的空白也作为一个节点包存在文档树中,本来,按照ibm这篇文章的说法是只要设置了setIgnoringElementContentWhitespace(true)就可以让扫描器无视掉这些空白,但是却没有提到,要让这个功能正常工作还必须要有定义过的dtd文件,同理,Node.normalized()方法也是一样的。关于文档标准化的内容,可以读读这一段:

-----------------------------------------

文档标准化

在 DOM Level 3 中定义的一个新方法是 Document 接口的 normalizeDocument 方法。从方法名可以看出,您可以使用这个方法来标准化文档。在默认情况下,这个方法完成以下工作:

  • 标准化 Text 节点,将相邻的 Text 节点整合为一个 Text 节点。
  • 根据 EntityReference 节点所引用的实体更新它们的内容。
  • 验证和修复文档中的命名空间信息,使命名空间格式是格式良好的。

一定要注意,在这个方法中使用的命名空间标准化算法(在 Appendix B 中定义)只对 namespace-aware 节点起作用,这些节点是使用具有“NS”后缀的方法(例如 createElementNS )创建的。 Namespace unaware 节点,即用 DOM Level 1 方法(如 createElement )创建的节点,与所有依赖于 XML 命名空间的处理不完全兼容。如果在文档中有 DOM Level 1 节点,那么在尝试进行命名空间标准化时, normalizeDocument 会失败并报告一个错误。一般来说,如果希望使用 XML 命名空间,并且要对文档执行任何需要 XML 命名空间支持的操作,那么就不应该用 DOM Level 1 方法创建节点。对于其他的操作,例如针对 XML Schema 重新验证内存中的文档,也是如此。

还可以通过 DOMConfiguration 配置 normalizeDocument ,以便对文档执行其他操作。例如,可以使用这个方法去掉注释,将 CDATASection 节点转换为 Text 节点,或者放弃树中所有命名空间声明属性。还可以通过它一次完成上述所有工作,从而轻松地使文档具有可以自然地映射到 XML Infoset 的形式。下面的程序片段展示了如何用 Document.config 控制 normalizeDocument 。

使用 Document.config 控制 normalizeDocument

// retrieve document configuration
DOMConfiguration config = document.getConfig();
// remove comments from
config.setParameter("comments", false);
// remove namespace declarations
config.setParameter("namespace-declarations", false);
// transform document
core.normalizeDocument();
// put document into a form closest to the XML Infoset
config.setParameter("infoset", true);
// transform document
core.normalizeDocument();

normalizeDocument 方法还允许您用 XML Schema 或者 DTD 对内存中的文档进行重新验证。过去,要在文档修改后对它进行重新验证,必须将它保存为一个文件,再用验证解析器读回去。有了这种新方法,现在就可以通过让 DOM 实现重新验证内存中的文档从而更有效地完成这项工作。为此,首先需要将 DOMConfiguration 的 validate 参数设置为 true 。然后需要实现一个 DOMErrorHandler 对象,验证错误将报告给这个对象,再用 error-handler 参数将这个对象注册到 Document 上。这与对 SAX 解析器所做的工作很类似。最后,可以通过调用 normalizeDocument 检查文档是否有效。

目前,还没有访问 XML Schema Post-Schema Validation Infoset(PSVI)的标准 API。不过,DOM Level 3 允许您获取一些 PSVI 信息。例如,如果希望获得 PSVI 标准化的模式值属性,那么就将 DOMConfiguration 上的 datatype-normalization 和 validate 参数设为“true”,并用经过 XML Schema 标准化的值调用 normalizeDocument 以更新树 ——这意味着文档中属性值和元素内容现在表示的是 PSVI 标准化的模式值属性。

-----------------------------------------

添加节点:

  一般要先构造一个element 并且要把它的值作为子节点append到这个element下。

删除节点:

  直接把要删除的节点remove就可以,子节点会跟着消除


最后就是写入XML文档了。

  如果用递归的方法去遍历文档树是个很不实用的方法。所以看这篇文章:http://www.ibm.com/developerworks/cn/java/l-javaxml/


  在JAXP中所提供的标准的更新原始XML文档的方法就是调用XSLT引擎,亦即使用TransformerFactory和Transformer类。请看下面的Java代码片断:

 //首先创建一个DOMSource对象,该构造函数的参数可以是一个Document对象doc代表更改后的DOM Tree。
DOMSource doms = new DOMSource (doc);

//创建一个File对象,代表DOM Tree所包含的数据的输出介质,这是一个XML文件。
File f = new File ("XMLOutput.xml");
//创建一个StreamResult对象,该构造函数的参数可以取为File对象。
StreamResult sr = new StreamResult (f);
//下面调用JAXP中的XSLT引擎来实现输出DOM Tree中的数据到XML文件中的功能。
//XSLT引擎的输入为DOMSource对象,输出为StreamResut对象。
try
{
//首先创建一个TransformerFactory对象,再由此创建Transformer对象。Transformer类相当于一个XSLT引擎。通常我们使用它来处理XSL文件,但是在这里我们使用它来输出XML文档。
TransformerFactory tf=TransformerFactory.newInstance();
Transformer t=tf.newTransformer ();
//关键的一步, 调用Transformer对象 (XSLT引擎)的transform()方法,该方法的第一个参数是DOMSource对象,第二个参数是StreamResult对象。
t.transform(doms,sr);
}
catch (TransformerConfigurationException tce)
{
System.out.println("Transformer Configuration Exception\n-----");
tce.printStackTrace();
}
catch (TransformerException te)
{
System.out.println ("Transformer Exception\n---------");
te.printStackTrace ();
}

  在实际的应用中,我们可以应用传统的DOM API从XML文档中获取DOM Tree,然后根据实际的需求对DOM Tree执行各种操作,得到最终的Document对象,接下来可以由此Document对象创建DOMSource对象,剩下的事情就是照搬上面的代码 了,程序运行完毕后, XMLOutput.xml就是你所需要的结果(当然了,你可以随意更改StreamResult类构造函数的参数,指定不同的输出介质,而不必是千篇一 律的XML文档)。

  这个方法最大的好处在于可以随心所欲的控制DOM Tree中的内容输出到输出介质中的格式,但是光靠TransformerFactory类和Transformer类并不能实现这个功能,还需要依赖OutputKeys类的帮助。 完整的例子请参考下列文件: AddRecord2.javauser.xml。该例子的运行环境为:Windows XP Professional、JDK 1.3.1。为了能够正常编译运行AddRecord2.java这个程序,你需要到网址 http://java.sun.com去下载安装JAXP 1.1或者Java XML Pack(Java XML Pack已经内含JAXP了)。

OutputKeys类

javax.xml.transform.OutputKeys类和java.util.Properties类配合使用,可以控制JAXP的XSLT引擎(Transformer类)输出XML文档的格式。请看下面的代码片断:

 //首先创建一个TransformerFactory对象,再由此创建Transformer对象。
tf=TransformerFactory.newInstance();
Transformer t=tf.newTransformer ();

//获取Transformser对象的输出属性,亦即XSLT引擎的缺省输出属性,这是一个java.util.Properties对象。
Properties properties = t.getOutputProperties();
//设置新的输出属性:输出字符编码为GB2312,这样可以支持中文字符,XSLT引擎所输出
//的XML文档如果包含了中文字符,可以正常显示,不会出现所谓的"汉字问题"。
//请留意OutputKeys类的字符串常数OutputKeys.ENCODING。
properties.setProperty(OutputKeys.ENCODING,"GB2312");
/更新XSLT引擎的输出属性。
t.setOutputProperties(properties);
//调用XSLT引擎,按照输出属性中的设置,输出DOM Tree中的内容到输出介质中。
t.transform(DOMSource_Object,StreamResult_Object);


从 上面的程序代码,我们不难看出,通过设置XSLT引擎(Transformer类)的输出属性,可以控制DOM Tree中的内容的输出格式,这对于我们定制输出内容是很有帮助的。那么JAXP的XSLT引擎(Transformer类)有那些输出属性可以设置呢? javax.xml.transform.OutputKeys类定义了很多字符串常数,它们都是可以自由设置的输出属性,常用的输出属性如下所示:

  1. public static final java.lang.String METHOD
    可以设为"xml"、"html"、"text"等值。
  2. public static final java.lang.String VERSION
    所遵循规范的版本号,如果METHOD设为"xml",那么它的值应该设为"1.0",如果METHOD设为"html",那么它的值应该设为"4.0",如果METHOD设为"text",那么这个输出属性会被忽略。
  3. public static final java.lang.String ENCODING
    设置输出时所采用的编码方式,比如"GB2312"、"UTF-8"等等,如果将其设置为"GB2312",可以解决所谓的"汉字问题"。
  4. public static final java.lang.String OMIT_XML_DECLARATION
    设置输出到XML文档中时是否忽略XML声明,亦即类似于:
    <?xml version="1.0" standalone="yes" encoding="utf-8" ?>
    这样的代码。它可选的值有"yes"、"no"。
  5. public static final java.lang.String INDENT
    IDENT设定XSLT引擎在输出XML文档时,是否自动添加额外的空格,它可选的值为"yes"、"no"。
  6. public static final java.lang.String MEDIA_TYPE
    MEDIA_TYPE设定输出文档的MIME类型。

如果设定XSLT引擎的输出属性呢?下面我们来总结一下:

首先是获取XSLT引擎(Transformer类)的缺省输出属性的集合,这需要使用Transformer类的getOutputProperties()方法,返回值是一个java.util.Properties对象。

Properties properties = transformer.getOutputProperties();
然后是设定新的输出属性,比如:
properties.setProperty(OutputKeys.ENCODING,"GB2312");
properties.setProperty(OutputKeys.METHOD,"html");
properties.setProperty(OutputKeys.VERSION,"4.0");
………………………………………………………

最后是更新XSLT引擎(Transformer类)的缺省输出属性的集合,这需要使用Transformer类的setOutputProperties()方法,参数是一个java.util.Properties对象。

我们编写了一个新的程序,其中应用了OutputKeys类,用以控制XSLT引擎的输出属性,该程序的架构和前一个程序(AddRecord3.java)大致相同,不过输出结果略有不同。完整的代码请参考下列文件: AddRecord3.java(见附件)、 user.xml(见附件)。该例子的运行环境为:Windows XP Professional、JDK 1.3.1。为了能够正常编译运行 AddRecord3.java这个程序,你需要到网址 http://java.sun.com去下载安装JAXP 1.1或者Java XML Pack(Java XML Pack内含JAXP了)。


2008-11-05

DOM扫描XML后设节点树

  一般使用DOM扫描一个XML文档后会生成一个以节点树表示的文档,XML中的每一个元素、实体、PCData和Attribut都会生成一个节点,节点类型是实现了Node接口的类。参考代码如下:


public static void getScanner(String address) throws Exception{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//create a DocumentBuilderFactory

DocumentBuilder db = null;
//create a DocumentBuilder
try{
  db=dbf.newDocumentBuilder();
  } catch (ParserConfigurationException pce){
    System.err.println(pce);
    System.exit(1);
  }

Document doc = null;
try{
  doc=db.parse(new File(address));
  } catch (SAXException se){
    System.err.println(se.getMessage());
    //to be replaced by the log method;
    System.exit(1);
} catch (IOException ioe){
System.err.println(ioe);
//to be replaced by the log method;
System.exit(1);
}
//parse the input file
}

public static void printxml(Node n)
{
//recursive routine to print out Dom Tree nodes
int type = n.getNodeType();

switch (type){
case Node.DOCUMENT_NODE:
System.out.print("DOC:");
break;
case Node.DOCUMENT_TYPE_NODE:
System.out.print("DOC_TYPE:");
break;
 case Node.ELEMENT_NODE:
System.out.print("ELEM:");
break;
case Node.TEXT_NODE:
System.out.print("TEXT:");
break;
default:
System.out.print("Other Node:" + type);
break;
}

System.out.print(" nodeName=\"" + n.getNodeName() + "\"");

String val = n.getNodeValue();
if(val!=null){
if (!(val.trim().equals(""))){
System.out.print("nodeValue \"" + n.getNodeValue() + "\"");
}
}
System.out.println();


//Print children if any
for (Node child = n.getFirstChild() ; child!=null ; child = child.getNextSibling() )
{
  printxml(child);
  }
}


比如我导入的xml文档是这样:

<?xml version="1.0"?>

<GenericProfileOfVideoCodecSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<Name>1P-Goodquality</Name>

<Test>test</Test>

</GenericProfileOfVideoCodecSettings>


生成的文档树就是这样的:

不过,从实际情况来看GenericProfileOfVideoCodecSettings的所有子节点每个都会带着一个空白的兄弟节点,这个"空白"其实就是xml代码页中两个元素之间的空格和换行。于是上面的输出就会带有很多的
TEXT: nodeName="#text"

2008-11-01

x264编码参数解释

源文:http://www.digital-digest.com/articles/x264_options_page1.html


你有使用mencoder ffmpeg对视频编码成h.264吗?面对复杂的编码参数无所适从吗?读读这篇文章吧,虽然它面向StaxRip和mergui.
另外,这篇文章发布于n年前,上面所说的东西实际上已经是很老的了,如果你对新的参数有兴趣请看http://mewiki.project357.com/wiki/X264_Settings

Introduction + Basic x264 Usage

What is this guide about?
This guide aims to explain, to people just starting out with H.264 encoding, what the various options in x264 mean and how they affect the encoded video. For each option, a description is provided, as well as a list of possible options (and their descriptions), the command line version of the option and the recommend setting is shown in underline whenever possible.
If you are reading this guide, then it must mean that you already know all about H.264 and H.264 playback. If you don't, head on to our H.264 Playback Guide to get acquainted with this new video compression format.
Future versions of this guide will feature more information regarding compatibility (eg. with QuickTime, iPod, PSP, Xbox).

What is x264?
x264
x264 is a free H.264 encoder. It is mainly aimed at intermediate users, so it has lots of options that will be confusing to the average user. If you don't know your trellis from your pyramid, then this guide will hopefully help you to understand things a bit better (or just enough so that you don't have to select options at random).
The x264 options discussed in this article are ones that can be inputted using the command line version of the tool or through a Windows GUI software called StaxRip. A separate StaxRip H.264 Encoding Guide is also available, so don't fret if you can't figure out how to use this software (or to even install it).

Why use StaxRip?
Or rather, why not use MeGUI? MeGUI is probably the best tool around with dealing with x264, but it can be daunting for new users because of the numerous options that are included. StaxRip is aimed more at beginners, and so has (as the author states) only the important x264 options available to configure. Plus, StaxRip assumes no knowledge of Avisynth scripting.
You can also read our MeGUI H.264 Conversion Guide.

Software Requirements:Basic x264 usage:
At it's most basic, x264 is a command line tool, where you can specify the input, output and encoding options all through a glorious black-background/white-text command line interface.
The command line syntax is as follows

x264.exe options --output output.*** inputfile.*** widthxheight
A simple example of a x264 command line entry:
x264.exe --bitrate 1087 --output "test.mp4" "test.avi"
A more complicated example of a x264 command line entry:
x264.exe --pass 2 --bitrate 1087 --stats "test.stats" --ref 3 --bframes 3 --b-pyramid --weightb --b-rdo --bime --direct auto --filter -4:-3 --analyse all --8x8dct --subme 6 --me umh --trellis 1 --mixed-refs --progress --no-psnr --output "test.264" "test.avs"
There are many graphical user interfaces (GUIs) which allow you to set these options through a normal Windows program, and StaxRip is one of them.

Throughout this guide, whenever an x264 option is explained, both the command line equivalent and the StaxRip/GUI version of the option will be shown.

Frames Basics and x264 Profiles

Frames Basics:
Modern compressed video are made up of 3 different types of frames. Intra (I) frames (also known as key frames), Predictive (P) and Bidirectional (B) frames. Certain types of frames can be referenced, which means a frame sometimes only need to stores the difference between it-self and the referenced frame. The problem with referencing is that any error that occurs when frame Y references frame X will be carried over and propagated if frame Y is it-self referenced later on. This is why there are also frames which can't be referenced.

The I frame stores the entire image and so are the least compressible. Video seeking (when you skip to a part of a video) requires I-frames, as otherwise a symptom called seeking lag will occur when the video is blank until the next I-frame is encountered.
P-frames store the difference (called "referencing") between itself and an I-frame or other P-frames. This means P-frames can be referenced, so it needs to store enough information for this to happen, but not as much I-frames because of it's encoding technique (motion compensation).
B frames also store the differences between itself and other frames as well (uses both previous and future frames for reference), but it can't be referenced ("B-frame pyramid" excepted), so they are the most compressible (holds least amount of information). 264 supports "B-frame pyramids", which allow B-frames to be referenced for other consecutive B-frames, but otherwise B-frames can't be referenced by any other frame, so less information is stored.
So basically, a compressed video will be a combination of I, P and B frames, some referencing others. The successful combination of these frames and the referencing determines how well the video is compressed.

x264 Profiles:
Profiles are the easiest way to configure x264. Profiles are basically pre-configured x264 settings that have been saved and can be loaded time and time again to encode files. They save you time by not requiring you to re-set all the options whenever you use x264, and most importantly, they give new users a chance to experience x264 without understanding what the options are.
Sharktooth from the Doom9 forums has produced several profiles for everyday usage, and has made it available for download. You should read the official forum thread for details of what each profile is intended for, although the profiles "PD-PSP", "PD-Xbox_Hires", "PD-Xbox_LoRes" and "PD-iPod" should come in handy for encoding a PSP/Xbox/iPod compatible video. There are even profiles specifically designed for Anime/cartoons
The other piece of good news is that software like MeGUI allow you to import profiles, and StaxRip has these profiles built into the software it self (and also allow you to edit and create your own profiles).
But what if you are curious and you want to find out just what options are being selected in a profile? It's actually very easy to view profiles, because they are actually just XML files. Clicking on the XML file should open them in Internet Explorer, and you should see a screen similar to the one below:
Profiles

What the above shows is that for this particular profile, NbBframes to 3, KeyframeInterval to 250, trellis to false and so on. On the x264 command line, the three options I've mentioned would translates to the following:
x264.exe --bframes 3 --keyint 250 --trellis 0








导言和与x264的基本用法

本篇指导的内容


  这篇指导文章的目的是向那些刚开始了解H.264编码的人们解释这些纷繁复杂的选项的意义以及它们对编码的视频的影响。每个选项我都将提供它的描述,以及一个相关选项的列表,命令行选项和推荐参数设置尽可能添加下划线。

  我假设正在阅读这篇文章的你已经了解了H.264和H.264回放,如果你不清楚的话,清先阅读我们的H.264回放指导以便于了解这种新的压缩格式。

  这篇指导的新版本将添加更多的关于兼容性的信息(比如QuickTime,iPod,PSP,Xbox)




什么是x264?

  x264是一个免费的H.264编码器,它主要中级用户,所以它拥有的大量的选项将会让普通用户头痛死。如果你不了解你的水平,那么这篇文章可能帮助你增加一些了解(即便是能够让你不至于乱用选项)

  这篇文章中讨论的x264选项是那些能够在命令行版本编码器中输入的,或者通过一个windows下的被成为StaxRip的图形程序使用的。你也可以阅读StaxRip H.264 Encoding Guide。所以如果你不懂如何使用那个软件也不必烦恼。




为什么使用StaxRip?

  或者更进一步问,为什么不实用MeGUI?它也许是处理x264最好的工具,但是对新手来说它那大量的选项太复杂了,而这款软件是面向初学者的,并且允许导入x264选项处理,此外,它还不需要Avisynth脚本的知识。
你也可以阅读我们的MeGUI H.264 Conversion Guide.



软件需求:

基本的x264用法:

  这是最基本的用法,x264是一个命令行工具,你能指定输入,输出文件,和编码选项通过这个黑白的命令行交互窗口。

  命令行的使用语法是这样的:

x264.exe options --output output.*** inputfile.*** widthxheight

一个通过命令行使用x264的例子:

x264.exe --bitrate 1087 --output "test.mp4" "test.avi"

一个更加复杂的命令行使用x264的例子:

x264.exe --pass 2 --bitrate 1087 --stats "test.stats" --ref 3 --bframes 3 --b-pyramid --weightb --b-rdo --bime --direct auto --filter -4:-3 --analyse all --8x8dct --subme 6 --me umh --trellis 1 --mixed-refs --progress --no-psnr --output "test.264" "test.avs"


  有很多普通的windows下的图形用户界面程序允许你设置这些参数。StaxRip就是其中之一。

  通过这篇指导,你将了解所有的x264可选参数,包括命令行和软件版本的选项.




帧基础和x264 profiles
帧基础

  现代压缩视频是由三种不同的帧组成: Intra (I) frames(内部帧(非官方翻译),也被称作关键帧),Predictive (P)(预测帧(非官方翻译)) 和 Bidirectional (B) frames(双向帧(非官方翻译)).每个类型的帧将会被引用,这意味着一个帧有时候只需要保存它自己和被它引用的帧的不同之处。引用导致的问题是,假设当Y帧引用X帧的时候,如果Y帧之后被引用的话,发生的错误将被一直传递。这就是为什么有一些帧是不能被引用的原因。

  I帧存储着整个图像,所以它最不能被压缩,视频查找(当你跳过一个部分视频的时候)就需要I帧,否则当视频是空的时候并且未遇到下一个I帧时,就会发生查找滞后的现象。

  P帧存储着它与I帧和其他P帧的不同之处(被称作引用),这意味着P帧能被引用, 所以它需要存储有足够的信息以保证引用的正确,但是由于编码技术的运动补偿,它并不需要存有I帧那么多的信息。

  B帧也保存着它与其他帧的不同之处(通过同时使用先前的数据以及引用它的帧的数据),但是它不能被引用(B-frame pyramid例外),所以他们是最能被压缩的部分(因为他们只需要保有最少的信息),264支持所谓的 "B-frame pyramids",这项技术允许B帧被其他连续的B帧引用,除此之外B帧不能被其他任何B帧引用。因此保证了它可以保存最少的信息。

  所以,基本上一个压缩过的视频将包含I,P和B帧,其中一些引用另外一些。一个视频压缩的好不好取决于是否能够成功的混合这些帧和处理好其中的引用关系。




x264 Profiles:

  Profiles是最简单的配置x264的方法,Profiles是已存档的基本的x264预配置文件,它能够随时被读取来编码视频。他们能够让你不需要每次都被重复要求设置所有选项,从而大大的节省了你的时间。并且,最重要的是,他们可以让一个新手有机会体验x264而不需要去了解那些选项是干什么的。
Doom9论坛的Sharktooth制作了许多profiles文件以供日常使用。你可以下载它,你应该阅读论坛的官方帖子以了解每个profiles文件的详细情况与用处,尽管那些profiles文件比如"PD-PSP", "PD-Xbox_Hires", "PD-Xbox_LoRes" 和"PD-iPod"可以让我们很便捷的编码出适用于PSP/Xbox/iPod的视频,不过我们还能找到专为动画设计的profiles文件哦。

  另外一个好消息是像MeGUI这样的软件允许你导入profiles,而StaxRip则内建了一个profiles文件,同样它也允许你编辑和创建自己信的profiles文件。
  不过,要是你是个很有好奇心的人,并且你想要去找出每个选项的用处,你可以很容易的查看profiles文件,因为它们是标准的xml文档,在ie中打开它你会看到下面的内容:



Profiles

  上面这个profiles配置了NbBframes为3,KeyframeInterval为250,trellis被禁用等。用命令行来表示就会被翻译成:



x264.exe --bframes 3 --keyint 250 --trellis 0




x264 Options: Common

x264 Options: Common


Mode:

Description: Selects the encoding mode to be used by the encoder. Single pass encoding can give unexpected output file sizes (Quantizer and Quality modes) and/or poorer quality compared to multi pass encoding.
Available Options:
Single Pass - Bitrate: Encodes the video once (single pass) with a set constant bitrate for each frame
Single Pass - Quantizer: Single pass encoding with a set quantizer (higher quantizer => lower quality) for each frame
Single Pass - Quality: Single pass encoding with a set quality rating for each frame
Two Pass: Encodes the video twice (once to determine it's properties, another to ensure the selected output file size is reached with maximum efficiency). This is the most common setting.
Three Pass: Same as Two Pass except for an extra encoding pass to ensure even better quality/accurate file size
Command Line: --bitrate, --qp, --crf, --pass 1/2/3

Quantizer:

Description: Only available with "Single Pass - Quantizer" mode is selected. Set the quantizer value for the encoding. A high quantizer will equal a low quality (and smaller file size). A quantizer value between 20 (high quality) and 30 (low quality) should be used. Anime/cartoons or scenes with large patches of color or less details benefit from having a higher quantizer, typical movies require a lower quantizer.
Command Line: --qp n
(where 'n' is the quantizer value)

Quality:

Description: Only available with "Single Pass - Quality" mode is selected. Set the quality value for the encoding. A high quality value equals a higher quality encoding (and larger file size).
Command Line: --crf n
(where 'n' is the quality value)

B-Frames:

Description: Selects the number of consecutive B-frames x264 should use. It is also the maximum number of consecutive B-frames x264 can use if the "Adaptive" B-frames option (see next section) is selected. B-frames are frames that are small in size, but when placed correctly, offer no loss of quality. This can help improve compression. With the "Adaptive" option on (x264 will decide how many B-frames to use), having a setting of 3 is recommended as this gives x264 enough room to work with.
Command Line: --bframes n
(where 'n' is the number of B-frames)

Reference Frames:

Description: Selects the maximum number of reference frames that can be used. Referenced frames are frames that refer to other frames (eg. if both frames are similar). Having a high referenced frame will improve quality but slow up encoding. For typical content, a reference frame of 3 to 5 is recommended. For content with a lot of repetition (eg. animation), a reference frame of 8 to 10 can be used. If a large number of reference frames is selected, then the "Mixed References" options should also be selected to allow x264 greater control (see "Analysis Options" section).
Command Line: --ref n
(where 'n' is the number of reference frames)

Loop Filter:

Description: Also known as "de-blocking" filter. Connected with the "Alpha" and "Beta" setting next to it. One of the fundamental differences between H.264 and previous codecs. Should always be enabled or excessive video artifacts may appear. Controversial because blocking (when the video looks like a series of different colored squares in low bitrate video) and artifacts are treated as details by the human visual system, and removing them makes people think details is lost, when it's actually the other way around (more "actual" details shown due to less artifacts). This is an interesting topic that is better discussed in DeathTheSheep's x264 guide.
Command Line: --nf
(disables loop filter)

Alpha/Beta:

Description: This controls the "Loop Filter" (see above). Also known as Strength (Alpha) and Threshold (Beta). Alpha determines the strength of the deblocking action. Beta determines when x264 decides something is a block and when something isn't - a high value means x264 sees more video as blocks than a lower value. For example, a too high Beta value and a too high Alpha means x264 will identify too many blocks (even when they aren't artifacts) and apply too much filtering to remove them, making the picture look "washed out" and lacking detail. Both values can be positive or negative. 0/0 (Alpha/Beta) is the default and recommended setting, unless you find the video quality unacceptable, then you should try combinations. Do not go under -2 or above 3. This is an interesting topic that is better discussed in DeathTheSheep's x264 guide.
Command Line: --filter

x264 选项: 普通部分

x264 Options: Common


模式:

说明选择编码器使用的编码模式,一次编码输出的文件可能不能断定大小(在量化器和质量模式下)并且/或者可能会产生比二轮编码烂一点的质量。


可用选项

Single Pass -Bitrate:用对每帧固定码率的设置一次编码视频。

Single Pass -Quantizer:用一个对每帧设置量化器的设置一次编码视频。

Single Pass -Quality:用一个对每帧设置与源文件的质量比率的设置来一次编码视频。

Two Pass:两次编码视频,第一次检测视频文件的信息,蝶如此确保输出的视频在确定的码率下质量最大化。这是最常用的设置。

Three Pass:同二次编码垒石,只是多用了一轮编码来确保更佳的文件品质。

命令行:-bitrate, -qp ,-crf ,-pass 1/2/3


量化器:


说明只有当使用“一次编码量化器模式”的时候可用,需要设置量化器的值,值越高,表示越低的质量越小的文件。可以使用20-30之间的值。动画和卡通或者是一个有着大块相同色彩的区域的场景以及一个比较少细节的画面可以设置一个比较好的量化器值,普通的电影用比较少的值



命令行: -qp n (n为量化器的值)






质量:

说明: 只在“一次编码质量模式“被选用的模式下可用,这是一个值作为编码的质量,越高的值代表越高的质量,越大的文件,




命令行: --crf n (n为质量的值)


B帧:

说明: 选择x264使用的连续b帧的数量,这也是当Adaptive B帧选项被使用时x264可用的b帧的最大数量,b帧虽然体积小,但是当插入的位置正确的话不会降低质量。因此能够提升压缩率。当采用了Adaptive 选项的时候推荐把这个值设置为3以便于给x264程序足够的空间处理。








命令行: --bframes n (n表示b帧的帧数)

引用帧:


说明: 选择引用帧的最大可用值,引用帧引用了其他的帧(比如当两个帧非常相似时),引用帧多的话会提升质量,但是会减慢编码速度。对于一般的视频内容,设置它为 3到5是一个比较不错的选择,对于有着大量重复内容的视频来说(比如动画)可以把它设置为8到10,如果使用了大量的引用帧,那么应该使用Mixed References选项,以便于允许x265更好的控制编码






Command Line: --ref n (n表示引用帧的帧数)


循环过滤:

说明:也 被称作“去块效应滤镜”,需要紧跟着Alpha和Beta设置,H.264同之前的编码器的一个根本性的区别就是它总是允许过度的artifacts存 在,这样的处理有很大的争议,由于块效应(当视频在地码率下看起来像一系列不同的色块堆积而成的)和artifacts被人的视觉系统作为画面细节对待, 移除它们会让人觉得视觉细节丢失了,虽然实际的效果正好相反(越少artifacts会让人觉得有越多的“实际”细节),这是一个有趣的讨论题目,在这篇 文章中有详细的讨论:DeathTheSheep's x264 guide.





命令行: --nf (禁用循环过滤)

Alpha/Beta:

说明:这 个选项控制循环过滤。Alpha也作为Strength,Beta也作为Threshold,alpha决定去块效应的强度,beta控制x264判定某 物是否是块。越高的值意味着x264把越多的东西作为块,例如,一个很高的beta值和一个很高的alpha值将判定过多的块(即使它们并非 artifacts)并且将允许更多此过滤来除去它们,这以为着图像会丢失很多细节。这两个值都可以是正负的。推荐把它们都设置为0,除非你发现视频的质 量实在让人无法接受。否则不要调整,而且即使调整也不要低于-2或高于3。



命令行: --filter

x264 Options: B-Frames


x264 Options: B-Frames


Direct Mode:
Description: This option when selected can improve compression efficiency. Disabled by default, Auto seems to be the most common value, with Spatial being used occasionally.
Available Options:
None
Spatial
Temporal: least used (at least in Sharktooth's profiles)
Auto: most common
Command Line: --direct x
(where 'x' is 'none', 'spatial', 'temporal' or 'auto')

Bias:
Description: Sets how much bias x264 should give the usage of B-frames (higher means more use of B-frames). Setting this to 100 is the equivalent of not selecting the "Adaptive" option (see below). A default value of 0 works well. Option only available when at least 1 B-frame has been set.
Command Line: --b-bias n
(where 'n' is the bias value)

Adaptive:
Description: Turns on adaptive B-frames, which allows x264 to determine the number of B-frames to use (within the set B-frames limit in the previous section). A default value of On works well. Option only available when at least 1 B-frame has been set.
Command Line: --no-b-adapt
(disables adaptive B-frames)

Pyramid:
Description: Turns on B-frame Pyramid option, which allows B-frames to be used as references for other B-frames in prediction. A default value of On (when available) works well. Option only available when at least 2 B-frame has been set.
Command Line: --b-pyramid
(enables adaptive B-frames)

RDO:
Description: Turns on/off RDO for B-Frames. Turning it On will improve quality at the expense of encoding speed, but it is almost always worth it. Must have at least 1 B-frame and must have a "Subpixel Motion Estimation" (see "Analysis options" section) of 6 or 7.
Command Line: --b-rdo
(enables RD based mode decision for B-frames)

Weighted Prediction:
Description: Turns on weighted prediction for B-frames, which results in improved accuracy and therefore a more efficient encoding. Set it to On in most cases. Option only available when at least 1 B-frame has been set.
Command Line: --weightb
(enables weighted prediction)

Bidirectional M.E.:
Description: Turns on bidirectional M.E, which allows predictions based on motion both before and after the B-frames. Set it to On in most cases.
Command Line: --bime
(enables bidirectional M.E.

x264选项: B帧部分


x264 Options: B-Frames


直接模式:

说明:这个选项可以提升压缩性价比,默认禁用,自动是最常用的选择,偶尔会用到Spatial

可用选项:

None
Spatial
Temporal: 极少使用
Auto: 最常用

命令行: --direct x ('x' 可以是 'none', 'spatial', 'temporal' 或 'auto')

Bias:

说明: 设置x264使用多少斜线,越高的值使用越多的b帧,设置这个为100等价于不使用Adaptive选项,默认值是0,这个值能很好的工作,要设置这个选项要求b-frames大于1




命令行: --b-bias n (n为bias的值)

Adaptive:

说明: 打开B帧的自适应,将允许x264决定使用b帧的数量(在bias中设置的值会限制这个数量),默认值是开启,只有当B-frame设置大于1的时候有效


命令行: --no-b-adapt (禁用 adaptive B-frames)

Pyramid:

说明: 打开b帧金字塔层次选项, 将允许b帧引用其他b帧来预测,默认打开(当可用时),只有当B-frame设置大于2的时候有效


命令行: --b-pyramid (打开b pyramid)

RDO:
说明:为b帧打开或者关闭RDO,开启这个选项能提升质量而仅仅减少一点编码速度,这个代价通常是值得的,b-frame必须大于1并且必须有“子像素运动估计”




命令行: --b-rdo (开启b帧的rd基础判断模式)

权重预测:


说明: 打开b帧的权重预测,这将提升精确度,即使编码更具性价比,大多数情况下都开启这个,只有当B-frame设置大于1的时候有效


命令行: --weightb (开启权重预测)

双向M.E.:


说明: 打开双向M.E,这将允许基于这个b帧的前后帧的变化来预测,多数情况都打开它


命令行: --bime (打开双向M.E)

x264 Options: Frame Options

x264 Options: Frame Options


Scene Cut:

Description: This option sets how x264 determines when a scene change has occurred and hence when a key frame is needed. A higher value will allow x264 to be more sensitive to scene changes. A video that has very few camera movements may require a higher scene cut value, for example. The default value of 40 should work well in most cases, plus or minus 5 for low/high action videos.
Command Line: --scenecut n
(where 'n' is the scene cut value)

CABAC:

Description: Stands for Context Adaptive Binary Arithmetic Coding. Improves encoding efficiency at the expense of playback/decoding efficiency. The default option of leaving this setting On is recommended, unless the encoded video is to be played back on devices with limited decoding power (eg. portable devices such as the iPod or high resolution clip playback on the Xbox).
Command Line: --no-cabac
(disables CABAC)

GOP Size (Min/Max):

Description: This option sets the minimum and maximum number of frames before a key frame has to be inserted by x264. For example, a minimum setting that is the same as the framerate of the video (eg. 24/25/30) will prevent the encoded video from having two subsequent key frames within a second of each other, which only aims to increase file size without any noticeable quality improvements.

Similarly, a maximum setting ensures that a key frame is inserted at least every X number of frames. A video without key frames will have lower quality and there will be problem with seeking (if you try to skip to a part of the video without a key frame, there won't be any video until the next key frame is reached, also known as "seeking lag"). A recommend setting, as with DivX/XviD encoding, is to set this as 10 times the framerate, which equates to 10 seconds of video between key frames (ensures "seeking lag" is at most 10 seconds).
Command Line: --keyint m --min-keyint n
(where 'm' and 'n' are the max and min GOP size values)



x264 Options: Analysis

x264 Options: Analysis


Mixed References:

Description: This option allows x264 to have greater control over "Reference Frames" (see "Common options" section). Especially needed if the "Reference Frames" is set to a high value.
Command Line: --mixed-refs
(enables mixed references)

No Fast P Skip:

Description: Fast P Skip can improve encoding speed at the expense of a very slight quality drop. Leave this option set to Off (to allow for Fast P Skips) is recommended unless encoding for maximum quality with no regard to encoding time.
Command Line: --no-fast-pskip
(disables fast P skip)

Motion Estimation Method:

Description: This option select the way motion is detected by x264. Motion is what compression codecs are all about, tracking differences between scenes to allocate the various frame types and bitrates.
Available Options (listed from fastest to slowest, encoding speed wise):
Diamond: Only use when maximum encoding speed is required.
Hexagon: A good option for when quality is not the most important factor, but still important.
Multi Hex: Also known as "Uneven Multi-Hexagon". This is the most common setting, as it is a good trade off between speed and quality.
Exhaustive: Slowest and totally unnecessary (it isn't estimation anymore, rather, it's Motion Calculation, pixel by pixel).
Command Line: --me x
(where 'x' is 'dia', 'hex', 'umh' or 'esa')

Subpixel Motion Estimation:

Description: Also known as "Partition Decision". A very important option that determines how x264 makes decisions about motion estimation. The options are available from 1 to 7, with 1 being the fastest (lowest quality) and 7 being the slowest (best quality). A setting of 6 is the most common, with 1 or 7 being used in extreme cases (fastest encoding or best quality). A setting of 6 or 7 enables the B-frames RDO option (see "B-Frames options" section).
Command Line: --subme n
(where 'n' is the estimation value)

Trellis RD Quantization:

Description: This option when turned on is supposed to improve quality, but at a severe slow down of encoding. The quality improvements are also subjective. Leaving it Off is recommended unless you have a fast computer and using multi-pass encoding. Never turn it on in single pass quantizer mode, as it would lead to unexpected results.
Available Options:
Disabled: Use this for 1-pass encoding
Final MB: Use this for typical 2-pass encoding
Always: Use this for maximum quality (slowest speed)
Command Line: --trellis n
(where 'n' is 0 {disabled}, 1 {Final MB} or 2 {Always})

x264选项:帧选项部分:

x264 Options: Frame Options

Scene Cut:

说明: 这个选项决定x264如何判断当场景发生改变的时候是否需要插入关键帧,一个高的值将允许x264对场景变化更加敏感,如果一个视频只有很少的摄像机移动的话就需要更高的值,例如,默认的值40将在绝大多数情况下工作的很好,一般我们只在这个值上增删5左右。




命令行: --scenecut n

CABAC:

说明:CABAC表示上下文适应的二进制算术编码。这个选项能够提高编码效率,而只会略微将少编码和解码的效率,默认选项就是打开,我们推荐打开,除非视频回放设备很烂。








命令行: --no-cabac (禁用 CABAC)

GOP 大小 (Min/Max):

说明:这个选项设置了x264在每个关键帧前面插入的最大和最小帧数,例如,把最小值设置成和视频帧率一致(比如24/25/30)将防止编码的视频一秒之内有两个连续的关键帧(这种情况只会增加视频的大小却不能增加其质量)。

   类似的,最大值确保关键帧至少在每x个帧中能被插入,一个没有关键帧的视频的质量很低而且有寻址问题,(如果你试着去跳过包含关键帧的视频的一部分,那 么你就会直接跳到下一个关键帧处)。推荐的设置和DivX/XviD编码一样,把它设置为帧率的10倍,也就是每十秒一定有一个关键帧(这样确保寻址延迟 最多十秒)




命令行: --keyint m --min-keyint n ( 'm' 和 'n' 分别代表max和min)



x264选项:


x264 Options: Analysis


混合:

说明:这个选项允许x264对引用帧有更好的控制,尤其是当引用帧设置到很高的值的时候更加需要这个参数


命令行: --mixed-refs (开启混合引用)

禁用快速跳过p帧:

说明: 快速跳过p帧能够提升编码速度,而仅仅轻微降低视频质量,把这个选项设置为off能开启快速跳过p帧,我们推荐这样做,除非你更在意编码速度,而不是质量



命令行: --no-fast-pskip (禁用快速跳过p帧)

运动估计方式:


说明: 这个选项设定x264检测运动的方式,运动是视频编码的全部,追踪两个场景中的不同之处,并且分配帧类型和比特率
可用选项(从编码速度最快的排到最慢的):
Diamond:只有当要求最快的编码速度时使用。。
Hexagon:当视频质量不是最重要,但也是一个重要参考因素的时候使用。
Mulit Hex:也被称作“非匀称六边形搜索“这个是最常用的选项。它能够很好的平衡质量与速度,
Exhaustive:最慢的并且完全不必要的选项。它搜索所有像素。







命令行: --me x ( 'x' 可以是 'dia', 'hex', 'umh' 或 'esa')


子像素运动估计:


说明: 也被成为分区判断,一个非常重要的选项,以决定x264怎样判断运动估计。值可以从1到7,1是最快但最低质量的方式,7是最慢当最高质量的方式,一般设置为6,1和7一般只有在极端条件下使用。设置为6或7允许B帧RDO选项





命令行: --subme n (n为评估值)

RD栅格量化:


说明: 开启这个选项可以提升质量,但是会严重降低编码速度,而且质量提升也是主观的,一般推荐关闭,除非你有一台高速计算机并且使用多次编码,不论如何,绝对不要在一次量化器编码模式下使用它,否则会造成不可预期的结果。



可用选项:
Disabled: 只用一次编码的时候使用
Final MB: 一般多次编码的时候用这个
Always: 最大质量模式,也最慢



命令行: --trellis n
( 'n'为 0 代表{disabled}, 1 代表{Final MB} 或 2 代表{Always})

x264 Options: Partitions


x264 Options: Partitions


Partitions:
Description: These options determine the partition search types. Generally, you want to enable all of these options whenever possible, as they will improve encoding quality. The "P4x4" option requires the "P8x8" option.
Command Line: --analyse x
(where 'x' is 'p8x8', 'p4x4' {requires 'p8x8'}, 'b8x8', 'i8x8', 'i4x4' , 'none' or 'all')

8x8 DCT:
Description: This option has been separated from the above because it has a different command line flag. This option is required if you want to select the "I8x8" option above.
Command Line: --8x8dct
(enables 8x8 DCT)


x264 Options: Input/Output


Show progress indicator:

Description: This option when enabled shows you how many frames have been encoded and how many frames are left. Best to leave it On if you don't want to sit there guessing how much is still left to do.
Command Line: --progress
(enables progress indicator)



Disable PSNR computation:

Description: This option disables noise reduction calculations. It is recommended that you leave this option On (to diable PSNR).
Command Line: --no-psnr
(disables PSNR computation)



Threads:

Description: This sets the number of CPU threads to use in encoding. An Intel Pentium processor with HyperThreading counts as 2 threads. Dual Core processors are also 2 threads. Dual core processor with HyperThreading (eg. Intel Extreme Edition) will have 4 threads.
Command Line: --threads n
(where 'n' is the number of threads)



Output Type:

Description: Selectable within the x264 command line by the output filename. A file with extension .264 will equal the "RAW" setting.
Command Line: --output x
(where 'x' is the output filename with the extension being .264, .mp4 or .mkv to indicate output type)

x264选项: 分区


x264 Options: Partitions


分区:
说明: 这个选项决定分区搜索方式,你会希望把它设置为all,这样能提升编码质量,P4x4选项要求开启p8x8, p4x4只在subq >= 5,并且分辨率低时才推荐使用。



命令行: --analyse x ( 'x' 是 'p8x8', 'p4x4' {需要 'p8x8'}, 'b8x8', 'i8x8', 'i4x4' , 'none' 或 'all')

8x8 DCT:

说明: 这个选项被从上面单独分离出来是因为它的命令标志不同于上面的,这个选项要求你开启i8x8

命令行: --8x8dct (开启 8x8 DCT)



x264 Options: Input/Output


禁用PSNR 计算:

说明: 这个选项禁用降噪运算,推荐开启它以禁用降噪运算




命令行: --no-psnr (禁用 PSNR 运算)



Threads:

说明: 这个选项设置cpu编码线程数。支持intel的HT技术的cpu每个核心被视为2个线程,双核处理器也是2个线程,双核ht的cpu就是4线程了。
命令行: --threads n
( 'n'表示线程数)