/** * 使用切割的方式来替换给定文件中的一段数据 * * @param file 给定的文件 * @param off 要替换的一段数据的开始位置(包括) * @param length 要替换的一段数据的长度,大于1 * @param newData 用来替换旧数据的新数据 * @throws IOException * @throws LengthTooBigException (fileLength - (off + length)) > 31457280 * 因为本方法采用的是先把需要替换的数据之后的数据读到内存中,然后将文件截短,最后把之前保存的数据写到文件中。因此读到内存中的数据不能太大 */ public static void replaceFileDataByCutWay(File file, long off, long length, byte[] newData) throws IOException, LengthTooBigException { // 获取文件长度 long fileLength = file.length(); // 验证数据合法性 CheckingUtils.valiLongValue(off, 0, fileLength - 1, "off"); CheckingUtils.valiLongValue(off + length, off + 1, fileLength, "length"); CheckingUtils.valiObjectIsNull(newData, "newData"); if (newData.length > 0) { // 计算需读到内存的数据的长度 long keepDataLength = fileLength - (off + length); // 如果需要读到内存的数据长度为0 if (keepDataLength == 0) { // 打开原文件 RandomAccessFile raf = new RandomAccessFile(file, "rw"); // 设置长度 raf.setLength(off); // 将新数据写到末尾去 raf.write(newData); // 关闭原文件 raf.close(); } else if (keepDataLength <= 31457280) { // 打开原文件 RandomAccessFile raf = new RandomAccessFile(file, "rw"); // 读取要保存的数据 byte[] keepData = new byte[(int) keepDataLength]; raf.seek(off + length); raf.read(keepData); // 将文件截掉合适的长度 if (length != 0) { raf.setLength(fileLength - length); } // 写入新数据 raf.seek(off); raf.write(newData); // 写入保存的数据 raf.write(keepData); // 关闭原文件 raf.close(); } else { throw new LengthTooBigException( "Need to read the length of data of the memory more than 30720 ((fileLength - (off + length)) > 30720)"); } } }
/** * 使用切割的方式在给定的文件中给定的位置处插入一段数据 * * @param file 给定的文件 * @param off 在此处开始插入数据最小值为0表示将数据插在文件头部,最大值为文件长度表示将数据插在文件尾部 * @param data 要插入的数据 * @throws IOException * @throws LengthTooBigException (fileLength - (off + length)) > 30720 * 因为本方法采用的是先把需要替换的数据之后的数据读到内存中,然后将文件截短,最后把之前保存的数据写到文件中。因此读到内存中的数据不能太大 */ public static void insertFileDataByCutWay(File file, long off, byte[] data) throws IOException, LengthTooBigException { // 获取文件长度 long fileLength = file.length(); // 验证数据合法性 CheckingUtils.valiLongValue(off, 0, fileLength, "off"); CheckingUtils.valiObjectIsNull(data, "data"); if (data.length > 0) { // 计算需读到内存的数据的长度 long keepDataLength = fileLength - off; // 如果需要读到内存的数据长度为0 if (keepDataLength == 0) { writeByte(file, data, true); } else if (keepDataLength <= 31457280) { // 打开原文件 RandomAccessFile raf = new RandomAccessFile(file, "rw"); // 读取要保存的数据 byte[] keepData = new byte[(int) keepDataLength]; raf.seek(off); raf.read(keepData); // 写入新数据 raf.seek(off); raf.write(data); // 写入保存的数据 raf.write(keepData); // 关闭原文件 raf.close(); } else { throw new LengthTooBigException( "Need to read the length of data of the memory more than 30720 ((fileLength - (off + length)) > 30720)"); } } }
/** * (01)、获取指定数量的随机数,可以指定是否允许重复 * @param size 指定数量,取值范围大于0 * @param maxValue 最大值,如果小于0,无限制 * @param repeat 是否允许重复,true:允许 * @return 长度为size的随机数数组 */ public static int[] getRandoms(int size, int maxValue, boolean repeat) { CheckingUtils.valiIntMinValue(size, 1, "size"); Random random = new Random(); int[] randoms = new int[size]; if(repeat){ //如果允许重复 if(maxValue < 0){ //如果无限制 for(int w = 0; w < randoms.length; w++){ randoms[w] = random.nextInt(); } }else{ //如果有限制 for(int w = 0; w < randoms.length; w++){ randoms[w] = random.nextInt(maxValue); } } }else{ //如果不允许重复 if(maxValue < 0){ //如果无限制 int length = 0; while(length <= size){ //条件为长度小于等于size boolean skip = false; int ran = random.nextInt(); for(int e = 0; e < length; e++){ //遍历寻找是否有重复的 if(randoms[e] == ran){ //有的话 skip = true; //跳 break; //结束本层循环 } } if(skip){ //如果跳 continue; } randoms[length++] = ran; //如果不跳,放进去,长度加1 } }else{ //如果有限制 int length = 0; while(length <= size){ //条件为长度小于等于size boolean skip = false; int ran = random.nextInt(maxValue); for(int e = 0; e < length; e++){ //遍历寻找是否有重复的 if(randoms[e] == ran){ //有的话 skip = true; //跳 break; //结束本层循环 } } if(skip){ //如果跳 continue; } randoms[length++] = ran; //如果不跳,放进去,长度加1 } } } return randoms; }
/** * 使用创建新文件的方式来替换给定文件中的一段数据 * * @param file 给定的文件 * @param off 要替换的一段数据的开始位置(包括) * @param length 要替换的一段数据的长度,大于1 * @param newData 用来替换旧数据的新数据 * @throws IOException */ public static void replaceFileDataByNewFileWay(File file, long off, long length, byte[] newData) throws IOException { // 获取文件长度 long fileLength = file.length(); // 验证数据合法性 CheckingUtils.valiLongValue(off, 0, fileLength - 1, "off"); CheckingUtils.valiLongValue(off + length, off + 1, fileLength, "length"); CheckingUtils.valiObjectIsNull(newData, "newData"); if (newData.length > 0) { // 打开原文件 RandomAccessFile raf = new RandomAccessFile(file, "rw"); // 创建一新文件 File newFile = null; try { newFile = createFileByCurrentDateTime(file.getParentFile()); } catch (IOException e) { raf.close(); throw e; } // 打开新文件 RandomAccessFile newRaf = null; try { newRaf = new RandomAccessFile(newFile, "rw"); } catch (FileNotFoundException e) { raf.close(); newFile.delete(); throw e; } byte[] data = new byte[IOUtils.MAX_OPERATION_LENGTH]; // 读取原文件中之前的数据写入到新文件中去 raf.seek(0); while (raf.getFilePointer() < off) { int number = (int) (off - raf.getFilePointer()); int readNumber = -1; if (number >= IOUtils.MAX_OPERATION_LENGTH) { readNumber = raf.read(data); } else { readNumber = raf.read(data, 0, number); } newRaf.write(data, 0, readNumber); } // 写入新数据 newRaf.write(newData); // 读取原文件中之后的数据写入到新文件中去 raf.seek(off + length); int number = -1; while ((number = raf.read(data)) != -1) { newRaf.write(data, 0, number); } // 关闭文件 newRaf.close(); raf.close(); // 记录原文件的名字并删掉原文件 String filePath = file.getPath(); // 如果原文件删除失败 if (!file.delete()) { // 删除新文件 newFile.delete(); throw new IOException(); } // 将新文件重命名 newFile.renameTo(new File(filePath)); } }