Java核心编程四:文件流与正则匹配

1 流
Java.io中定义了抽象基类InputStream和OutputStream。分别支持基本的读和写操作。
int read(int n) 读取指定字节,结束返回-1;
int read(byte[] b,int offset,int len);
long skip(long n) 路过指定的偏移
int available() 返回流中可读的字节数。
void close() 关闭流

int write(int n)
int write(byte[] b,int offset,int len)
void close()
void flush()

2 流结构
二进制处理流类,只能读出为字节数组。


本地编码环境与unicode转换的处理器的类

这些层次类可以通过装饰器模式进行组合,以完成更复杂的功能。其构造函数都可以接受一个字符串路径对象。
2.1 Data处理接口
DataInput接口提供了一系列readXXX()的方法,XXX代表了一种基础数据类型。
DataOutput接口也提供了一系列writeXXX()的方法。

2.2 随机文件访问
RandomAccessFile(file,mode)返回可被随机访问的文件对象。
void seek(pos) 寻找到指定位置
long getFilePointer()  返回当前文件指针位置。

2.3 字符集与编码
如前所知,Java使用了utf-16的unicode编码。
Charset类定义了字符集操作,用forName()可以返回相应字符集的对象实例。有了字符串,我们便可以在unicode和本地编码之间进行转换。
encode(String str)
String decode(ByteBuffer bb).toString()
noi包中提供了ByteBuffer和CharBuffer用于对字节数组和字符数组进行包装。

2.4 文本输出与输入
printWriter作为一个输出类,可以连接到不同的输出端上,通过构造函数可以传入输出的流和writer上。

Scanner、BufferReader、FileReader等可以用来进行文本的输入。

4 使用流
下面的例子展现了使用缓冲输入器读取文件的方法。
FileInputStream fi = new FileInputStream("F:\\test\\hello\\src\\Test\\IRule.java");
InputStreamReader reader = new InputStreamReader(fi);
BufferedReader breader = new BufferedReader(reader);
String line;
while((line = breader.readLine()) != null)
{
    System.out.println(line);
}

下面的代码结合使用输入流和读取器,打开一个网页并按UTF8解码输出。

		try
		{
			URL url = new URL("http://www.baidu.com");
			InputStream is  = url.openStream();
			
			
//			byte[] buf = new byte[1024];			
//			int nread = 0;
//			Charset charset = Charset.forName("UTF8");
//			while((nread = is.read(buf))>=0)
//			{				
//				String text = charset.decode(ByteBuffer.wrap(buf,0,nread)).toString();			
//				System.out.print(text);				
//			}
			
			InputStreamReader ir = new InputStreamReader(is,"utf8");
			Scanner sc = new Scanner(ir);			
			while(sc.hasNextLine())
			System.out.println(sc.nextLine());		
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}	

StringBuilder支持动态的扩展当前的字符串数组,并在需要的时候转换为值类型的字符串。其API如下:
length() 
append()
appendCodePoint(int)
setCharAt(int,char)
insert(offset,str)
delete(start,end)
toString()

5 对象流
ObjectOutputStream与ObjectInputStream可以将实现Serelizable接口的类自动的序列化和反序列化。由于接口中没有方法,因此我们的类不需要做更多的更改了。
ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream("obj.dat"));
oos.writeObject(new Teacher("Jobs",30));
oos.close();
ObjectInputStream ois = new  ObjectInputStream( new FileInputStream("obj.dat") );
Teacher t = (Teacher) ois.readObject();
ois.close();
System.out.printf("read from file %s\n",t.toSting());


序列化的对象采用了Java特定的编码方式,这里不对这种格式进行描述。

对象持久面临的一个问题是引用对象的处理,我们希望存储之后恢复的对象结构和之前的对象结构完全一致。

Java在序列化时采用了标识的方式,对于每个序列化对象都会分配一个ID,在对象序列化前会先检查ID是否已经序列化,如果已经序列化,则只保存一个ID引用;如果没有才将对象完整序列化下来。反序列化的过程与之相反。

如果我们的对象中包含一些暂时数据,我们不希望对其进行持久化,则可以将其标注为transient。

Java在反序列化时会检查文件中的类与程序中的类的SHA1是否相同,用来保证不会将旧对象布局反序列化到程序中。我们可以在类中声明seriaVersionUID常量,这样使得jvm将使用我们声明的常量作为SHA1。这种方法对于我们的类方法变更比较有用,但如果有属性字段变改,则会有问题。

序列化也可以用作复制使用,可以序列化后,传送到另外的地方再反序列化出来,对象是一个深拷贝的对象。但这样会慢很多。当然对象需要自己实现深clone方法。

6 文件管理
File类,即可以表示文件也可以表示为目录的抽象。
String[] list() 如果是目录,返回目录下的文件名数组。
bool canRead/canWrite/canExcute  判断文件读写属性
bool createTempFile(prefix,suffix,path=.)  创建临时文件
bool delete/deleteOnExit()
bool exists()
File getCanonicalFile()  返回特定系统上的标准路径名的文件对象。
String getCanonicalPath() 返回特定系统的标准路径字符串
String getName()/getPath() 获取文件名/路径部分
String getParent()/File getParentFile()  获取父目录/文件对象
bool isDirectory/isFile/isHidden   获取文件的属性
long length() 获取文件大小
string[] list()/File[] listFiles()  列出目录
bool mkdir()    创建目录
bool renameTo() 重命名

7 NIO
NIO中提供了内存映射的文件访问方式以及文件锁功能。
7.1 内存映射
使用方式为从文件流获取channel,通过channel进行映射操作,可以对返回的buffer进行数组操作。
File file = new File("F:\\test\\hello\\src\\Test\\IRule.java");
fis = new FileInputStream(file);
FileChannel fc = fis.getChannel();
MappedByteBuffer buff = fc.map(MapMode.READ_ONLY, 0, file.length());
Charset cset = Charset.forName("gb2312");
System.out.println(cset.decode(buff).toString());

针对MappedByteBuffer,有下面的API:
getInt/Long/Short/Char/Float/Double()
putInt/Long/Short/Char/Float/Double()
order(LITTLE_ENDIAN/BIG_ENDIAN)
bool hasRemaining()  是否仍有数据
int limit()          缓冲中的总数据长度
byte get(int idx)    获取指定位置的字节,支持获取到数组
ByteBuffer put(idx)  向缓冲区中写入字节,支持数组写入


缓冲区在get时并不会清除数据,因此当读到头时,需要调用clear清除,以为后续写操作腾出空间。更多接口参考nio的Buffer文档。

7.2 文件锁
通过channel可以对文件进行锁定。
FileLock lock() 获取整个文件的锁,若无法锁定则阻塞
FileLock tryLock() 尝试获取锁,若无法获取则返回null
Filelock lock(start,size,exclusive)   获取文件中部分位置的锁
Filelock tryLock(start,size,exclusive)
release() 释放锁

8 正则表达式
正则表达式的基础知识就不在此详细描述了。
String str = "Java is good than java";
Pattern p = Pattern.compile("[J|j]ava");
Matcher m = p.matcher(str);
while(m.find())
{
    //System.out.println(str.substring(m.start(),m.end()));
    System.out.println(m.group());
}
System.out.println(m.replaceAll("C++"));


regex.pattern的API如下:
static Pattern compile(string expr,int flag) flag为CAST_INSENSITVIE...
Matcher Matcher(CharSequence input)  返回一个matcher对象,以对输入进行定位
String[] split(input) 
regex.Matcher的API如下:
bool matches() 是否可匹配模式
bool find(int) 尝试寻找下一个匹配字符串
int start/end() 返回当前匹配的开始和结束位置
String group()  返回当前匹配的字符串
int groupCount() 返回匹配的个数
String replaceAll/First() 将每一个匹配进行替换
Matcher reset() 返回重置的matcher对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值