絮叨
本人学生,往前一年左右的时间用在了Java上
都说写博客、随笔是百利一害的事情-->一害是费时间
近期也是在此申请开通了博客
此篇也算是开博第一篇,所以絮叨一下
——————————————————————————————————————————————————————
问题发现与解决
今天在写Socket的文件传输
程序涉及到Socket、线程、文件操作、流等
目标是Client可以向Server提交文件名
然后Server进行响应-->文件存在则传输,不存在则回复文件不存在的消息
因为想要完成多次文件传输,所以把方法块放进了循环
于是希望所有打开的资源,像InputStream, OutputStream,这些可以再运行过程中一直打开, 直到程序结束才关闭
——————————————————————————————————————————————————————
文件传输用的是 DataInputStream 中的 read(byte[] b, int off, int len) 和 DataOutputStream 中的 write(byte[] b, int off, int len)
JavaDoc 地址:
简单描述
DataInputStream 和 DataOutputStream 是字节流 可以视为-->他们操作的对象是每字节的编码-->机器认识而我不认识的东西
相对应的Writer和Reader 是字符流 他们操作的是将字节编码转化为字符的我能看懂的东西
所以在传输文件的时候使用字节流是更为合适的选择
——————————————————————————————————————————————————————
网上有关文件传输的代码大多是这个样子
通过(FileInputStream) fileInput 从文件读取,并通过(DataOutputStream) out 发送:
1 while((length = fileInput.read(bytes)) != -1) {2 out.write(bytes, 0, length);3 out.flush();4 }
通过(DataInputStream) in 读取数据,并通过(FileOutputStream) fileOutput 写入文件
1 while((length = in.read(bytes, 0, bytes.length)) != -1) {2 fileOutput.write(bytes, 0, length);3 fileOutput.flush();4 }
这两段代码没有问题,都是可以运行的
我的问题出现在接收文件数据的时候,文件数据已经发送完毕,但是程序没有跳出循环
其症结是while()中的判断条件是要 length = -1 才会跳出循环
可以通过上方贴出来的JavaDoc的截图看到-1表示的读取到流的结尾
但是想要让它读取到流的结尾 是要发送方关闭流
在发送方发送完成后需要有类似这样一句 out.close()
执行out.close() 实际上它所包装的socket也随之关闭了
也就是说整条连接都断了 这不是我想要的
我想要的是发送完一个 程序还能够继续响应我从Client发送来的消息
于是需要引入新的判断条件 让接收方知道它想要的文件已经传输完毕
——————————————————————————————————————————————————————
我找到的一个简单的方法是 利用文件的length
传输文件之前,在Server检查文件名是否存在,向Client反馈的时候,将文件的length也发送过去
这样就可在接收文件的时候对本地文件的length和传输过来的length进行比较
从而判断文件传输是否完成
1 private static void getBytes(String fileName, long fileLength) throwsIOException {2 File file = newFile(fileName);3 FileOutputStream f = newFileOutputStream(file);4 byte[] bytes = new byte[1024];5 int length = 0;6 while(true) {7 length = in.read(bytes, 0, bytes.length);8 f.write(bytes, 0, length);9 f.flush