diff --git a/gitcontroltool/Blob.java b/gitcontroltool/Blob.java index 5c08277..514dd64 100644 --- a/gitcontroltool/Blob.java +++ b/gitcontroltool/Blob.java @@ -1,26 +1,26 @@ -/* 任务一的理解:主要是针对blob对象 -@1. 给定value,向存储中添加对应的key-value - step1 在工作区新建一个file对象,并写入文件内容(控制台输入、或者是写入一个已有的文件) - step2 为这个file对象重命名为《文件的hash值》并保存 +/* 浠诲姟涓鐨勭悊瑙o細涓昏鏄拡瀵筨lob瀵硅薄 +@1. 缁欏畾value锛屽悜瀛樺偍涓坊鍔犲搴旂殑key-value + step1 鍦ㄥ伐浣滃尯鏂板缓涓涓猣ile瀵硅薄锛屽苟鍐欏叆鏂囦欢鍐呭锛堟帶鍒跺彴杈撳叆銆佹垨鑰呮槸鍐欏叆涓涓凡鏈夌殑鏂囦欢锛 + step2 涓鸿繖涓猣ile瀵硅薄閲嶅懡鍚嶄负銆婃枃浠剁殑hash鍊笺嬪苟淇濆瓨 -@2. 给定key,查找得到对应的value值 - 如果读取《文件的hash值》就可以得到文件内容,此时《文件的hash值》就是key,文件内容就是value。 +@2. 缁欏畾key锛屾煡鎵惧緱鍒板搴旂殑value鍊 + 濡傛灉璇诲彇銆婃枃浠剁殑hash鍊笺嬪氨鍙互寰楀埌鏂囦欢鍐呭锛屾鏃躲婃枃浠剁殑hash鍊笺嬪氨鏄痥ey锛屾枃浠跺唴瀹瑰氨鏄痸alue銆 */ package gitcontroltool; import java.io.*; -// 封装Blob类,类中属性包含blob对象的名字,一个输入流变量(用来读取具体的文件内容) +// 灏佽Blob绫伙紝绫讳腑灞炴у寘鍚玝lob瀵硅薄鐨勫悕瀛楋紝涓涓緭鍏ユ祦鍙橀噺锛堢敤鏉ヨ鍙栧叿浣撶殑鏂囦欢鍐呭锛 public class Blob { - private String name; // blob对象的名字 - FileInputStream input; // 输入流变量 - public Blob(String filename) throws Exception { // blob对象的构造方法,原有文件内容不变,生成一个文件名为hash(origin's value)的blob对象 - Hash s = new Hash(filename,true); // step1.传入一个已有的具体文件,先生成对应的hash值 - this.name = s.getSha(); // step2.为当前blob对象赋予hash值做名字 - this.input = new FileInputStream(filename); // step3.输入流变量引用由当前传入的具体文件生成的file对象实例,这一步只能在构造方法函数内实现 + private String name; // blob瀵硅薄鐨勫悕瀛 + FileInputStream input; // 杈撳叆娴佸彉閲 + public Blob(String filename) throws Exception { // blob瀵硅薄鐨勬瀯閫犳柟娉曪紝鍘熸湁鏂囦欢鍐呭涓嶅彉锛岀敓鎴愪竴涓枃浠跺悕涓篽ash锛坥rigin's value锛夌殑blob瀵硅薄 + Hash s = new Hash(filename,true); // step1.浼犲叆涓涓凡鏈夌殑鍏蜂綋鏂囦欢锛屽厛鐢熸垚瀵瑰簲鐨刪ash鍊 + this.name = s.getSha(); // step2.涓哄綋鍓峛lob瀵硅薄璧嬩簣hash鍊煎仛鍚嶅瓧 + this.input = new FileInputStream(filename); // step3.杈撳叆娴佸彉閲忓紩鐢ㄧ敱褰撳墠浼犲叆鐨勫叿浣撴枃浠剁敓鎴愮殑file瀵硅薄瀹炰緥锛岃繖涓姝ュ彧鑳藉湪鏋勯犳柟娉曞嚱鏁板唴瀹炵幇 } - public void createBlob() throws IOException { // 写入传入文件的内容,写入后用blob对象的名字保存。 - FileOutputStream output = new FileOutputStream(this.name); // 文件不存在会自动创建 - byte[] buffer = new byte[1024]; // 利用字符数组做缓冲器,提升读写速度。 + public void createBlob() throws IOException { // 鍐欏叆浼犲叆鏂囦欢鐨勫唴瀹癸紝鍐欏叆鍚庣敤blob瀵硅薄鐨勫悕瀛椾繚瀛樸 + FileOutputStream output = new FileOutputStream(this.name); // 鏂囦欢涓嶅瓨鍦ㄤ細鑷姩鍒涘缓 + byte[] buffer = new byte[1024]; // 鍒╃敤瀛楃鏁扮粍鍋氱紦鍐插櫒锛屾彁鍗囪鍐欓熷害銆 int numRead = 0; do { numRead = input.read(buffer); @@ -32,13 +32,14 @@ public void createBlob() throws IOException { // 写 output.close(); } - public String getkey() { // 写入传入文件的内容,写入后用blob对象的名字保存。 + public String getkey() { // 鍐欏叆浼犲叆鏂囦欢鐨勫唴瀹癸紝鍐欏叆鍚庣敤blob瀵硅薄鐨勫悕瀛椾繚瀛樸 String key = this.name; return key; } + @Override - public String toString() { // 重写object的tostring方法。 + public String toString() { // 閲嶅啓object鐨則ostring鏂规硶銆 return "blob " + name; } } diff --git a/gitcontroltool/Hash.java b/gitcontroltool/Hash.java index e5cd5ee..c397c2a 100644 --- a/gitcontroltool/Hash.java +++ b/gitcontroltool/Hash.java @@ -1,53 +1,54 @@ package gitcontroltool; import java.io.*; -import java.security.MessageDigest; // 导入消息摘要,提供信息摘要SHA1算法 +import java.security.MessageDigest; // 瀵煎叆娑堟伅鎽樿锛屾彁渚涗俊鎭憳瑕丼HA1绠楁硶 + public class Hash { -// 将sha值的计算封装为一个类,该类中有成员属性sha1(初始sha值)和outFile(最终转为16进制的字符串) -// 提供基于文件内容(blob)和文件名或字符串(针对tree)的sha值计算和读取方法、提供字符数组转字符串的方法 +// 灏唖ha鍊肩殑璁$畻灏佽涓轰竴涓被锛岃绫讳腑鏈夋垚鍛樺睘鎬ha1锛堝垵濮媠ha鍊硷級鍜宱utFile锛堟渶缁堣浆涓16杩涘埗鐨勫瓧绗︿覆锛 +// 鎻愪緵鍩轰簬鏂囦欢鍐呭锛坆lob锛夊拰鏂囦欢鍚嶆垨瀛楃涓诧紙閽堝tree锛夌殑sha鍊艰绠楀拰璇诲彇鏂规硶銆佹彁渚涘瓧绗︽暟缁勮浆瀛楃涓茬殑鏂规硶 private byte[] sha1; - public Hash(String inFile,boolean isFile) throws Exception{ // 构造该类的对象时,会根据是否是文件来初始化相应的对象私有成员属性 + public Hash(String inFile,boolean isFile) throws Exception{ // 鏋勯犺绫荤殑瀵硅薄鏃讹紝浼氭牴鎹槸鍚︽槸鏂囦欢鏉ュ垵濮嬪寲鐩稿簲鐨勫璞$鏈夋垚鍛樺睘鎬 if(isFile){ FileInputStream input = new FileInputStream(inFile); - this.sha1 = SHA1content(input); // 利用文件内容计算hash值 + this.sha1 = SHA1content(input); // 鍒╃敤鏂囦欢鍐呭璁$畻hash鍊 } else{ - this.sha1 = SHA1name(inFile); // 用文件名计算hash值 + this.sha1 = SHA1name(inFile); // 鐢ㄦ枃浠跺悕璁$畻hash鍊 } } - public static byte[] SHA1content(InputStream is) throws Exception { // @1.对一个具体文件,通过文件内容计算sha值的方法,即blob对象的key值 - byte[] buffer = new byte[1024]; // 采用一个字节数组做缓冲器 - MessageDigest complete = MessageDigest.getInstance("SHA-1"); // 指定SHA1算法 + public static byte[] SHA1content(InputStream is) throws Exception { // @1.瀵逛竴涓叿浣撴枃浠讹紝閫氳繃鏂囦欢鍐呭璁$畻sha鍊肩殑鏂规硶锛屽嵆blob瀵硅薄鐨刱ey鍊 + byte[] buffer = new byte[1024]; // 閲囩敤涓涓瓧鑺傛暟缁勫仛缂撳啿鍣 + MessageDigest complete = MessageDigest.getInstance("SHA-1"); // 鎸囧畾SHA1绠楁硶 int numRead = 0; do { - numRead = is.read(buffer); // 从输入流中读buffer.length个字节给buffer,并且返回实际读取的字节数给整型变量numRead + numRead = is.read(buffer); // 浠庤緭鍏ユ祦涓buffer.length涓瓧鑺傜粰buffer锛屽苟涓旇繑鍥炲疄闄呰鍙栫殑瀛楄妭鏁扮粰鏁村瀷鍙橀噺numRead if (numRead > 0) { complete.update(buffer, 0, numRead); } - } while (numRead != -1); // numRead = -1代表文件读取完毕。需要关闭输入流,并且返回消息摘要字节数组。 + } while (numRead != -1); // numRead = -1浠h〃鏂囦欢璇诲彇瀹屾瘯銆傞渶瑕佸叧闂緭鍏ユ祦锛屽苟涓旇繑鍥炴秷鎭憳瑕佸瓧鑺傛暟缁勩 is.close(); return complete.digest(); } - public static byte[] SHA1name(String s) throws Exception{ // @2.对一个文件或文件夹名计算sha值的方法 + public static byte[] SHA1name(String s) throws Exception{ // @2.瀵逛竴涓枃浠舵垨鏂囦欢澶瑰悕璁$畻sha鍊肩殑鏂规硶 MessageDigest complete = MessageDigest.getInstance("SHA-1"); int numRead = 0; complete.update(s.getBytes()); return complete.digest(); } - public String convertToHexString(byte data[]) { // @3.由于MessageDigest对象的digest()方法返回的是字符数组,要得到十六进制的sha值还需要转为字符串 - //(tree的value包括了文件名(字符串)、子文件夹名(字符串)、子文件夹的treekey(字符串)、子文件的blobkey(字符串) - StringBuffer strBuffer = new StringBuffer(); // 用StringBuffer去建立可变字符串对象 + public String convertToHexString(byte data[]) { // @3.鐢变簬MessageDigest瀵硅薄鐨刣igest()鏂规硶杩斿洖鐨勬槸瀛楃鏁扮粍锛岃寰楀埌鍗佸叚杩涘埗鐨剆ha鍊艰繕闇瑕佽浆涓哄瓧绗︿覆 + //锛坱ree鐨剉alue鍖呮嫭浜嗘枃浠跺悕锛堝瓧绗︿覆锛夈佸瓙鏂囦欢澶瑰悕锛堝瓧绗︿覆锛夈佸瓙鏂囦欢澶圭殑treekey锛堝瓧绗︿覆锛夈佸瓙鏂囦欢鐨刡lobkey锛堝瓧绗︿覆锛 + StringBuffer strBuffer = new StringBuffer(); // 鐢⊿tringBuffer鍘诲缓绔嬪彲鍙樺瓧绗︿覆瀵硅薄 for (int i = 0; i < data.length; i++) { - strBuffer.append(Integer.toHexString(0xff & data[i])); // 用十六进制数oxff与某个字节值做按位与运算, - // 只保留了32位的最后8位,保证负数转换成十六进制不会出错 + strBuffer.append(Integer.toHexString(0xff & data[i])); // 鐢ㄥ崄鍏繘鍒舵暟oxff涓庢煇涓瓧鑺傚煎仛鎸変綅涓庤繍绠楋紝 + // 鍙繚鐣欎簡32浣嶇殑鏈鍚8浣嶏紝淇濊瘉璐熸暟杞崲鎴愬崄鍏繘鍒朵笉浼氬嚭閿 } return strBuffer.toString(); } public String getSha() { // return convertToHexString(sha1); } -} \ No newline at end of file +} diff --git a/gitcontroltool/Test.java b/gitcontroltool/Test.java index f156c62..ecb4ee5 100644 --- a/gitcontroltool/Test.java +++ b/gitcontroltool/Test.java @@ -1,12 +1,13 @@ package gitcontroltool; import java.io.*; -// 单元测试类测试最终效果 -// 即给定一个文件内容,向存储中添加对应的key-value;给定key,查找得到对应的value值 +// 鍗曞厓娴嬭瘯绫绘祴璇曟渶缁堟晥鏋 +// 鍗崇粰瀹氫竴涓枃浠跺唴瀹癸紝鍚戝瓨鍌ㄤ腑娣诲姞瀵瑰簲鐨刱ey-value锛涚粰瀹歬ey锛屾煡鎵惧緱鍒板搴旂殑value鍊 + public class Test { - public static void testValid(String filename){ // testvalid函数测试是否可以生成一个以hash(value)即key值为文件名的新文件 -// 传入一个具体的origin文件名称,生成一个hash(origin‘s value)做名字的新文件,文件内容同origin。 + public static void testValid(String filename){ // testvalid鍑芥暟娴嬭瘯鏄惁鍙互鐢熸垚涓涓互hash锛坴alue锛夊嵆key鍊间负鏂囦欢鍚嶇殑鏂版枃浠 +// 浼犲叆涓涓叿浣撶殑origin鏂囦欢鍚嶇О锛岀敓鎴愪竴涓猦ash锛坥rigin鈥榮 value锛夊仛鍚嶅瓧鐨勬柊鏂囦欢锛屾枃浠跺唴瀹瑰悓origin銆 File file = new File(filename); try{ Blob blob = new Blob(file.getAbsolutePath()); @@ -14,12 +15,12 @@ public static void testValid(String filename){ // testvalid System.out.println(blob); } catch (Exception ex){ - ex.printStackTrace(); // 在命令行打印异常信息在程序中出错的位置及原因 + ex.printStackTrace(); // 鍦ㄥ懡浠よ鎵撳嵃寮傚父淇℃伅鍦ㄧ▼搴忎腑鍑洪敊鐨勪綅缃強鍘熷洜 } } public static void getValue(String path, String encoding) throws IOException { - // 根据testValid()方法生成的key值为文件名的文件,现在用getValue方法去得到对应的value + // 鏍规嵁testValid()鏂规硶鐢熸垚鐨刱ey鍊间负鏂囦欢鍚嶇殑鏂囦欢锛岀幇鍦ㄧ敤getValue鏂规硶鍘诲緱鍒板搴旂殑value String content = ""; File file = new File(path); BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), encoding)); @@ -37,4 +38,4 @@ public static void main(String[] args) throws IOException { String testfile = "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed"; getValue(testfile,"utf-8"); } -} \ No newline at end of file +} diff --git "a/gitcontroltool/\344\273\273\345\212\241\344\270\200\350\257\246\347\273\206\346\226\207\346\241\243" "b/gitcontroltool/\344\273\273\345\212\241\344\270\200\350\257\246\347\273\206\346\226\207\346\241\243" new file mode 100644 index 0000000..8a66225 --- /dev/null +++ "b/gitcontroltool/\344\273\273\345\212\241\344\270\200\350\257\246\347\273\206\346\226\207\346\241\243" @@ -0,0 +1,49 @@ +璇剧▼椤圭洰锛 +鍙傝僩it瀹炵幇鍘熺悊锛屼娇鐢↗ava瀹炵幇blob銆乼ree銆乧ommit鏍稿績瀛樺偍缁撴瀯 +鍔熻兘锛 +1.Commit锛氭彁浜ommit锛屽彲浠ヤ娇鐢ㄢ漡it log鈥濇煡鐪媍ommit鍘嗗彶 +2.鍥炴粴 浣跨敤鈥漡it reset鈥 鍥炴粴鍒版寚瀹氬垎鏀 +3.鍒嗘敮 鍒涘缓鍒嗘敮銆佸疄鐜板垎鏀棿鍒囨崲 + +绗竴鍛ㄤ换鍔★細 +锛1锛夋枃浠剁殑key-value锛 +瀹炵幇key-value瀛樺偍锛堝皝瑁呬负class锛夛細 +Key锛氭枃浠跺悕 +Value锛氭枃浠朵腑鍐呭锛坘ey鏍规嵁value璁$畻寰楀嚭锛 +鍔熻兘锛 +1.缁欏畾value锛屽悜瀛樺偍涓坊鍔犲搴旂殑key-value +2.缁欏畾key锛屾煡鎵惧緱鍒板搴旂殑value + +锛2锛夋枃浠跺す鐨刱ey-value瀛樺偍锛 + 閬嶅巻鏂囦欢澶圭洰褰曪紝 濡傛灉閬囧埌瀛愭枃浠跺垯杞寲涓篵lob骞朵繚瀛 + 濡傛灉閬囧埌瀛愭枃浠跺す鍒欓掑綊璋冪敤鍐呴儴鐨勬枃浠跺す鎴栨枃浠讹紝杞寲涓篵lob涓巘ree +骞朵繚瀛 + +锛3锛夊崟鍏冩祴璇曪紙unittest锛 + 閫氳繃浠g爜鑷姩鍖栫殑妫娴媖ey-value瀛樺偍瀹炵幇鏄惁姝g‘锛岀‘淇濆ぇ閲忔枃浠惰繘琛屽瓨鍌ㄦ椂鐨勬晥鐜囦笌姝g‘鐜囥 + + +瀛樺偍鐩爣鍒嗘瀽锛 +锛1锛塨lob鏂囦欢鐨剉alue锛氭枃浠跺唴瀹 + Key锛歷alue鐨刪ash鍊 +锛2锛塼ree鏂囦欢澶圭殑value锛氬唴閮╞lob鏂囦欢鐨刱ey銆佹瘡涓瓙鏂囦欢澶箃ree鐨刱ey銆佸瓙鏂囦欢浠ュ強瀛 +鏂囦欢澶圭殑鍚嶇О + Key锛歵ree鏂囦欢澶箆alue鐨刪ash鍊 + +瀹炵幇璁捐锛 +锛1锛塰ash绫伙細璁$畻鏂囦欢blob銆佹枃浠跺すtree鐨刪ash鍊笺 +-璁$畻瀛楃涓诧紙string鍨嬶級鍙傛暟鐨刪ash鏂规硶 +-璁$畻file鐨刪ash鏂规硶 +-杩斿洖寰楀埌鐨刪ash鍊 +锛2锛<浼樺寲鍚>KeyValueObject: blob銆乼ree鐨勭埗绫伙紝瀛愮被blob涓巘ree缁ф壙鑷猳bject绫 + 璁$畻key鍊 + 鍒涘缓绫诲瀷涓篵lob绫诲瀷鐨勬枃浠 + 鍒涘缓绫诲瀷涓簍ree绫诲瀷鐨勬枃浠 + +锛3锛塨lob绫伙細 +璁$畻璇lob鏂囦欢鐨刱ey +鍒涘缓浠ey鍛藉悕鐨刡lob鏂囦欢 + +锛4锛塼ree绫伙細 +璁$畻璇ree鏂囦欢鐨刱ey鍊 +浠ey鍛藉悕鐨則ree鏂囦欢