关于java.nio.BufferOverflowExceptionat

项目运行的时候报了一个新的错误,记录一下。
贴上报错:

java.nio.BufferOverflowExceptionat java.nio.HeapByteBuffer.put(HeapByteBuffer.java:183)
 at java.nio.ByteBuffer.put(ByteBuffer.java:832)
 at com.util.FileIO.write2File(FileIO.java:79)

分析一下,报错是在流写入文件的时候。

public static void write2File(String items) throws IOException {
		String path = "temp/test";
		File file = new File(path);
		if (!file.exists()) {
			file.getParentFile().mkdirs();
		}
		file.createNewFile();
		// 切记,此处的初始化必须在确定要修改文件才执行,否则由于写入流并没有指定允许追加,所以一旦打开写入流指针默认为0,则清空文件
		FileOutputStream outputStream = null;
		FileChannel out = null;
		RandomAccessFile raf = null;
		try {
			raf = new RandomAccessFile(path, "rw");
			FileChannel fc = raf.getChannel();

			Charset charset = Charset.forName("UTF-8");
			CharsetDecoder decoder = charset.newDecoder();
			ByteBuffer buffer = ByteBuffer.allocate(1024);
			CharBuffer cb = CharBuffer.allocate(1024);
			StringBuffer line = new StringBuffer("");

			int count = fc.read(buffer);
			// NIO读取文件
			while (count != -1) {
				buffer.flip();
				decoder.decode(buffer, cb, false);
				cb.flip();
				while (cb.hasRemaining()) {
					line.append(cb.get());
				}
				buffer.clear();
				cb.clear();
				count = fc.read(buffer);
			}
			raf.close();

			// 有数据则读取比对
			List<String> itemsList = Arrays.asList(items.split(","));
			List<String> lineList = Arrays.asList(line.toString().split(","));

			// tmp用于临时存储itemsList, 数组转化的集合长度固定不能执行增删操作,所以新建两个集合
			List<String> tmp = new ArrayList<String>();
			List<String> l1 = new ArrayList<String>();
			List<String> l2 = new ArrayList<String>();

			tmp.addAll(itemsList);
			l1.addAll(itemsList);
			l2.addAll(lineList);

			l1.removeAll(lineList);
			l2.removeAll(tmp);
			// 存在差异则写入新的数据
			if (l1.size() != 0 || l2.size() != 0) {
				outputStream = new FileOutputStream(path, false);
				out = outputStream.getChannel();
				buffer.clear();
				byte[] bytes = items.getBytes();//将字符串转换为字符数组
				buffer.put(bytes);
				buffer.flip();
				log.info("content change:" + items);
				out.write(buffer);

				HttpUtils http = new HttpUtils(items);
				int uploadCount = 0;
				while (uploadCount < 3) {
					http.dataDeal();
					String response = http.postRequest();
					JSONObject resJSON = JSONObject.fromObject(response);
					if (resJSON != null && resJSON.containsKey("code")) {
						int code = resJSON.getInt("code");
						if (code == 0) {
							uploadCount = 3;
						}else{
							uploadCount++;
						}
					}
				}

			} else {
				log.info("no change");
			}
		} finally {
			if (outputStream != null) {
				outputStream.close();
			}
			if (raf != null) {
				raf.close();
			}
			log.info(
					"=-------------------------------------------------------------------------------------------------=");
		}

	}

发现问题最关键的在于
ByteBuffer buffer = ByteBuffer.allocate(1024);

什么是ByteBuffer ?

一般是操作数据的字节(byte)形式,经常会用到ByteBuffer这样一个类。ByteBuffer提供了两种静态实例方式:
public static ByteBuffer allocate(int capacity)
public static ByteBuffer allocateDirect(int capacity)

(为什么要提供两种方式呢?这与Java的内存使用机制有关。第一种分配方式产生的内存开销是在JVM中的,而另外一种的分配方式产生的开销在JVM之外,以就是系统级的内存分配。不细说,咱也不会。)

写入的字节流超过了分配的1024,因此写入失败。只需要扩大分配容量即可。尴尬。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值