android 如何在不关闭OutputStream对象的情况下强制刷新它?

aiazj4mn  于 2023-05-15  发布在  Android
关注(0)|答案(7)|浏览(207)

我的问题在于以下假设,我希望这些假设是正确的,因为我相信这些假设,因为我在谷歌搜索我的问题时读到了它们:
1.关闭Socket的OutputStream也会关闭Socket

  1. OutputStream的flush()方法什么也不做
    因此,我基本上需要从我的OutputStream对象中清除数据,以便我的应用程序工作。
    如果您对详细信息感兴趣,请查看以下两个链接:
    . Weird behavior : sending image from Android phone to Java server (code working)
    已通过关闭OutputStream解决此问题。这样做会将所有数据刷新到套接字的另一端,并使我的应用程序进一步工作,但这个修复很快就引起了第2个问题-相应的套接字也会关闭:
    . SocketException - 'Socket is closed' even when isConnected() returns true
qgelzfjb

qgelzfjb1#

您可以调用OutputStream的flush方法而不是close。继承自OutputStream的具体类将重写flush(),以执行除不执行操作以外的操作(将数据写入文件或通过网络发送数据)。

ff29svar

ff29svar2#

OutputStream的flush()方法什么也不做。
这是不正确的。
确实,OutputStream类提供的flush()的基本实现什么也不做。但是,您的应用将调用由您正在使用的 actual stream类提供的该方法的版本。如果流类没有直接写语义,它将覆盖flush()来执行所需的操作。
简而言之,如果需要flush(并且它是Socket输出流所必需的),那么调用flush()将做正确的事情。(如果一些互联网资源告诉你,否则它要么是错误的,要么你误解了它。
仅供参考,基础OutputStreamflush()实现为no-op的原因是:

  • 一些输出流类在刷新时不需要做任何事情;例如ByteArrayOutputStream,以及
  • 对于flush()不是no-op的流类,没有办法在基类级别实现该操作。

他们可以(理论上)设计流API,使OutputStream成为一个抽象类(flush()成为一个抽象方法)或接口。然而,在Java 1.0之前,这个API实际上被冻结了,当时没有足够的实际Java编程经验来认识到API设计是次优的。

dkqlctbz

dkqlctbz3#

你真的需要冲水吗?我还遇到了一个问题,c#服务器上的侦听器无法接收从android发送的数据(我试图同步获取数据)。
我确信这是因为在Android端,下面的代码没有刷新。

OutputStream str = btSocket.getOutputStream();
str.write(data_byte);
// "This implementation does nothing"
str.flush();

事实证明,如果我在服务器的侦听器上使用异步数据检索-它会获取数据,并且不需要客户端的flush()!

8qgya5xd

8qgya5xd4#

关闭Socket的OutputStream也会关闭Socket
没错。
OutputStream的flush()方法什么也不做
假的。有覆盖。请参阅FilterOutputStream.flush()BufferedOutputStream.flush()ObjectOutputStream.flush()的Javadoc,仅举几例。所有可以在内部缓冲输出的流都有flush()方法。所有的溪流都没有,没有。具体地,从Socket.getOutputStream()产生的输出流不被缓冲,并且不覆盖flush()
所以你最初的问题是不存在的,所以你不需要导致问题#2的“解决方案”。

eit6fx6z

eit6fx6z5#

我试试看。我也有同样的问题。关闭outputstream是我可以“刷新”数据的唯一方法。但因为我仍然需要输出流,这不是一个选择。所以我首先发送字节数组长度out.writeInt,然后是数组本身。当所有字节都被读取时,ie buffer.length == in.readInt()i break loop

ByteArrayOutputStream dataBuffer = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    byte[] fileBytes;
    int n;
    int length;

    try
    {
        size = in.readInt();

        while((n = in.read(buffer)) != -1)
        {
            dataBuffer.write(buffer, 0, n);

            if(dataBuffer.toByteArray().length == length)
            {
                fileBytes = dataBuffer.toByteArray(); break;
            }
        }
    }
i2loujxw

i2loujxw6#

我也有同样的问题。在流的末尾添加“\n”。刷新工作,但目标不知道消息是否结束

b4wnujal

b4wnujal7#

YES在Android flush()上不做任何事情(基于API 23的示例)

public Socket() {
    this.impl = factory != null ? factory.createSocketImpl() : new PlainSocketImpl();
    this.proxy = null;
}

public class PlainSocketImpl extends SocketImpl {

    @Override protected synchronized OutputStream getOutputStream() throws IOException {
        checkNotClosed();
        return new PlainSocketOutputStream(this);
    }

}

private static class PlainSocketOutputStream extends OutputStream {
        // doesn't override base class flush();
}

要刷新输出流而不关闭套接字,您可以关闭输出:

protected void shutdownOutput() throws IOException

--这将关闭WRITE文件描述符。

不使用输出流,您可以直接写入文件描述符或通过使用OutputStream创建自己的Socket实现,它将覆盖flush方法(例如使用c中的Berkeley socket实现(通过本机调用))。

相关问题