问题描述
|
我遇到了一个问题,在我的服务器中,发送了X个字节的文件后,我发送了一个字符串,表明该文件已结束,另一个文件即将来临,例如
FILE: a SIZE: Y\\r\\n
send Y bytes
FILE a FINISHED\\r\\n
FILE b SIZE: Z\\r\\n
send Z byes
FILE b FINISHED\\r\\n
FILES FINISHED\\r\\n
在我的客户中,它无法正常接收。
从套接字读取Y或Z字节后,我使用readline()获取命令行。
一个文件可以正常工作,而多个文件则很少工作(是的,我不知道它是一两次工作)
这是我用来传输二进制文件的一些代码
public static void readInputStreamToFile(InputStream is,FileOutputStream fout,long size,int bufferSize) throws Exception
{
byte[] buffer = new byte[bufferSize];
long curRead = 0;
long totalRead = 0;
long sizetoRead = size;
while(totalRead < sizetoRead)
{
if(totalRead + buffer.length <= sizetoRead)
{
curRead = is.read(buffer);
}
else
{
curRead = is.read(buffer,(int)(sizetoRead - totalRead));
}
totalRead = totalRead + curRead;
fout.write(buffer,(int) curRead);
}
}
public static void writeFileInputStreamToOutputStream(FileInputStream in,OutputStream out,int bufferSize) throws Exception
{
byte[] buffer = new byte[bufferSize];
int count = 0;
while((count = in.read(buffer)) != -1)
{
out.write(buffer,count);
}
}
仅作说明,我可以解决将readline替换为以下代码:
ByteArrayOutputStream ba = new ByteArrayOutputStream();
int ch;
while(true)
{
ch = is.read();
if(ch == -1)
throw new IOException(\"Conecção finalizada\");
if(ch == 13)
{
ch = is.read();
if(ch == 10)
return new String(ba.toByteArray(),\"ISO-8859-1\");
else
ba.write(13);
}
ba.write(ch);
}
PS:\“是\”是我从套接字的输入流:socket.getInputStream();
我仍然不知道它是否是最好的实现方式,即时通讯试图找出
解决方法
这里的代码中没有
readLine()
调用,但可以回答您的问题;是的,调用ѭ4可能会在内部缓冲区中留下很多东西。它正在缓冲输入。
如果您将ѭ5中的一个包裹在ѭ6中,那么从ѭ7中读取内容,然后再从ѭ8中读取内容,您将不会真正获得理智的举止。
您可以从InputStream
中读取字节,并通过寻找一对\\r\\n
字节来解析出文本行。当您得到的一行显示\“ FILE:a SIZE:Y \\ r \\ n \”时,您照常进行,除了用来解析行的缓冲区可能包含文件的前几个字节外,请写这些首先输出字节。
或者,您使用FTP的想法,使用一个TCP流进行命令,并使用一个TCP流进行实际传输,使用ѭ11from从命令流中读取数据,然后像使用InputStream.
一样读取数据。
, 是的,BufferedReader的重点是缓冲数据。它正在从其底层Reader读取较大的块中的输入,以避免进行多次较小的读取。
它具有readLine()
方法,这只是一个不错的奖励,可以通过缓冲轻松实现。
如果确实需要在同一连接上混合文本和二进制数据,则可能需要使用DataInputStream(在BufferedInputStream之上)及其“ 3”方法-从同一DataInputStream读取数据。 (但是请注意此处的编码。)
, 写入确定要发送的数据后,在OutputStream上调用ѭ15。因此,基本上每个文件的末尾都调用ѭ15。
, 我猜您必须刷新您的输出流,以确保任何缓冲的字节都正确地沿着该流发送。关闭流同样会运行此过程。
刷新的Javadocs说:
冲洗此输出流并强制
任何要缓冲的输出字节
写出来。总合同
同花顺是称它为
指示如果有字节
先前写入的已被缓冲
通过执行输出
流,此类字节应立即
被写成他们的意图
目的地。