最近在做一个仓库管理系统,架构在svn之上。要求每一项操作要记录在log文件中,弄了很久起初感觉无法向库中的文本文件添加东西,就是修改库中的文本文件。于是采用了一个很笨的办法:    现将库中的log文件export下来到本地,修改完之后将库中的原来的log文件删除,然后上传(import)本地这个新的日志文件,然后删除掉本地的这个日志文件。

先看看代码:

package com.repositoryclient.svnoptions;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter; import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions;
import org.tmatesoft.svn.core.wc.ISVNOptions;
import org.tmatesoft.svn.core.wc.SVNClientManager;
import org.tmatesoft.svn.core.wc.SVNCommitClient;
import org.tmatesoft.svn.core.wc.SVNCopyClient;
import org.tmatesoft.svn.core.wc.SVNCopySource;
import org.tmatesoft.svn.core.wc.SVNMoveClient;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNUpdateClient;
import org.tmatesoft.svn.core.wc.SVNWCUtil; import com.repositoryclient.models.User;
import com.repositoryclient.treeview.FileNode; public class UserLogOption { public boolean doLog(String userName,String passwd,String LogMessage){
SVNClientManager ourClientManager;
SVNRepositoryFactoryImpl.setup();
SVNURL repositoryUrl = null;
String SVNServerUrl=User.getLogUrl();
File outFile=new File("./");
try {
repositoryUrl = SVNURL.parseURIEncoded(SVNServerUrl);
ISVNOptions options = SVNWCUtil.createDefaultOptions(true);
ourClientManager = SVNClientManager.newInstance(
(DefaultSVNOptions) options, userName, passwd);
//将log文件下载到本地
SVNUpdateClient updateClient=ourClientManager.getUpdateClient();
updateClient.doExport(repositoryUrl, outFile, SVNRevision.HEAD, SVNRevision.HEAD, LogMessage,false,true);
//添加此次操作的内容到log文件
try {
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("./Log.txt",true)));
bw.append("\r\n"+LogMessage);
bw.flush();
bw.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
//上传新的log文件,替换掉老的log文件
outFile=new File("./log.txt");
SVNURL repositoryTrgtUrl = SVNURL.parseURIEncoded(SVNServerUrl);
SVNCopySource[] copySources = new SVNCopySource[];
copySources[] = new SVNCopySource(null, null, outFile);
SVNCopyClient copyClient=ourClientManager.getCopyClient();
SVNMoveClient moveClient=ourClientManager.getMoveClient();
SVNCommitClient commitClient=ourClientManager.getCommitClient(); SVNURL[] svnurl = new SVNURL[];
svnurl[] = SVNURL.parseURIEncoded(SVNServerUrl);
commitClient.doDelete(svnurl, "delete log file."); commitClient.doImport(outFile, repositoryTrgtUrl, "dologlog", true); //updateClient.doSwitch(outFile,repositoryTrgtUrl,SVNRevision.HEAD , true);
//copyClient.doCopy(copySources, repositoryTrgtUrl, true, true, true, "move", null);
//SVNCommitClient commitClient=ourClientManager.getCommitClient();
//commitClient.doCommit(new File[]{outFile}, false, LogMessage, true, true);
//删除本地的log文件
outFile.delete(); return true;
} catch (SVNException e) {
// TODO: handle exception
e.printStackTrace();
return false;
}
} }

测试代码:

package com.repositoryclient.svnoptions;

import com.repositoryclient.models.User;

public class testlog {
public static void main(String args[]){
UserLogOption logOption=new UserLogOption();
logOption.doLog(User.getUserName(), User.getPasswd(), "do log is good.");
}
}

发现虽然是可行的,但是真的很不好。

于是给svnkit的作者写了封邮件问了问能否直接修改库中的文本文件,他们很快给我回了邮件

You need to commit a file modification. There is an example at http://wiki.svnkit.com/Committing_To_A_Repository

Alexander Kitaev,
TMate Software Support,
TMate Software,
http://subgit.com/ - Safe Svn To Git Migration!
http://svnkit.com/ - Java [Sub]Versioning Library!
http://hg4j.com/ - Java Mercurial Library!
http://sqljet.com/ - Java SQLite Library!

于是我就试了试svnkit的low api,结果成功了,但是有点问题:直接覆盖了log中的内容而不是添加到log中原内容的后边。这个之后再解决。

先看看代码:

public void logRepository(){
FSRepositoryFactory.setup();
try {
byte[] oldData={};
byte[] newData;
String logMessage="you are the god.";
newData=logMessage.getBytes();
SVNRepository repository=SVNRepositoryFactory.create(SVNURL.parseURIDecoded("http://10.13.30.22/svn/SVNRepository/Log/"));
ISVNAuthenticationManager authenticationManager = SVNWCUtil
.createDefaultAuthenticationManager(userName, passwd); repository.setAuthenticationManager(authenticationManager);
ISVNEditor editor=repository.getCommitEditor("logMessage", null,true,null);
editor.openRoot(-);
editor.openFile("log.txt", -);
editor.applyTextDelta("log.txt", null);
SVNDeltaGenerator deltaGenerator = new SVNDeltaGenerator( );
String checksum =deltaGenerator.sendDelta( "log.txt" ,new ByteArrayInputStream(newData),editor , true ); // String checksum = deltaGenerator.sendDelta( "log.txt" , new ByteArrayInputStream(oldData) , -1 , new ByteArrayInputStream(newData) , editor , true ); //Closes filePath.
editor.closeFile( "log.txt" , checksum ); //Closes the root directory.
editor.closeDir( );
editor.closeEdit();
} catch (SVNException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }

这个执行完之后,就将库中Log文件夹下的log.txt文件的内容修改为: you are the god.了。

注意这个很重要的类:SVNDeltaGenerator:http:

http://svnkit.com/kb/javadoc/org/tmatesoft/svn/core/io/diff/SVNDeltaGenerator.html#sendDelta(java.lang.String, java.io.InputStream, long, java.io.InputStream, org.tmatesoft.svn.core.io.ISVNDeltaConsumer, boolean)
public String sendDelta(String path,
InputStream target,
ISVNDeltaConsumer consumer,
boolean computeChecksum)
throws SVNException
Generates a series of diff windows of fixed size comparing target bytes (from target stream) against an empty file and sends produced windows to the provided consumer. consumer's textDeltaChunk() method is called to receive and process generated windows. Now new data comes within a window, so the output stream is either ignored (if it's null) or immediately closed (if it's not null).
If computeChecksum is true, the return value will be a strig containing a hex representation of the MD5 digest computed for the target contents. Parameters:
path - a file repository path
target - an input stream to read target bytes from
consumer - a diff windows consumer
computeChecksum - true to compute a checksum
Returns:
if computeChecksum is true, a string representing a hex form of the MD5 checksum computed for the target contents; otherwise null
Throws:
SVNException

---------------------------------------------------------------------------------------------------------------------------------------------------------------

刚才上面提到的问题有一个笨办法,就是获得log.txt的原内容,将新的log信息组织到原内容的后面,然后通过sendDelta就行了。

上代码:

public void logRepository(String logMessage){
FSRepositoryFactory.setup();
try {
String readmeContent=getFileInfo("http://10.13.30.22/svn/SVNRepository/Log/log.txt"); SVNRepository repository=SVNRepositoryFactory.create(SVNURL.parseURIDecoded("http://10.13.30.22/svn/SVNRepository/Log/"));
ISVNAuthenticationManager authenticationManager = SVNWCUtil
.createDefaultAuthenticationManager(userName, passwd); repository.setAuthenticationManager(authenticationManager);
ISVNEditor editor=repository.getCommitEditor("logMessage", null,true,null);
editor.openRoot(-);
editor.openFile("log.txt", -);
editor.applyTextDelta("log.txt", null);
SVNDeltaGenerator deltaGenerator = new SVNDeltaGenerator( );
String checksum =deltaGenerator.sendDelta( "log.txt" ,new StringBufferInputStream(readmeContent+"\r\n"+logMessage),editor , true ); // String checksum = deltaGenerator.sendDelta( "log.txt" , new ByteArrayInputStream(oldData) , -1 , new ByteArrayInputStream(newData) , editor , true ); //Closes filePath.
editor.closeFile( "log.txt" , checksum ); //Closes the root directory.
editor.closeDir( );
editor.closeEdit();
} catch (SVNException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
public String getFileInfo(String SVNServerUrl){

        SVNClientManager ourClientManager;
// 初始化支持svn://协议的库
SVNRepositoryFactoryImpl.setup();
// 相关变量赋值
SVNURL repositoryUrl = null;
try {
repositoryUrl = SVNURL.parseURIEncoded(SVNServerUrl);
ISVNOptions options = SVNWCUtil.createDefaultOptions(true);
// 实例化客户端管理类
ourClientManager = SVNClientManager.newInstance(
(DefaultSVNOptions) options, userName, passwd); OutputStream outputStream;
outputStream = new ByteArrayOutputStream();
SVNWCClient svnWCClient = ourClientManager.getWCClient();
svnWCClient.doGetFileContents(repositoryUrl, SVNRevision.HEAD, SVNRevision.HEAD, false, outputStream);
return outputStream.toString(); } catch (SVNException e) {
// TODO: handle exception
e.printStackTrace();
return null;
} }

测试代码:

package com.repositoryclient.svnoptions;

import com.repositoryclient.models.User;

public class testEditor {
public static void main(String args[]){
StoreManagerFileNodeOption fileNodeOption=new StoreManagerFileNodeOption(User.getUserName(), User.getPasswd());
fileNodeOption.logRepository("新的log信息");
}
}

SVNKIT的low api应用之修改库中文件内容(File modification)的更多相关文章

  1. 修改SVN中文件的可执行属性

    博文来自下面路径,转载请注明原出处: http://bigwhite.blogbus.com/logs/74568031.html 修改SVN中文件的可执行属性 - [开源世界] Tag:开源世界 S ...

  2. Java中如何修改Jar中的内容

    一.摘要 好长时间没写blog了,之前换了一家公司.表示工作更有战斗力了,可惜就是没时间写文章了.在这段时间其实是遇到很多问题的,只是都是记录下来,并没有花时间去研究解决.但是这周遇到这个问题没办法让 ...

  3. Java使用jxl修改现有Excel文件内容,并验证其是否对公式的结果产生影响

    jxl的maven坐标: <!-- https://mvnrepository.com/artifact/net.sourceforge.jexcelapi/jxl --> <dep ...

  4. Linux学习 - 修改、查询文件内容

    一.显示文件内容 cat  [-n]  [文件名] 正向显示 -n 显示行号 tac  [文件名] 反向显示 more  [文件名] 可实现分页显示 (空格)或(f) 翻页 (Enter) 换行 (q ...

  5. 怎么样修改PHPStorm中文件修改后标签和文件名的颜色与背景色

    自从最近在PHPstrom里引入Git,并且使用MONOKAI_SUBLIME主题之后 ,当文件在PHPstrom中进行编辑,文档内容变化时,左侧项目文件列表中的文件名颜色以及右侧编辑区域标签卡的文件 ...

  6. 怎样修改Response中的内容

    重写Stream public class CatchTextStream : Stream { private Stream output; public CatchTextStream(Strea ...

  7. JavaScript修改表中的内容

    例子: <?php ?> <html> <head> <meta http-equiv="Content-Type" content=&q ...

  8. 修改windows7中文件的权限

    1.修改ntkrnlpa.exe的权限 2.鼠标右键,选择"属性" 3.单击"安全"选项,选择"高级" 4.在高级安全设置中,选择" ...

  9. 修改String中的内容

    例子:有一个字符串"abcdef",现在想让字符串中的字符各自加1,求修改后的字符 String 在Java中是不可修改的. 方法1:将String 变为字符数组,通过修改字符数组 ...

随机推荐

  1. JavaScript 进阶(四)解密闭包closure

    闭包(closure)是什么东西 我面试前端基本都会问一个问题"请描述一下闭包".相当多的应聘者的反应都是断断续续的词,“子函数”“父函数”“变量”,支支吾吾的说不清楚.我提示说如 ...

  2. 解决android应用程序适用新老android系统版本方法

    老的android系统不能运行高版本系统的新方法,为了解决这个问题:  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { ...

  3. Entity - 使用EF框架进行增删改查 - 模型先行

    模型先行:先创建数据库实体模型,然后再进行数据库的增删改查. 基本步骤是不变的,可参照 <Entity - 使用EF框架进行增删改查 - 数据库先行> 其中的不同是,在创建数据库实体模型的 ...

  4. Lazy Math Instructor

      Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 3721   Accepted: 1290 Description A m ...

  5. 如何在一个jpg图片上面叠加文字

    1.将jpg转为bmp格式 2.在bmp文件上写上所需文字 3.将写入文字的bmp文件重新转为jpg格式 http://dev.csdn.net/develop/article/22/22948.sh ...

  6. 小米手机usb共享网络mac

    今天.我想去FQgoogle,mac在墙上,不便于使用.甚至只是用Android手机wifi,打开墙软件.然后usb分享到mac.然后mac互联网. 在谈到一些复杂.其实,关键一,小米手机usb共享, ...

  7. ASP.NET常被忽视的一些细节

    原文:ASP.NET常被忽视的一些细节 前段时间碰到一个问题:为什么在ASP.NET程序中定时器有时候会不工作? 这个问题看起来很奇怪,代码好像也没错,但就是结果与预期不一致. 其实这里是ASP.NE ...

  8. ThinkPhp学习10

    原文:ThinkPhp学习10 查询操作 Action模块 User下的search public function search(){ //判断username是否已经传入,且不为空 if(isse ...

  9. Linux程序设计学习笔记----多线程编程线程同步机制之相互排斥量(锁)与读写锁

    相互排斥锁通信机制 基本原理 相互排斥锁以排他方式防止共享数据被并发訪问,相互排斥锁是一个二元变量,状态为开(0)和关(1),将某个共享资源与某个相互排斥锁逻辑上绑定之后,对该资源的訪问操作例如以下: ...

  10. Win8下在Vmware11中安装使用苹果系统OS X 10.10

    原文:Win8下在Vmware11中安装使用苹果系统OS X 10.10   近来因为需要做 iOS 的项目,所以需要多花一些时间看看敲敲代码.因为自己手头上并没有 Mac(过年为了闲的时候能玩玩游戏 ...