`

NIO官方例子—正则表达式匹配和解码问题MalformedInputException

阅读更多

NIO的特性:

  1. Buffers for data of primitive types
  2. Character-set encoders and decoders
  3. A pattern-matching facility based on Perl-style regular expressions
  4. Channels, a new primitive I/O abstraction
  5. A file interface that supports locks and memory mapping
  6. A multiplexed, non-blocking I/O facility for writing scalable servers

很多书本上,一般只提到NIO的特性1、4、5,对特性2提及的也比较少,我看过的几本书上几本上没有提到特性3、6。特性6在网上到能搜到不少资料,socket的高级编程、MINA框架、Lucene框架中大量使用NIO。

 

 

最经查看NIO的官方API的时候,发现其官方NIO的第一个例子Grep.java中就有特性3的运用:

 

public class Grep {
	//16 位的 Unicode 代码单元序列和字节序列之间的命名映射关系。
    //此类定义了用于创建解码器和编码器以及检索与 charset 关联的各种名称的方法。
    // Charset and decoder for ISO-8859-15
    private static Charset charset = Charset.forName("UTF-8");//测试中文。。
    private static CharsetDecoder decoder = charset.newDecoder();

    // Pattern used to parse lines
    private static final Pattern linePattern = Pattern.compile(".*\r?\n");

    // The input pattern that we're looking for
    private static Pattern pattern; 

    // Compile the pattern from the command line
    private static void compile(String pat) {
	try {
	    pattern = Pattern.compile(pat);
	} catch (PatternSyntaxException x) {
	    System.err.println(x.getMessage());
	    System.exit(1);
	}
    }

    // Use the linePattern to break the given CharBuffer into lines, applying
    // the input pattern to each line to see if we have a match
    private static void grep(File f, CharBuffer cb) {
	Matcher lm = linePattern.matcher(cb);	// Line matcher
	Matcher pm = null;			// Pattern matcher
	int lines = 0;
	while (lm.find()) {
	    lines++;
	    CharSequence cs = lm.group(); 	// The current line
	    if (pm == null)
		pm = pattern.matcher(cs);
	    else
		pm.reset(cs);
	    if (pm.find())
		System.out.print(f + ":" + lines + ":" + cs);
	    if (lm.end() == cb.limit())
		break;
	}
    }

    // Search for occurrences of the input pattern in the given file
    //
    private static void grep(File f) throws IOException {

	// Open the file and then get a channel from the stream
	FileInputStream fis = new FileInputStream(f);
	FileChannel fc = fis.getChannel();

	// Get the file's size and then map it into memory
	int sz = (int)fc.size();
	MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz);

	// Decode the file into a char buffer
	CharBuffer cb = decoder.decode(bb);
	// Perform the search
	grep(f, cb);
	// Close the channel and the stream
	fc.close();
    }

    public static void main(String[] args) {
    	args = new String[]{"int","test.log"};
	if (args.length < 2) {
	    System.err.println("Usage: java Grep pattern file...");
	    return;
	}
	compile(args[0]);
	for (int i = 1; i < args.length; i++) {
	    File f = new File(args[i]);
	    try {
		grep(f);
	    } catch (IOException x) {
		System.err.println(f + ": " + x);
	    }
	}
    }

}

 

总结:

Grep.java使用正则表达式来封装分行,这样就可以实现BufferedReader的readLine()方法的功能。

使用这则匹配,可以查询匹配的行的内容,可以做日志查询的功能。

直接借助Charset类提供解码(字符解码),但是用上面的代码解码方式改造后,读文件超过10M就抛出java.nio.charset.MalformedInputException的异常。

 

public class MalformedInputException extends CharacterCodingException 当输入字节序列对于给定 charset 来说是不合法的,或者输入字符序列不是合法的 16 位 Unicode 序列时,抛出此经过检查的异常。

提出解决方案一:只是一个思路,与我这里的问题不符合,就没有深入研究。

        方案二描述:在处理大文本文件字符编码转换时碰到该问题,即使用CharsetDecoder.decode()方法解码一个MappedByteBuffer对象时,如果这个MappedByteBuffer对象的长度设置的不好,可能会出现“java.nio.charset.MalformedInputException:Malformed input length is N(N代表一个整数).”的错误。但是如果直接使用Charset.decode()方法,则不会出现这样的错误。

方案二解码成功,但是我测了个20M的文件就OutOfMemoryError。(20M只是我随便测试的一个值)

 

 

 

<!--EndFragment-->

 

1
0
分享到:
评论

相关推荐

    (转)java 正则表达式详解

    Java中的正则表达式是一个强大的文本处理工具,它允许程序员进行复杂的字符串匹配、查找、替换和分割操作。在Java中,正则表达式是通过`java.util.regex`包来实现的,这个包提供了一系列类,如`Pattern`、`Matcher`...

    java IO系统与正则表达式

    正则表达式(Regular Expression,简称regex)是一种模式匹配工具,广泛用于文本搜索、替换和分析。Java中,正则表达式的处理主要依赖于java.util.regex包,其中Pattern类用于编译正则表达式,Matcher类用于在目标...

    Java正则表达式详解

    Java正则表达式是Java编程语言中用于处理文本模式匹配和替换的重要工具。它基于一套特殊的字符序列(元字符)构建,能够描述一系列可能匹配的字符串。正则表达式不仅用于验证字符串格式,如判断是否为数字或有效的...

    java文件io与正则表达式.pdf

    通过上述内容,可以看出《Java 编程第十三讲 IO 系统》不仅涵盖了 Java I/O 系统的基础知识,还深入探讨了高级主题如 NIO 和正则表达式的使用技巧。无论是初学者还是有经验的开发人员,都能从中获得宝贵的知识。

    21天学java part3

    2. **字符串类中的支持**:Java中的`String`和`StringBuffer`类(位于`java.lang`包中)以及`CharBuffer`类(位于`java.nio`包中),都提供了对正则表达式的支持。这些类包含了一些使用正则表达式进行文本处理的方法...

    Java NIO 英文版

    正则表达式在Java NIO中用于处理文本数据,如解析和搜索。本书还介绍Java中的正则表达式API,以及如何在字符串类中使用正则表达式。 字符集章节关注于文本的编码和解码,讲述了如何处理不同字符集之间的转换,以及...

    javaswing小程序-看谁没有写作业.zip

    例如,如果学生的作业文件名格式为“学号_姓名_作业.txt”,那么正则表达式可能设计为匹配这种格式。 在压缩包中,有两个文件:`代码.txt`和`注意事项.txt`。`代码.txt`很可能包含了项目的源代码,我们可以从这里...

    Java.NIO资源下载资源下载

    - **正则表达式基础**:介绍了正则表达式的概念和基本语法。 - **Java 正则表达式 API**:详细讲解了 Java 提供的正则表达式 API 及其使用方法。 - **字符串类的正则表达式方法**:讨论了 String 类中与正则表达式...

    邮件地址抽取

    正则表达式(Regular Expression)是一种模式匹配工具,可以用来进行字符串搜索、替换和提取。在邮件地址抽取中,正则表达式是关键。一个基本的邮件地址正则表达式可能如下所示: `[\w.-]+@[\w-]+(\.[\w-]+)+` 这...

    Java NIO 电子书

    - 提供了一个基于正则表达式的面向对象的文件搜索工具的实现。 - 5.6 总结 - **第六章:字符集** - 6.1 字符集基础 - 讨论了字符集的基础知识。 - 6.2 字符集 - 解释了 Java 中字符集的处理方法。 - 6.3 ...

    一个java NIO的例子

    Java NIO,全称为Non-Blocking ...这个例子"一个java NIO的例子"是学习和理解Java NIO概念和机制的一个很好的起点。通过分析和运行这个示例,开发者可以更深入地理解Java NIO的工作原理,并能更好地运用到实际项目中。

    java代码文件转HTML

    我们可能需要使用`java.io`包下的`BufferedReader`和`FileReader`来读取代码文件,使用`java.nio.file`包的`Files`类来操作文件,以及使用`java.util.regex`包的`Pattern`和`Matcher`类来执行正则表达式。...

    批量查找未打开的文本内的内容

    - Java中可以使用`java.util.regex`包进行正则表达式的匹配,`java.nio.file`包则提供了读取文件的便捷方法。 - C++中可以利用标准库中的`&lt;regex&gt;`头文件进行正则匹配,`&lt;fstream&gt;`用于文件操作。 2. **文件遍历*...

Global site tag (gtag.js) - Google Analytics