FileWriter
创建一个FileWriter对象,该对象一被初始化就必须明确被操作的文件,而且该文件会被创建到指定的目录下。如果该目录下已有同名文件,将被覆盖。
下面的例子是将客户端的文件拷贝到服务器上:
客户端:
Socket s = new Socket("1.1.1.1",10000);//定义客户端的套接字
BufferedReaderbf = new BufferedReader(new FileReader("Client.txt"));//将要传的文件封装到bf中
PrintWriterout = newPrintWriter(s.getOutputStream(),true);//定义一个向服务端写文件的对象
Stringline = null;
while((line=bf.readLine())!=null){
out.println(line);
}
BufferedReaderbufin = new BufferedReader(new InputStreamReader(s.getInputStream()));
Stringstr = bufin.readLine();
System.out.println(str);
bf.close();
s.close();
服务器端:
ServerSocket ss = new ServerSocket(10000);
Sockets =ss.accept();
BufferedReaderbf = new BufferedReader(newInputStreamReader(s.getInputStream()));
PrintWriterout = new PrintWriter(new FileWriter("Server.txt"));
Stringline = null;
while((line=bf.readLine())!=null){
out.println(line);
}
PrintWriterpc = newPrintWriter(s.getOutputStream(),true);
pc.println("上传成功");
bf.close();
s.close();
ss.close();
但如果运行就会发现无论是客户端还是服务器端都不能结束,总会一直停留在那里。原因不难发现是因为服务器端循环处不知道客户端文件已经发送完毕,所以就会一直等着客户端发送,也同样不会给客户端发送“上传成功”,所以客户端也会停在那里等着服务器端发送上传成功的消息。
解决这个问题就是要让服务器端知道客户端循环已经结束。我们可以自定义结束标记,
客户端:
DataOutputStream dos = newDataOutputStream(s.getOutputStream());
long time = System.currentTimeMillis();
dos.writeLong(time);
String line = null;
while((line=bf.readLine())!=null){
out.println(line);
}
dos.writeLong(time);
告诉服务器端第一次收到的time是结束标记,下次收到该time时就是结束。服务器端我们做个判断:当第二次收到time时就结束循环。这样做虽然也可以结束但比较麻烦,要定义许多流。
方式二:API中也提供了另外一种结束标记,用s.shutdownOutput();关闭客户端输出流。相当于与给客户端价格结束标记-1。这样服务器端就不需要修改什么程序依然可以结束。