Java 里把 InputStream 转换成 String 的几种方法

我们在 Java 中经常会碰到如何把 InputStream 转换成 String 的情形,比如从文件或网络得到一个 InputStream,需要转换成字符串输出或赋给别的变量。

未真正关注这个问题之前我常用的办法就是按字节一次次读到缓冲区,或是建立 BufferedReader 逐行读取。其实大可不必费此周折,我们可以用 Apache commons IOUtils,或者是 JDK 1.5 后的 Scanner,还可用 Google  Guava 库的 CharStreams。到了 JDK7,若要从文件中直接得到字符串还能用 java.nio.file.Files#readAllLines 和 java.nio.file.Files#readAllBytes 方法。

下面看各个例子,为能够实际用运,例子写在 main 方法里,并从文件获得一个 InputStream,代码中把可能要捕获的异常抛出来。再就是注意处理输入输出流时有涉及到字符集,字符集乱了就乱码了,默认字符集是 System.getProperty("file.encoding"),通常我们都用 UTF-8,异常 UnsupportedEncodingException 继承自 IOException。

下面的 6 个方法中应该有一个你能看得上的吧,用 Groovy,Scala 的除外,若未找到一个遂意的,告诉我,你有好办法更应该告诉我。

1. 使用 JDK 5 的 Scanner 阅读全文 >>

类别: Java/JEE. 标签: , . 阅读(18,764). 评论(0) »

Scala 2.10.0 新特性之动态属性、方法

最早的介绍 Scala 语言的书都是以 Scala 的静态类型系统为傲。Scala 也算是个脚本语言,却不像其他许多脚本语言那样类型是动态的,只有执行时才确定,而 Scala 在执行前就确定了类型,比如依赖于比 Java 更强大的类型推断行为。

静态类型不光是变量类型是确定的,还有比如在使用  qual.sel 时,sel 这个属性或是方法(Scala 的访问一致性,属性和方法有时候并没有那么大的区别)必须在 qual 的类型中声明了的。

Scala 思考再三还是加入了 Dynamic Types,这个特性在 Scala 2.9 中是试验性的,必须用 -Xexperimental 进行开启,到了 Scala 2.10.0 中,只有代码中 import scala.language.dynamics 就可用了,或是编译时加 -language:dynamics 选项。

虽然 Scala 2.10.0 加进了 Dynamic Types 特性,但 Scala 仍然是静态类型的语言,因为在编译器同样会检查多出来的类型。

有了 Dynamic Types 之后,Scala 又可更 DSL 了,方法名的动态上可以让它随时包括深刻的业务含义。相比 Java 的 DSL 的能力就太逊了,我们几乎无法在 Java 面前提 DSL 这回事。 阅读全文 >>

类别: Java/JEE, PlayFramework, Scala. 标签: , . 阅读(1,171). 评论(1) »

Scala 2.10 新特性之使用隐式类进行类型隐式转换

在 Scala 2.10.0 之前类型的隐式转换必须通过隐式方法来完成,现在的 Scala 可以用 implicit class 来声明类,并且它的主构造器 (Primary Constructor) 只有一个参数时,就可以用来把参数隐式转换成该类型。

能理解上面什么意思,知道怎么用隐式类吗? 就上面那句话,我自己都不知道在说什么。

首先要知道 Scala 先前是怎么依据隐式方法进行类型的隐式转换,其次又何谓主构造器呢? 关于 Scala 2.10.0 的 implicit class,官方的解释在这里 http://docs.scala-lang.org/sips/pending/implicit-classes.html 再多说只能让大家更摸不到头,实例演示是王道:

scala-2.10.0-implicit-class 阅读全文 >>

类别: Scala. 标签: , . 阅读(2,119). 评论(0) »

JavaDoc 编程,书写自定义的 Doclet, 定制输出

前一篇介绍了 JavaDoc 编程,书写自定义的 Taglet 支持 @unmi 等, 那时提到了 Doclet,但是差点无视了 Doclet,现在才知道 Doclet 真是太强大了,有了它你会觉得 javadoc 已经不是原本的那个 javadoc 了,别再把 javadoc 看作只会生成一大堆 HTML 文件的工具了。尤其是搭配上自定义的 Taglet,那可是,自已体验吧。

Doclet 是 JavaDoc 的一个很隆重的扩展点,可以在执行 javadoc 时用 -doclet 来指定自己的 Doclet,那么 doclet 可以为我们做些什么呢?

可以为我们生成 HTML 的 JavaDoc API 文档,这就是默认的 com.sun.tools.doclets.standard.Standard 为我们做的事,还可以像以前那样从源文件中抽取信息生成各种 XML 文件,或是 PDF, Excel, UML 图等等任何可能的内容,或做任何有作为的事情。总之在 doclet 中可以感知道对任何包,类,方法,字段等的遍历。这里 Doclet.com 有大量的第三方的 doclet 供你选择,如:

AntDoclet, API Guide Doclet, EJBGen, Java2Rose Doclet, JDiff, JUnitDoclet, LaTeXtaglet, PDFDoclet, PublishedApiDoclet, ServletDoclet, Spell Check Doclet, UMLGraph, VelocityDoclet, XDoclet, xml-doclet 等数十种 Doclet, 还可以找到别的,所以你要是不想自定义 Doclet 的话,有第三方可用就直接用人家的就行。

总有特殊需求的时候,总有要自定义 Doclet 的时候。说那么多总要来看看 Doclet 可以用来做什么,见如下 DocumentDoclet: 阅读全文 >>

类别: Java/JEE. 标签: , , , . 阅读(5,974). 评论(3) »

Java 的多行字符串 Here Document 的实现

寻求了很久关于如何在 Java 中实现多行字符串,即 Here Document。因为在测试中准备大的字符串数据是不得不用加号去拼接,甚至是麻烦。稍好就是用 http://www.htmlescape.net/javaescape_tool.html 把你输入的大段文字生成 Java 的字符串。

找过一些介绍 Java 实现 Here Document 的方法,首先大家无一不是把这个多行字符串塞在注释里,有些实现在运行还在依赖于 Java 源文件中的注释,这不太可取。聪明的做法应该要去打编译器的主意,让编译后体现在 Class 文件中,变量就被赋上了多行字符串值,这就是 JDK1.5 引入的 APT(Annotation Processing Tool),到 JDK1.6 后可操作性更强了,可以 javac 的时候带上 -processor 参数。

单单从语法特性上来讲,我觉得 Java 与现今流行的语言还是有差距,不过它一直在成长,像 JDK 1.5 和 1.7 这两个版本就带来了不少好东西。想要见识一下其他些个语言,如 Perl, PHP, Ruby, C++11 怎么实现 Here Document 还是请看 http://en.wikipedia.org/wiki/Here_document

就连 Java 最亲密的战友 C# 都早实现了 Here Document,用 @ 符号: 阅读全文 >>

类别: Java/JEE. 标签: , , . 阅读(788). 评论(4) »

保持顺序的 Java Properties 类

Java 的 Properties 加载属性文件后是无法保证输出的顺序与文件中一致的,因为 Properties 是继承自 Hashtable 的, key/value 都是直接存在 Hashtable 中的,而 Hashtable 是不保证进出顺序的。

总有时候会有关心顺序一致的需求,恰如有 org.apache.commons.collections.OrderdMap(其实用 LinkedHashMap 就是保证顺序) 一样,我们也想要有个 OrderdProperties。网上查了下还真有:

http://livedocs.adobe.com/jrun/4/javadocs/jrunx/util/OrderedProperties.html

http://www.openrdf.org/doc/alibaba/2.0-rc4/apidocs/org/openrdf/repository/object/composition/helpers/OrderedProperties.html

不过没找到源码,其实自己写一个 OrderedProperties  也不难,并不需要重头写起,只要继承自 Properties,覆盖原来的 put/keys,keySet,stringPropertyNames 即可,其中用一个 LinkedHashSet 来保存它的所有 key。完整代码如下: 阅读全文 >>

类别: Java/JEE. 标签: , . 阅读(2,454). 评论(3) »

切分 Tomcat 的 catalina.out 文件,解决日志文件过大的问题

Tomcat 下日志文件 catalina.out 过大,几百兆或几个G,进而造成再也无法写入更多的日志内容,至使 Tomcat 无法处理请求。需然你可以在 $TOMCAT_HOME/logs 目录下看到有 catalina.2012-09-16.log 这样分日期的归档,但是主文件 catalina.out 却一直在膨胀。

你可以每次手工或定时(crontab/计划任务)清理 catalina.out 文件,或是规划好日志输出(终究也会有满的时候)。再就是有两种较好的解决方案去真正的切分 catalina.out 文件,让 catalina.out 只存有最新的日志。

一. 改用 Log4J 来输出 Tomcat 日志,借助 Log4J 的各种日志切分的功能。详情可参考: http://baalwolf.iteye.com/blog/1464093http://tomcat.apache.org/tomcat-6.0-doc/logging.html

二. Linux 下使用 cronolog 工具来切分 catalina.out

这里重点介绍这种方法,具体步骤如下: 阅读全文 >>

类别: Java/JEE. 标签: , . 阅读(4,522). 评论(2) »

再说 Java 中使用正则表达式进行后向引用($1,$2...)

前面通过 在 Java 中使用正则表达式进行后向引用($1,$2...) 讲了在 Java 中使用 JavaScript 和 JRegex 来实现正则表达式的后向分组引用 $1, $2 替换。

自 JDK 1.4 出现正则表达式以来我还真不知道 Java 的正则表达式是可以在替换时用 $1, $2 达成后向分组替换的,所以前一篇表述有些出入的。也就是要实现 JavaScript 中的

的功能,完全可以不求助于第三方的正则表达式组件库或是通过 ScriptEngine + JavaScript 来实现,在 Java 字符串的:

public String replaceFirst(String regex, String replacement)
public String replaceAll(String regex, String replacement)

两方法的第三个参数中是可以用 $1, $2 ... 来引用第一个参数的括号分组的,简单 Java 示例代码如下:

Java 的正则表达式原本还是很强大的,只怕不能被人发现。

2015-07-14: 补充一点,在正则表达式外是用  $1, $2 ... 来进行后向引用,如果是在正则表达式中就需要用  \1, \2 ... 的形式来进后向引用。下面例子,替换重复出现的两位数及之间的内容

类别: Java/JEE. 标签: , . 阅读(2,367). 评论(0) »

Java 下高效的反射工具包 ReflectASM 使用例解

ReflectASM 使用字节码生成的方式实现了更为高效的反射机制。执行时会生成一个存取类来 set/get 字段,访问方法或创建实例。一看到 ASM 就能领悟到 ReflectASM 会用字节码生成的方式,而不是依赖于 Java 本身的反射机制来实现的,所以它更快,并且避免了访问原始类型因自动装箱而产生的问题。

下面三个图是 ReflectASM 与 Java 自身反射机制的性能对比,表现很不错的。

测试代码包含在项目文件中. 上面图形是在  Oracle 的 Java 7u3, server VM 下测试出的结果。

下面我们自己来做个测试,测试环境是 Mac OS X 10.8, 2.4G Core 2 Duo, 4G RAM, 64 位 JDK 1.6. 阅读全文 >>

类别: Java/JEE. 标签: , , . 阅读(11,392). 评论(0) »

Java 使用 dom4j 来获得 XML 文档的 innerXML

在网页的 Document 中如果想要获得某个结点的 innerHTML 就行,而在 Java 处理 XML 文档时想要获得某个节点的的 innerXML 就没那么简单的,标准的 org.w3c.Element 和  org.w3c.Node 均未提供类似 innerXML 的方法。

幸好,我们常用的 dom4j 里的 org.dom4j.Node 有一个方法是 String asXML(),不过它的意义相当于是 outerXML,也就是说它返回的内容还包括节点本身。

比如有这么在个 XML 文档:

阅读全文 >>

类别: Java/JEE, XML/DOM. 标签: , , , . 阅读(500). 评论(0) »