HDFS读取实时写入的文件大小

1.用HDFS API写入数据,如何能够读到最新写入的数据?

2.如果写操作一直在进行,但没关闭FileSystem fs,如何获取所写文件的当前大小。

 

想获取最新写入的数据,即使写操作一直没断一直没关闭fs,如何来做呢?

用FSDataInputStream dis = fs.open(path);来做, 参考下面函数testRead函数的已注释部分。

 

如何获取实时的文件大小呢?

两种方式,一种用available(), 另外一种通过FileStatus的getLength()

经过测试:

(1)fs.getFileStatus.getLen():获得的是namespace上的文件状态里的文件大小;
(2)fs.open(path).available():获取文件流的可读字节大小。
比较:
getFileStatus()只能精确到block size的倍数,即写在缓存中的数据不计算在内,直等到文件关闭才将小于blocksize(当前64M)的数据写到硬盘。(hdfs写数据的原理有关,等到缓存刚好称为blocksize那么大,写入到磁盘一个blocksize的block,如果没达到blocksize,则不写到block里,此时除非关闭fs才写入磁盘中。)
而available()返回可读的字节数,当文件小时,可以实时的读取刚写完的数据,而如果数据很大(512-896M),则和前种方法返回相同数,而如果大于2G,则超过int界限4字节能代表的最大值2^31,为负值或其他的不正常的正值。
所以,如果用的话,最好用getFileStatus,long型的值。

	/**
	 * 测试hdfs实时写实时读的性能,本函数写数据,并flush,但是flush只是客户端上传,而hdfs服务器段并不更新filestatus,
	 * 一直到达到block size才更新
	 * @param num
	 */
	public static void testFlushHDFS(int num) {
		try {
			FileSystem fs = FileSystem.get(conf);
			Path path = new Path("/user/root/testflush");
			if(!fs.exists(path)) { 
				fs.create(path);
				fs.close();
			}
			FSDataOutputStream dis = fs.append(path);
			for (int j = 0; j < num; j++) {
				for (int i = 0; i < 1024*10; i++) {
					dis.writeBytes("aaabbbcccdefgqwei");
				}
				dis.flush();
				
				System.out.println("Has done 170K: " + j);
				Thread.sleep(100);
				//dis.sync();
			}
			
			dis.close();
			
			System.out.println("close%%%%%%%%%%");
			Thread.sleep(10000);
			fs.close();
			

		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("write failed!");
			e.printStackTrace();
		} catch(InterruptedException e) {
			System.out.println("thread wait failed!");
			e.printStackTrace();
		}
	}
	public static void testRead() {
		try {
			FileSystem fs = FileSystem.get(conf);
			Path path = new Path(/*"/user/hadooper/testflush"*/"/user/root/testflush"/*1334937621582*/);
			if(!fs.exists(path)) { 
				System.out.println("no file!");
				return;
			}
			FSDataInputStream dis = fs.open(path);
			long length = fs.getFileStatus(path).getLen();
			System.out.println("length: " + (((double)length)/1024/1024) + "M");
			int j =0;
			byte[] b = new byte[1000000];
			System.out.println((double)dis.available()/1024/1024);
		//	while(dis.read(b)>0) {
		//		j++;
			//	System.out.println("******************************************"+(j++));
		//	}
	//		System.out.println("total: 1000 * " + j);
//			dis.read(b);
//			for (int j = 0; j < 990; j++) {
//				dis.read(b);
//				System.out.println(Bytes.toString(b));
//				
//			}
			dis.close();
			fs.close();
			

		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("read failed!");
			e.printStackTrace();
		} 
	}


 

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值