-
Notifications
You must be signed in to change notification settings - Fork 1
JAVA课程项目_简单版本控制工具项目_第一阶段任务 #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
bigbeats
wants to merge
4
commits into
main
Choose a base branch
from
dev1
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,53 +1,54 @@ | ||
| package gitcontroltool; | ||
| import java.io.*; | ||
| import java.security.MessageDigest; // ������ϢժҪ���ṩ��ϢժҪSHA1�㷨 | ||
| import java.security.MessageDigest; // 导入消息摘要,提供信息摘要SHA1算法 | ||
|
|
||
|
|
||
| public class Hash { | ||
| // ��shaֵ�ļ����װΪһ���࣬�������г�Ա����sha1����ʼshaֵ����outFile������תΪ16���Ƶ��ַ����� | ||
| // �ṩ�����ļ����ݣ�blob�����ļ������ַ��������tree����shaֵ����Ͷ�ȡ�������ṩ�ַ�����ת�ַ����ķ��� | ||
| // 将sha值的计算封装为一个类,该类中有成员属性sha1(初始sha值)和outFile(最终转为16进制的字符串) | ||
| // 提供基于文件内容(blob)和文件名或字符串(针对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对象的key值 | ||
| 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代表文件读取完毕。需要关闭输入流,并且返回消息摘要字节数组。 | ||
| 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对象的digest()方法返回的是字符数组,要得到十六进制的sha值还需要转为字符串 | ||
| //(tree的value包括了文件名(字符串)、子文件夹名(字符串)、子文件夹的treekey(字符串)、子文件的blobkey(字符串) | ||
| StringBuffer strBuffer = new StringBuffer(); // 用StringBuffer去建立可变字符串对象 | ||
| for (int i = 0; i < data.length; i++) { | ||
| strBuffer.append(Integer.toHexString(0xff & data[i])); // ��ʮ��������oxff��ij���ֽ�ֵ����λ�����㣬 | ||
| // ֻ������32λ�����8λ����֤����ת����ʮ�����Ʋ������ | ||
| strBuffer.append(Integer.toHexString(0xff & data[i])); // 用十六进制数oxff与某个字节值做按位与运算, | ||
| // 只保留了32位的最后8位,保证负数转换成十六进制不会出错 | ||
| } | ||
| return strBuffer.toString(); | ||
| } | ||
| public String getSha() { // | ||
| return convertToHexString(sha1); | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,25 +1,26 @@ | ||
| package gitcontroltool; | ||
| import java.io.*; | ||
| // ��Ԫ�������������Ч�� | ||
| // ������һ���ļ����ݣ���洢�����Ӷ�Ӧ��key-value������key�����ҵõ���Ӧ��valueֵ | ||
| // 单元测试类测试最终效果 | ||
| // 即给定一个文件内容,向存储中添加对应的key-value;给定key,查找得到对应的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(value)即key值为文件名的新文件 | ||
| // 传入一个具体的origin文件名称,生成一个hash(origin‘s value)做名字的新文件,文件内容同origin。 | ||
| File file = new File(filename); | ||
| try{ | ||
| Blob blob = new Blob(file.getAbsolutePath()); | ||
| blob.createBlob(); | ||
| System.out.println(blob); | ||
| } | ||
| catch (Exception ex){ | ||
| ex.printStackTrace(); // �������д�ӡ�쳣��Ϣ�ڳ����г�����λ�ü�ԭ�� | ||
| ex.printStackTrace(); // 在命令行打印异常信息在程序中出错的位置及原因 | ||
| } | ||
| } | ||
|
|
||
| public static void getValue(String path, String encoding) throws IOException { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. getValue方法是不是应该整合到功能代码里?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
明白学长的意思!今晚会再做修改。 |
||
| // ����testValid()�������ɵ�keyֵΪ�ļ������ļ���������getValue����ȥ�õ���Ӧ��value | ||
| // 根据testValid()方法生成的key值为文件名的文件,现在用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"); | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| 课程项目: | ||
| 参考git实现原理,使用Java实现blob、tree、commit核心存储结构 | ||
| 功能: | ||
| 1.Commit:提交commit,可以使用”git log”查看commit历史 | ||
| 2.回滚 使用”git reset” 回滚到指定分支 | ||
| 3.分支 创建分支、实现分支间切换 | ||
|
|
||
| 第一周任务: | ||
| (1)文件的key-value: | ||
| 实现key-value存储(封装为class): | ||
| Key:文件名 | ||
| Value:文件中内容(key根据value计算得出) | ||
| 功能: | ||
| 1.给定value,向存储中添加对应的key-value | ||
| 2.给定key,查找得到对应的value | ||
|
|
||
| (2)文件夹的key-value存储: | ||
| 遍历文件夹目录, 如果遇到子文件则转化为blob并保存 | ||
| 如果遇到子文件夹则递归调用内部的文件夹或文件,转化为blob与tree | ||
| 并保存 | ||
|
|
||
| (3)单元测试(unittest) | ||
| 通过代码自动化的检测key-value存储实现是否正确,确保大量文件进行存储时的效率与正确率。 | ||
|
|
||
|
|
||
| 存储目标分析: | ||
| (1)blob文件的value:文件内容 | ||
| Key:value的hash值 | ||
| (2)tree文件夹的value:内部blob文件的key、每个子文件夹tree的key、子文件以及子 | ||
| 文件夹的名称 | ||
| Key:tree文件夹value的hash值 | ||
|
|
||
| 实现设计: | ||
| (1)hash类:计算文件blob、文件夹tree的hash值。 | ||
| -计算字符串(string型)参数的hash方法 | ||
| -计算file的hash方法 | ||
| -返回得到的hash值 | ||
| (2)<优化后>KeyValueObject: blob、tree的父类,子类blob与tree继承自object类 | ||
| 计算key值 | ||
| 创建类型为blob类型的文件 | ||
| 创建类型为tree类型的文件 | ||
|
|
||
| (3)blob类: | ||
| 计算该blob文件的key | ||
| 创建以key命名的blob文件 | ||
|
|
||
| (4)tree类: | ||
| 计算该tree文件的key值 | ||
| 以key命名的tree文件 |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
其实Tree对象也是一样,也是通过key-value接口进行读写的,Tree和Blob本质上没什么不同,都是有自己的value值,然后value的哈希值作为key,只是Blob和Tree的value的具体含义不一样