黑马程序员技术交流社区

标题: TCP上传图片问题 [打印本页]

作者: 菊花爆满山    时间: 2015-9-24 13:09
标题: TCP上传图片问题
  1. <blockquote>import java.net.*;
复制代码
一开始没有写BufferedOutputStream 是用的OutputStream没问题,后来我改成了BufferedOutputStream 发现出现了字符串角标越界异常,
我就想难道lenIn没有长度 于是打印一下lenIn=-1  于是我想难道数据没有从缓冲区到流中 于是刷了一下 解决了
但是我以前写BufferedOutputStream就没刷过 字节流不是不需要刷的吗
为什么上面没刷就可以写到输出流中?



作者: didixyy    时间: 2015-9-24 13:09
上面那个不需要单独写刷新时因为你在最后写了 s.shutdownOutput();关闭了流,关闭流都是可以自己刷新的,就像写了out.colse()
作者: 菊花爆满山    时间: 2015-9-24 13:10
  1. import java.net.*;
  2. import java.io.*;
  3. class PicClient
  4. {
  5.         public static void main(String[] args) throws Exception
  6.         {
  7.                 Socket s = new Socket("100.97.97.68",10008);
  8.                 FileInputStream fis = new FileInputStream("c:\\1.jpg");
  9.                 InputStream in = s.getInputStream();
  10.                 //OutputStream out =s.getOutputStream();
  11.                 BufferedOutputStream out = new BufferedOutputStream(s.getOutputStream());
  12.                 byte[] buf = new byte[1024];
  13.                 int len = 0;
  14.                 while((len=fis.read(buf))!=-1)
  15.                 {
  16.                         out.write(buf,0,len);
  17.                         //这里为什么不需要flush
  18.                 }
  19.                
  20.                 s.shutdownOutput();
  21.                
  22.                 byte[] bufIn = new byte[1024];
  23.                 int lenIn = in.read(bufIn);
  24.                 System.out.println(new String(bufIn,0,lenIn));
  25.                 fis.close();
  26.                 s.close();       
  27.         }
  28. }
  29. class PicServer
  30. {
  31.         public static void main(String[] args) throws Exception
  32.         {
  33.                 ServerSocket ss = new ServerSocket(10008);
  34.                 Socket s = ss.accept();
  35.                
  36.                 FileOutputStream fos = new FileOutputStream("Server.jpg");
  37.                
  38.                 InputStream in = s.getInputStream();
  39.         //        OutputStream out = s.getOutputStream();
  40.             BufferedOutputStream out = new BufferedOutputStream(s.getOutputStream());
  41.                
  42.                 byte[] buf = new byte[1024];
  43.                 int len = 0;
  44.                 while((len=in.read(buf))!=-1)
  45.                 {
  46.                         fos.write(buf,0,len);
  47.                 }
  48.                
  49.                 out.write("上传成功".getBytes());
  50.                 out.flush();//       ?这里为什么要刷一下
  51.                 fos.close();
  52.                 s.close();
  53.                 ss.close();
  54.         }
  55. }
复制代码

代码在这里
作者: boboyuwu    时间: 2015-9-25 16:57
BufferedOutputStream你没刷是因为你close()了缓冲区中close()关闭流的同时也会刷新缓冲区
作者: 菊花爆满山    时间: 2015-9-25 23:53
didixyy 发表于 2015-9-25 15:09
上面那个不需要单独写刷新时因为你在最后写了 s.shutdownOutput();关闭了流,关闭流都是可以自己刷新的,就 ...

服务端 最后的s.close不也是关闭了输出流了吗?
作者: 菊花爆满山    时间: 2015-9-25 23:54
boboyuwu 发表于 2015-9-25 16:57
BufferedOutputStream你没刷是因为你close()了缓冲区中close()关闭流的同时也会刷新缓冲区 ...

服务端最后的s.close()不也是关闭了输出流了吗?
作者: a8336675    时间: 2015-9-26 23:07
楼上说的都不对。
BufferedOutputStream缓冲输出流的默认缓冲区大小为8192,当你向这个缓冲区里面写满了8192个字节时,就会自动写入流中。
这就是缓冲流的机制,实际上就是在底层定义了一个数组,先写入数组中,等数组内容满了,就写入流中。以达到缓冲的效果。

一般图片的大小都会大于8192字节(8M),所以会自动flush()写入流中;
而下面的“上传成功”4个中文字最多占12个字节,并不能填满缓冲区,所以不会自动flush()。
作者: a8336675    时间: 2015-9-26 23:08
而且其实你PicServer里面最后这个out对象流没有关闭,如果你关闭了,其实也是可以不能flush的。

作者: 菊花爆满山    时间: 2015-9-28 13:10
a8336675 发表于 2015-9-26 23:08
而且其实你PicServer里面最后这个out对象流没有关闭,如果你关闭了,其实也是可以不能flush的。
...

看来是的 最后的close并没有关闭输出流。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2