同步照片的时候,发现照片名字不规则 。 以下类产生的格式 2014-04-20 09.44.43.jpg  
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;/******************************************************************************** * 读出数码图片中的拍照时间* * * 原理:* * 1、由于数码图片的拍照时间可以直接从图片中搜索到,所以本例不需要分析EXIF的格式。* * 2、正常的(Normal)数码图片,会有三处到四处的时间,其中第二、第三处固定在一起,* * 第二处是图片拍摄时间,第三处是图片存储时间,一般两者相同,他们之间用NULL值* * 分隔(ASCII值为0),如下:* * 2001:01:02 12:23:56[NULL]2001:01:02 12:23:56[NULL] 2001/01/02* 12:23[NULL]2001/01/02 12:23[NULL]* * 两者位置不定,但格式好查找,八个冒号,两个空格,两个NULL值,其余为数字。* * 不用考虑01:09:34被压缩为1:9:34这样的特例,见EXIF2.1规范关于时间的三段:* * 1. DateTime(第一处,修改时间)* * The date and time of image creation. In this standard it is the date and time* * the file was changed.* * The format is "YYYY:MM:DD HH:MM:SS" with time shown in 24-hour format, and* * the date and time separated by one blank character [20.H].* * When the date and time are unknown, all the character spaces except colons* (":")* * may be filled with blank characters, or else the Interoperability field may* be* * filled with blank characters.* * The character string length is 20 bytes including NULL for termination.* * When the field is left blank, it is treated as unknown.* * Tag = 306 (132.H)* * Type = ASCII* * Count = 20* * Default = none* * 2. DateTimeOriginal(第二处,拍摄时间)* * The date and time when the original image data was generated. For a DSC the* * date and time the picture was taken are recorded.* * The format is "YYYY:MM:DD HH:MM:SS" with time shown in 24-hour format, and* * the date and time separated by one blank character [20.H].* * When the date and time are unknown, all the character spaces except colons* (":")* * may be filled with blank characters, or else the Interoperability field may* be* * filled with blank characters.* * The character string length is 20 bytes including NULL for termination.* * When the field is left blank, it is treated as unknown.* * Tag = 36867 (9003.H)* * Type = ASCII* * Count = 20* * Default = none* * 3. DateTimeDigitized(第三处,存储时间)* * The date and time when the image was stored as digital data. If, for example,* * an image was captured by DSC and at the same time the file was recorded, then* * the DateTimeOriginal and DateTimeDigitized will have the same contents.* * The format is "YYYY:MM:DD HH:MM:SS" with time shown in 24-hour format, and* * the date and time separated by one blank character [20.H].* * When the date and time are unknown, all the character spaces except colons* (":")* * may be filled with blank characters, or else the Interoperability field may* be* * filled with blank characters.* * The character string length is 20 bytes including NULL for termination.* * When the field is left blank, it is treated as unknown.* * Tag = 36868 (9004.H)* * Type = ASCII* * Count = 20* * Default = none* * 3、特别的(Special)相机,如富士系列FUJIFILM,使用XML格式记录EXIF,时间格式如下:* * <exif:DateTimeOriginal>2006-12-24T12:33:08+08:00</exif:DateTimeOriginal>* * 对比正常的(Normal)相片,我们发现两者格式很类似:* * 2006:12:24 12:33:08 Normal* * 2006-12-24T12:33:08 Special* * * 另外:* * 1、由于本人测试的*.tif和*.tiff图片是由*.jpg通过ACDSee转换的,所以可能不准。* * 2、当然,网上有现成的包可供利用,详细方法请自行搜索,以下是包下载地址:* * http://www.drewnoakes.com/code/exif/releases/metadata-extractor-2.2.0.jar* * 3、此例没有按照标准的Java规范格式化。* * 4、开源的目的只有一个:我为人人,人人为我,欢迎开源!* * * Version: 1.10* * Author: NeedJava* * E-Mail: NeedJava@126.com* * Modified: 2007.08.16/2007.08.29/2007.09.28/2010.03.15* * * 你可以使用此程序于任何地方,但请保留程序作者及注释的完整。如果你改进了程序,* * 请在原作者后添加姓名,如:Author: NeedJava/Jack/Mike,版本及修改时间同理。* ******************************************************************************/
public final class PictureRenamer {public static final int FILE_MIN_LENGTH = 102400; // 查找文件的最小字节数public static final int SEQUENCE_LENGTH = 3; // 默认图片序列号的长度private static final char[] SUFFIX_JPG = { '.', 'j', 'p', 'g' }; // { 46,// 106,// 112,// 103 }private static final char[] SUFFIX_JPEG = { '.', 'j', 'p', 'e', 'g' }; // {// 46,// 106,// 112,// 101,// 103// }private static final char[] SUFFIX_JPE = { '.', 'j', 'p', 'e' }; // { 46,// 106,// 112,// 101 }private static final char[] SUFFIX_JFIF = { '.', 'j', 'f', 'i', 'f' }; // {// 46,// 106,// 102,// 105,// 102// }private static final char[] SUFFIX_TIF = { '.', 't', 'i', 'f' }; // { 46,// 116,// 105,// 102 }private static final char[] SUFFIX_TIFF = { '.', 't', 'i', 'f', 'f' }; // {// 46,// 116,// 105,// 102,// 102// }private static final char PRI_SEPARATOR = '-'; // 45 主要分隔符private static final char PRI_SUB_SEPARATOR = '.'; // 32 次要分隔符private static final char SUB_SEPARATOR = ' '; // 32 次要分隔符private int minLength; // 处理图片的最小字节数private int sequenceLength; // 图片序列号的长度private int totalFolders; // 文件夹总数private int totalFiles; // 文件总数private int totalPictures; // 图片总数private int parsedPictures; // 含有有效时间的图片总数private int renamedPictures; // 成功修改名称的图片总数/**************************************************************************** * 构造函数,默认使用当前路径,不搜索100KB以下图片* * 由ACDSee剪裁生成的图片,仍然保留着详细的EXIF信息,哪怕图片只有一个像素,* * 但是这样的图片有意义吗?我觉得既然是数码相片,至少应该大于100KB。* * 当图片大小小于一定值时不予理会,当然你可以取消这样的限制* **************************************************************************/public PictureRenamer() {this(FILE_MIN_LENGTH, SEQUENCE_LENGTH);}public PictureRenamer(int minLength, int sequenceLength) {this.totalFolders = 0;this.totalFiles = 0;this.totalPictures = 0;this.parsedPictures = 0;this.renamedPictures = 0;this.minLength = (minLength < 0 ? FILE_MIN_LENGTH : minLength);this.sequenceLength = (sequenceLength < 0 ? SEQUENCE_LENGTH: sequenceLength);}/**************************************************************************** * 列出当前目录下的文件列表,包括文件和文件夹* * Windows操作系统中,File类中关键是抽象类FileSystem,而FileSystem关键如下:* * public static native FileSystem getFileSystem();* * 实际返回的是子类Win32FileSystem* **************************************************************************/public final void listPictures(File parent, String fileName)throws FileNotFoundException, IOException {File file = new File(parent, fileName);if (file.isDirectory()) {totalFolders++;String[] children = file.list();if (children == null) {return;}// java.util.Arrays.sort( children ); //没必要排序for (int i = 0; i < children.length; i++) {listPictures(file, children[i]);}} else {totalFiles++;char[] suffix = getPictureSuffix(fileName);if (suffix == null) {return;}if (suffix.length > 0) // 当前文件是图片{totalPictures++;// logger( "/r/nProcess/t[" + file.getPath() + "]", false );// TODO:增加观察者,代替logger,使用线程wait和notify// TODO:判断是否是格式化过的图片,如果是,就退出,或者强制修改。XXXX:放弃这个,因为AcdSee处理的经常是错的long length = file.length();if (length < minLength) { /** logger( length + " is less than " +* minLength + " bytes, Ignore.", false* );*/return;}char[] datetime = getPictureDateTime(file);if (datetime == null) {return;} // fileName.substring( 0, fileName.length() - suffix.length// ).toCharArray();if (datetime.length == 19/**/) // 注释掉这行,就可以按序列号重新排序命名{parsedPictures++;String newName = rename(parent, file, fileName, datetime,suffix, 0/*-1*/); // 检查新文件名是否被占用,如果没被占用,就修改名称if (newName == null) { /** logger( "Rename/t[" + newName +* "]/tFailed", false );*/return;}renamedPictures++;// logger( "Rename/t[" + newName + "]/tSucceed", false );}}}}/**************************************************************************** * 根据后缀名判断是否是有效的图片,并且返回小写的后缀名* * lastIndexOf()和substring()可以完成,但是我还想把后缀名小写,并且减少无谓循环* **************************************************************************/private final char[] getPictureSuffix(String fileName) {if (fileName == null) {return null;}int pointer = fileName.length() - 1;if (pointer > 2) // 可能存在“.jpg”这样的文件,即文件名只有4个字符{char c = fileName.charAt(pointer--);if (c == 'g' || c == 'G') // 1{c = fileName.charAt(pointer--);if (c == 'p' || c == 'P') // 2{c = fileName.charAt(pointer--);if ((c == 'j' || c == 'J') && (pointer > -1)) // 3{if (fileName.charAt(pointer) == '.') {return SUFFIX_JPG;} // 4}} else if (c == 'e' || c == 'E') // 2{c = fileName.charAt(pointer--);if (c == 'p' || c == 'P') // 3{c = fileName.charAt(pointer--);if ((c == 'j' || c == 'J') && (pointer > -1)) // 4{if (fileName.charAt(pointer) == '.') {return SUFFIX_JPEG;} // 5}}}} else if (c == 'e' || c == 'E') // 1{c = fileName.charAt(pointer--);if (c == 'p' || c == 'P') // 2{c = fileName.charAt(pointer--);if ((c == 'j' || c == 'J') && (pointer > -1)) // 3{if (fileName.charAt(pointer) == '.') {return SUFFIX_JPE;} // 4}}} else if (c == 'f' || c == 'F') // 1{c = fileName.charAt(pointer--);if (c == 'i' || c == 'I') // 2{c = fileName.charAt(pointer--);if (c == 'f' || c == 'F') // 3{c = fileName.charAt(pointer--);if ((c == 'j' || c == 'J') && (pointer > -1)) // 4{if (fileName.charAt(pointer) == '.') {return SUFFIX_JFIF;} // 5}} else if ((c == 't' || c == 'T') && (pointer > -1)) // 3{if (fileName.charAt(pointer) == '.') {return SUFFIX_TIF;} // 4}} else if (c == 'f' || c == 'F') // 2{c = fileName.charAt(pointer--);if (c == 'i' || c == 'I') // 3{c = fileName.charAt(pointer--);if ((c == 't' || c == 'T') && (pointer > -1)) // 4{if (fileName.charAt(pointer) == '.') {return SUFFIX_TIFF;} // 5}}}}}return null;}/**************************************************************************** * 解析出图片中存储的照相时间* * * 正常相片(Normal),时间格式如下:* * 2001:01:02 12:23:56[NULL]2001:01:02 12:23:56* * 一般都是400到800字节之间,极个别在200和1500左右* * 还有些相机(如HP PhotoSmart R607)竟然在3100左右* * * 特殊相片(Special),如富士系列相片FUJIFILM,时间格式如下:* * <exif:DateTimeOriginal>2006-12-24T13:55:42+08:00</exif:DateTimeOriginal>* * 一般在8000以内任意地方,非常臃长* * * 综上考虑,我不得不用10240来代替原来的2048* * 或者我可以使用分段方法,将出现最多的段放在前面,最少的段放后面,我需要统计* * 现在我遇到的最大的为16000,也就是从2500到16000都有,很少,所以忽略了* * 现在已经分段了* **************************************************************************/private final char[] getPictureDateTime(File file)throws FileNotFoundException, IOException {FileInputStream fis = new FileInputStream(file);// ////// 时间信息全在文件前10240字节内,我们一次读入,一个一个字节分析,//// 但是当需要读入的内容大于10240字节时,最好分批读入,每次2048或1024//// //byte[] buffer = new byte[2048];int readLength = 0;int remain = 0;int n = 128; // 为防止溢出,而且没必要搜索最初的128字节int readTimes = 8; // readTimes和buffer.length的乘积应当在10000至16000左右,保证只搜索图片前16000字节int foundTimes = 0; // 找到有效时间的次数,我们使用第二次找到的时间int foundOffset = 0; // 在哪找到的byte tailByte = 0; // 从当前位置向后偏移18,就是时间的最后一位,判断字符是否符合要求while (--readTimes >= 0&& (readLength = fis.read(buffer, remain, buffer.length- remain)+ remain) >= 0) {// ////// 为速度,不准备转换成char,直接比较数字,如下://// NULL 0//// - 45//// 0 48// 1 49// 2 50// 3 51// 4 52// 5 53// 6 54// 7 55// 8 56// 9 57// / 47// : 58//// 空格 32//// T 84// t 116//// D 68// d 100//// O 79// o 111//// //while ((remain = readLength - n) > 0) {if (remain <= 38 && n >= 19) // 快要到末尾了,把剩余的字节复制到头部,我们重新开始{System.arraycopy(buffer, n -= 19, buffer, 0, remain += 19);foundOffset += n;n = 0;break;}tailByte = buffer[n + 18];// 末尾是数字if (tailByte > 47 && tailByte < 58) {// 必须是数字开头,并且时钟与分钟、分钟与秒钟之间是“:”if (buffer[n] > 47 && buffer[n] < 58&& buffer[n + 16] == 58 && buffer[n + 13] == 58) {// 日期与时间分隔的是空格“ ”,并且年与月、月与日之间是“:”,也就是2006:06:06 06:06:06if (buffer[n + 10] == 32 && buffer[n + 7] == 58&& buffer[n + 4] == 58) {foundTimes++;// Normal,两个时间在一起,或是第二次找到的时间if ((buffer[n + 36] == 58 && buffer[n + 33] == 58&& buffer[n + 30] == 32&& buffer[n + 27] == 58 && buffer[n + 24] == 58)|| (foundTimes == 2)) {foundOffset += n;// System.err.println( foundOffset );fis.close();return parseDateTime(buffer, n, 19);}}// 日期与时间分隔的是“T”或“t”,并且年与月、月与日之间是“-”,也就是2006-06-06T06:06:06else if ((buffer[n + 10] == 84 || buffer[n + 10] == 116)&& buffer[n + 7] == 45 && buffer[n + 4] == 45) {foundTimes++;// Special,含有“DateTimeOriginal”,只判断“D”或“d”、“T”或“t”、“O”或“o”三个字符if ((buffer[n - 9] == 79 || buffer[n - 9] == 111)&& (buffer[n - 13] == 84 || buffer[n - 13] == 116)&& (buffer[n - 17] == 68 || buffer[n - 17] == 100)) {foundOffset += n;// System.err.println( foundOffset );fis.close();return parseDateTime(buffer, n, 19);}}}// 别忘了移位n++;}// 末尾是“:”,向后移动2位else if (tailByte == 58) {// ////// [ CANON 42 H 2006:12:24 12:33:08 2006:12:24 12:33:08 ]// |// [// <exif:DateTimeOriginal>2006-12-24T12:33:08+08:00</exif:DateTimeOriginal>]// |// 0000:00:00 00:00:0A// |// 0000-00-00T00:00:0A// |// 0000:00:00 00:00:0A// |// 0000-00-00T00:00:0A//// //n += 2;}// 末尾是空格“ ”、“T”、“t”,向后移动8位else if (tailByte == 32 || tailByte == 84 || tailByte == 116) {// ////// [ CANON 42 H 2006:12:24 12:33:08 2006:12:24 12:33:08 ]// |// [// <exif:DateTimeOriginal>2006-12-24T12:33:08+08:00</exif:DateTimeOriginal>]// |// 0000:00:00 00:00:0A// |// 0000-00-00T00:00:0A// |// 0000:00:00 00:00:0A// |// 0000-00-00T00:00:0A//// //n += 8;}// 末尾是“-”,向后移动11位else if (tailByte == 45) {// ////// [// <exif:DateTimeOriginal>2006-12-24T12:33:08+08:00</exif:DateTimeOriginal>]// |// 0000-00-00T00:00:0A// |// 0000-00-00T00:00:0A//// //n += 11;}// 末尾不包含以上任何字符,整块向后移动19位else {// ////// [ CANON 42 H 2 f light 24 F 55 ]// | |// 0000-00-00T00:00:0A |// |// 0000-00-00T00:00:0A//// //n += 19;}}}fis.close();return null;}/**************************************************************************** * 将已经定位好的日期时间提取出来* **************************************************************************/private final char[] parseDateTime(byte[] buf, int off, int len) {if (buf == null || off < 0 || len < 0 || off + 1 > buf.length|| off + len > buf.length) {return null;}char[] array = new char[len];byte b;for (int i = 0; i < len; i++) {b = buf[off + i];if (b >= 48/* 0 */&& b <= 57/* 9 */) {array[i] = (char) b;} // 数字,没有检查日期合法性else if (b == 58/* : */ && i <8) {array[i] = PRI_SEPARATOR;} // 由于“:”不能用于文件名,我们用“-”代替else if (b == 58/* : */ && i > 2) {array[i] = PRI_SUB_SEPARATOR;} else {array[i] = SUB_SEPARATOR;} // NULL值或其他非数值用空格代替}System.out.println(array);return array;}/**************************************************************************** * 检查新文件名称是否已被占用,如果没被占用,则修改名称* **************************************************************************/private final String rename(File parent, File file, String name,char[] prefix, char[] suffix, int number) {if (parent == null || file == null || prefix == null || suffix == null) {return null;}char[] array = new char[64/**/];// //int pointer = array.length - suffix.length;System.arraycopy(suffix, 0, array, pointer, suffix.length); // [ .jpg]if (number > 0/*-1*/) {pointer = writeNumberSequence(array, --pointer, number); // [// 001.jpg]array[pointer] = SUB_SEPARATOR/**/; // [ _001.jpg]}int temp = pointer = pointer - prefix.length;System.arraycopy(prefix, 0, array, pointer, prefix.length); // [2008-01-01// 01-01-01_001.jpg]// System.out.println( "Get new file name: " + new String( array,// pointer, array.length - pointer ) );// //if (array.length - temp == name.length()) {for (int i = 0; temp < array.length; temp++, i++) {// 从pointer的点开始字符比较if (array[temp] != name.charAt(i)) {break;}}}if (temp == array.length) {return null/**/;} // 如果图片已经改好了,不需要再次修改// //String newName = new String(array, pointer, array.length - pointer);File newFile = new File(parent, newName);if (newFile.exists()) {return rename(parent, file, name, prefix, suffix, number + 1);} // 已经存在同名但本质不同的图片else if (file.renameTo(newFile)) {return newName;} // 改名成功,测试发现renameTo很耗时间return null;}/**************************************************************************** * 得到诸如001、002、012、569、999、0102、1345、4567、56789这样的数字序列* **************************************************************************/private final int writeNumberSequence(char[] array, int offset, int number) {if (array == null || offset < 0 || number < 0) {return offset;}int i = 0, pointer = offset, temp = number;for (; i < sequenceLength; i++, temp /= 10) {array[pointer--] = (char) (temp % 10 + 48); // 48是'0'的ASCII码}for (; temp > 0; temp /= 10) {array[pointer--] = (char) (temp % 10 + 48); // 48是'0'的ASCII码}return pointer;}public final int getTotalFolders() {return totalFolders;}public final int getTotalFiles() {return totalFiles;}public final int getTotalPictures() {return totalPictures;}public final int getParsedPictures() {return parsedPictures;}public final int getRenamedPictures() {return renamedPictures;}/**************************************************************************** * 既向控制台显示,又向日志写入* **************************************************************************/private final static void logger(String message, boolean both) {if (message == null || message.length() < 1) {return;}if (both) {System.out.println(message);}System.err.println(message);}public static void main(String[] args) {try {System.setErr(new PrintStream(new FileOutputStream("log.txt")));long start = System.currentTimeMillis();PictureRenamer rpodt = new PictureRenamer(10240, 3);rpodt.listPictures(null, "img");logger("/r/n共有文件夹:" + (rpodt.getTotalFolders()) + "个", true);logger("/r/n共有文件:" + (rpodt.getTotalFiles()) + "个", true);logger("/r/n共有图片:" + (rpodt.getTotalPictures()) + "张", true);logger("/r/n有效图片:" + (rpodt.getParsedPictures()) + "张", true);logger("/r/n修改成功:" + (rpodt.getRenamedPictures()) + "张", true);logger("/r/n修改失败:"+ (rpodt.getParsedPictures() - rpodt.getRenamedPictures())+ "张", true);logger("/r/n总共耗时:" + (System.currentTimeMillis() - start) + "毫秒",true);} catch (FileNotFoundException fnfe) {fnfe.printStackTrace();}catch (IOException ioe) {ioe.printStackTrace();}catch (Exception e) {e.printStackTrace();}}
}

工具类批量修改照片的名字相关推荐

  1. 批量修改照片名称的快速方法

    平时我们出去旅游的时候,都喜欢拍摄照片,如果恰巧你还是一名摄影爱好者,那么肯定会用相机拍摄很多的照片,并且还会将照片导入到电脑里,时间久了电脑里肯定会保存有很多不同时间和不同地点的照片,如果不好好整理 ...

  2. 【Python】批量修改照片文件名为拍摄日期

    更新2022.09.09 代码已经大幅更新,需要的同学可以去这篇博客自取. 更新 2021.05.07 合并了修改照片的拍摄日期和文件名功能,请看:批量修改照片的拍摄日期和文件名 需求 最近整理老照片 ...

  3. 【Python】批量修改照片日期

    更新2022.09.09 代码已经大幅更新,需要的同学可以去这篇博客自取. 更新 2021.05.07 合并了修改照片的拍摄日期和文件名功能,请看:批量修改照片的拍摄日期和文件名 需求 最近整理老照片 ...

  4. 如何批量修改文件名?批量修改照片文件名和添加前缀

    通常我们使用手机或者相机拍摄了一堆照片拷贝到电脑之后,照片的命名通常都是随机混乱的,如果要规范文件命名,你是不是会去一个一个去修改文件名呢?其实完全不需要这么麻烦,今天电脑百事小编就来教大家一个批量快 ...

  5. 批量修改照片(图片)格式、批量旋转照片方向(图片)、批量命名照片(图片)

    1 修改照片格式的方式 1.批量修改照片格式.例如批量将所有  .png 格式的照片修改成  .jpg格式 : mogrify -format jpg *.png 2 旋转照片方向的方式 1.批量将照 ...

  6. 文件批量重命名工具,批量修改文件名的实现思路

    在工作中可能会遇到文件数据成果已经制作完成后,遇到文件命名规则变更,需要对大量文件重命名,甚至修改目录结构的.本文介绍利用FME实现文件批量重命名的解决方法. 因为工作实际情况各不相同,文件重命名规则 ...

  7. 利用照片名中的日期批量修改照片的修改时间和访问时间(python实现)

    运用场景 前些天家人换了手机,在导入一些照片时发现相册APP中的照片排序混乱,好在照片名中有日期信息,就利用pyhton实现批量修改照片的相关时间 代码实现 修改文件时间,首先想到的就是利用pytho ...

  8. 计算机怎么快速改图片名称,如何批量修改文件名?批量修改照片文件名和添加前缀方法...

    通常我们使用手机或者相机拍摄了一堆照片拷贝到电脑之后,照片的命名通常都是随机混乱的,如果要规范文件命名,你是不是会去一个一个去修改文件名呢?其实完全不需要这么麻烦,今天电脑百事小编就来教大家一个批量快 ...

  9. Python如何批量修改照片像素大小

    可以使用Pillow库来批量修改照片像素大小.以下是一个示例代码: from PIL import Image import osinput_folder = "input_folder_p ...

最新文章

  1. MySQL5.7的date类型_Mysql5.7 虚拟列数据类型为DATE时,如何存入数据?
  2. 芯片项目烂尾怎么办?国家发改委回应了!
  3. oracle1537,dataguard 出现ORA-16136错误
  4. 【C++】 C++标准模板库(一) Vector
  5. * 构建一个list集合存储5个学生对象, 过滤年龄小于18的,存入一个新的map集合
  6. QT中的QButtonGroup
  7. 测视力距离5米还是3米_多功能视力表灯箱的用法
  8. Leetcode二叉树递归:563.binary-tree-tilt(二叉树的坡度)
  9. vue中watch监听路由传来的参数变化
  10. ios 图片合成 处理合成模糊 水印 模板图片合成
  11. 实现简单的web框架
  12. Anaconda下载(Windows系统)
  13. x轴z轴代表的方向图片_x轴y轴z轴代表的方向_x轴y轴z轴代表的方向图
  14. R语言根据日历周期处理时间序列数据(周、月、年等):使用xts包的apply.quarterly函数和mean函数计算时间序列的季度平均值(quarterly)
  15. 国产系统deepin。为什么要国产化?国产化意味着什么?(含Deepin系统部分问题解决)
  16. 华南理工计算机就业棒棒,为梦想、为公益,华南理工大学学子为爱发声
  17. 1.9无穷小新生五十年
  18. android 短信打开APP
  19. Kinect Fusion三维重建
  20. 如何平衡新老策略的好与坏,一道常见风控送命题解答

热门文章

  1. 公众账号迁移:微信订阅号怎么升级服务号?
  2. atari游戏模型_在Atari.com免费玩经典街机游戏
  3. python爬取公众号文章_python爬取微信公众号历史文章
  4. 确保软件开发生命周期(SDLC)的安全
  5. CTDC 2017 首席技术官领袖峰会 | 技术、探索、创新
  6. 用python写银行叫号系统(这个是学校的实训题目,真的没什么技术含量)
  7. R 数据正态分布检验
  8. 如何推广微信公众号(快速增加粉丝数量)?
  9. 实现支付功能并生成二维码
  10. mba辅导班哪个机构好?全方位解答<title>mba辅导班</title>