断断续续敲了一年的项目算是完工了,尽管重构了很多次,到现在来看仍是不忍直视,不过不能否认在这里面是学到了很多,现在简单记下笔记,算是正式结尾吧!
[这是一个使用多种加密方式的云盘系统,我负责写客户端和服务端后端非密码学部分]
项目管理
这个需要首先记,这个客户端和服务端有三次比较大的”重构”,其实就是因为自己各种失误把代码弄丢了,另外,我们一个团队协作但是代码同步都是使用QQ打包传输的,很不方便,后来使用SVN版本管理工具后方便了很多
文件传输
这里遇到了很奇怪的问题,就是使用socket进行文件传输时,对于字节流,它不能准确判断文件传输结束,最佳的方法是使用socket.close()或者是socket.shutdownOutput()(自带的sslsocket不支持此方法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| public class Transfer {
private static int bufferSize = 1024*8;
public static void upload(Socket socket,String path) throws IOException {
try (DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(path)));) { byte[] buf = new byte[bufferSize];
int hasread = 0;
while ((hasread = dis.read(buf, 0, bufferSize)) != -1) {
dos.write(buf, 0, hasread);
}
}
}
public static void download(Socket socket,String path) throws IOException {
File file = new File(path);
try (DataInputStream dis = new DataInputStream(socket.getInputStream());
DataOutputStream fileOut = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream(file)));) {
byte[] buf = new byte[bufferSize];
int hasread = 0;
while ((hasread = dis.read(buf, 0, bufferSize)) != -1) {
fileOut.write(buf, 0, hasread);
}
} catch (Exception e) {
if (file.exists())
file.delete();
}
}
}
|
另外还有一个方面,socket传输文件,发送完成并不能保证对方何时才能下载完成,这里的异步可能导致一些奇怪的错误。
命令传输
命令传输才开始是客户端与服务端共用一个存储参数的对象,使用序列化传输,后来发现灵活性很差,于是采用了JSON进行命令传递,方便了很多
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| public static void main(String[] args) throws Exception {
JSONObject parameterc = new JSONObject();
parameterc.put("username", "BetaMao");
parameterc.put("password", "12345678");
Socket socket = Conn.sslConnToCloud();
sendPara(socket, parameterc);
}
public static boolean sendPara(Socket socket,JSONObject parameter){
try {
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF(parameter.toString());
dos.flush();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
|
另外,文件列表信息,之前是一个文件的属性使用”,”分隔,再使用StringTokenizer来提取,其实使用JSON会清晰很多。
数据库
数据库这里有几个坑点需要注意:
1:使用连接池,速度提升了很多,但是在写的时候配置的最大连接数比较少,并且在写SQL语句时写的很”纯粹”,例如显示该用户所有文件,数据库语句时返回一个结果集,又由于使用结果集时不能关闭数据库连接,但是关闭结果集却不关闭数据库连接,于是服务端遇到了一个莫名其妙的错误,就是运行久了会卡住,阻塞在获取连接处!
2:使用SQL查询时,条件是不区分大小写的:
可以使用binary关键字进行大小写敏感查询:
3:同样是大小写问题,MYSQL主键为varchar类型时,大小写不敏感,就是不能同时出现大小写不同的同样字符串,需要的话应将其设置为binvarchar
4:使用PreparedStatement可以有效的阻止SQLI:
配置文件
作为一个正常的软件,配置信息都不可能写到源代码里面,那样太作了,才开始想到的是使用XML,这样能满足需求,但是灵活性很差:
后来在接触DBCP时发现了Properties是个很好的方法:
资源
由C语言调教过来,做的题都是OJ上的题,于是初始使用java开发都是小心翼翼,保证每条代码的时间与空间效率,后来发现真的不用这么抠,资源,有的是呢!
规划
其实这是最重要的,这次开发最大的感受就是事先架构很重要,由于后端其他部分都是一个人写,真是随心所欲,没有大的规划代码就很乱,而且容易出现各种错误,逻辑很不清晰,以后的话自己应该会先花大量时间来规划类与方法吧。