上传文本文件
需求:读取一个本地文本文件,将数据发送到服务端,服务器端对数据进行存储。 存储完毕后,给客户端一个提示。
代码:
客户端:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
/**
* 2018年5月10日 上午10:52:53
* @author <a href="mailto:447441478@qq.com">宋进宇</a>
* 客户端上传 “文本文件”
*/
public class Client {
//这里为了代码 简洁 直接抛异常
public static void main(String[] args) throws IOException {
//尝试与服务器 “握手”--建立连接
Socket s = new Socket( InetAddress.getByName( "127.0.0.1" ), 8888);
//能到这里说明握手成功,进行文本文件上传
//文件源:本地磁盘
//目的:服务器
//存文本,加缓存
BufferedReader br = new BufferedReader(
new FileReader( "a.txt" ) );
//在网络传输中最好采用 PrintWriter 进行 输出,并且可以设置自动刷缓存,
//注意自动刷缓存只对 println、printf或format 三个方法有用
PrintWriter pw = new PrintWriter( s.getOutputStream(),true);
//进行数据对拷
String str = br.readLine();
while ( str != null ) {
pw.println( str );
//如果没有设置 自动刷缓存 需要 pw.flush();
str = br.readLine();
}
s.shutdownOutput();
br.close();//不是 Socket 中的输入或输出流可以关
//pw.close();只要还有传输数据就不能 关掉 Socket中的 输入流或输出流
//接收 服务器 的提示:是否上传成功
InputStream in = s.getInputStream();
BufferedReader br2 = new BufferedReader(
new InputStreamReader( in, "UTF-8" ) );
String mes = br2.readLine();
while ( mes != null ) {
System.out.println( mes );
mes = br2.readLine();
}
in.close();
br2.close();
s.close();
}
}
服务器端:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 2018年5月10日 上午11:10:21
* @author <a href="mailto:447441478@qq.com">宋进宇</a>
* 接收客户端上传的 “文本文件”
*/
public class Server {
//这里为了代码 简洁 直接抛异常
public static void main(String[] args) throws IOException {
//打开服务器
ServerSocket server = new ServerSocket( 8888 );
//等待 客户端来 “握手” --建立连接
Socket s = server.accept();
//能到这里说明 客户端与服务器 建立了连接
//进行接收上传的文件
//源:客户端
//类型:纯文本文件
//目的:本地磁盘
InputStream in = s.getInputStream();
BufferedReader br = new BufferedReader(
new InputStreamReader( in, "UTF-8" ) );
PrintWriter pw = new PrintWriter( "server.txt" );
//进行数据对拷
String str = br.readLine();
while ( str != null ) {
pw.println( str );
pw.flush();//这里就演示没有 设置自动刷缓存 ,需手动刷缓存
str = br.readLine();
}
//br.close(); 不能关!!!
pw.close(); //不是 Socket 中的输入或输出流可以关
//能到这里说明 文件上传 成功 给用户发送提示
PrintWriter pw2 = new PrintWriter( s.getOutputStream(), true );
pw2.println( "文件上传 成功!!" );
s.shutdownOutput();
s.close();
server.close();
}
}
上传图片文件
客户端需求:
把一个图片文件发送到服务端并读取回馈信息。要求判断文件是否存在及
格式是否为jpg或gif并要求文件小于2M。
服务端需求:
接收客户端发送过来的图片数据。进行存储后,回馈一个 上传成功字样。
支持多用户的并发访问。
代码:
客户端:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
/**
* 2018年5月10日 下午3:03:07
* @author <a href="mailto:447441478@qq.com">宋进宇</a>
* 把一个图片文件发送到服务端并读取回馈信息。
* 要求判断文件是否存在及格式是否为jpg或gif并要求文件小于2M
*/
public class Client {
//为了 代码简洁 直接抛异常
public static void main(String[] args) throws IOException {
//先判断是否符合上传的要求
//要求1:文件是否存在
//要求2:格式是否为jpg或gif
//要求3:文件小于2M
JFileChooser jfc = new JFileChooser();
int sel = jfc.showOpenDialog( null );
File imagFile = null;
if ( sel == JFileChooser.APPROVE_OPTION ) {
imagFile = jfc.getSelectedFile();
}
if ( imagFile == null ) {
return ;
}
//如果文件不存在,就结束
if ( !imagFile.exists() || imagFile.isDirectory() ) {
JOptionPane.showMessageDialog(null, "文件不存在" );
return;
}
//能到这里说明文件存在,接下来进行格式校验
//如果不是 jpg或gif 就结束
if ( !( imagFile.getName().endsWith( ".jpg" ) || imagFile.getName().endsWith( ".gif" ) ) ) {
JOptionPane.showMessageDialog(null, "文件格式不符合,只能是jpg或者gif格式" );
return;
}
//能到这里说明上面的要求符合,进行最后的校验
if ( imagFile.length() >= 2*1024*1024 ) {
JOptionPane.showMessageDialog(null, "文件太大" );
return;
}
//与服务器 建立连接
Socket s = new Socket( "113.242.149.32", 8888 );
//能到这里 说明 已经建立连接
//程序能到这里说明可以进行上传了
//因为文件是 图片 类型 为了不失真 采用字节流
//考虑到速度问题 可以加个缓存
BufferedOutputStream bos = new BufferedOutputStream( s.getOutputStream() );
//先发送文件名
//这里需要定义一个协议--文件名协议 ,就是 文件名长度不能超过 1024-1 个字节
byte[] fileName = new byte[1024];
//采用 UTF-8 码表进行编码
byte[] bytes = ( imagFile.getName() + "\n" ).getBytes( "UTF-8" );
if ( bytes.length > 1024 ) {
JOptionPane.showMessageDialog(null, "文件名长度太长!必须小于1023个字节");
}
//采用系统的数组拷贝函数
System.arraycopy( bytes, 0, fileName, 0, bytes.length );
bos.write( fileName, 0, 1024 );
bos.flush();//采用缓存流需要刷缓存,不然有BUG
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream( imagFile ) );
//再数据对拷
byte[] buf = new byte[1024]; //一次读1KB
int len = bis.read( buf );
while ( len != -1) {
bos.write( buf, 0, len );
bos.flush(); //采用缓存流需要刷缓存,不然有BUG
len = bis.read( buf );
}
//关闭 输入流
bis.close();
//并且做一个标识--文件接收标识
s.shutdownOutput();
//接收 服务器端 反馈
BufferedReader br = new BufferedReader(
new InputStreamReader( s.getInputStream(), "UTF-8" ) );
//读取 服务器反馈的内容
String mes = br.readLine();
JOptionPane.showMessageDialog( null, mes );
s.close();
}
}
服务器端:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 2018年5月10日 下午3:27:09
*
* @author <a href="mailto:447441478@qq.com">宋进宇</a> 接收客户端发送过来的图片数据。 进行存储后,回馈一个
* 上传成功字样。 支持多用户的并发访问。
*/
public class Server {
public static void main(String[] args) {
ServerSocket server = null;
try {
// 服务器对外提供 一个 进行连接的端口
server = new ServerSocket( 8888 );
// 等待客户端 进行建立连接
while (true) {
Socket s = server.accept();
// 能到这里说明用户连接成功
// 为了支持多用户的并发访问,采用多线程进行处理
new Thread(new Upload(s)).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Upload implements Runnable {
private Socket s = null;
public Upload(Socket s) {
this.s = s;
}
@Override
public void run() {
// 如果s为空直接结束
if (s == null) {
return;
}
// 先获取地址
InetAddress clientIp = s.getInetAddress();
PrintStream ps = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
// 再获取文件名称
try {
ps = new PrintStream( s.getOutputStream(), true );
///注意///
//这里需要注意这里读取内容的大小 要与上传时定义的文件头大小一样 1024B
bis = new BufferedInputStream( s.getInputStream() );
byte[] b = new byte[1024];
bis.read( b );
int i = 0;
for ( ; i < b.length; i++ ) {
if ( b[i] == 10 ) {
break;
}
}
//获取文件名(采用 UTF-8 码表进行解码)
String imagFilename = new String( b, 0, i, "UTF-8" );
//System.out.println( imagFilename );
///
//每个ip都对应一个文件夹
File imagDir = new File( "netFiles\\imag\\" + clientIp.getHostAddress() );
if ( !imagDir.exists() ) {
imagDir.mkdirs();
}
//给文件名加个前缀
int count = 1;
File imagFile = new File( imagDir, (count++) +"_"+ imagFilename );
//进行文件重名处理
while (imagFile.exists()) {
imagFile = new File( imagDir, (count++) +"_"+ imagFilename );
}
imagFile.createNewFile();
// 进行数据对拷
bos = new BufferedOutputStream(
new FileOutputStream( imagFile ) );
byte[] buf = new byte[1024];// 一次拷1KB
int len = bis.read( buf );
while (len != -1) {
bos.write( buf, 0, len );
bos.flush();
len = bis.read( buf );
}
bos.close();
// 能到这里说明文件上传成功,给客户端 反馈
ps.println("文件上传成功!");
} catch (IOException e) {
System.out.println(e.getMessage());
if (ps != null) {
ps.println("文件上传失败!!!");
try {
s.shutdownOutput();
} catch (IOException e1) {
}
}
} finally {
try {
if (s != null) {
s.close();
}
} catch (IOException e) {
}
}
}
}