一个小小的总结

断断续续敲了一年的项目算是完工了,尽管重构了很多次,到现在来看仍是不忍直视,不过不能否认在这里面是学到了很多,现在简单记下笔记,算是正式结尾吧!

[这是一个使用多种加密方式的云盘系统,我负责写客户端和服务端后端非密码学部分]

项目管理

这个需要首先记,这个客户端和服务端有三次比较大的”重构”,其实就是因为自己各种失误把代码弄丢了,另外,我们一个团队协作但是代码同步都是使用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开发都是小心翼翼,保证每条代码的时间与空间效率,后来发现真的不用这么抠,资源,有的是呢!

规划

其实这是最重要的,这次开发最大的感受就是事先架构很重要,由于后端其他部分都是一个人写,真是随心所欲,没有大的规划代码就很乱,而且容易出现各种错误,逻辑很不清晰,以后的话自己应该会先花大量时间来规划类与方法吧。