传输文件后输入流未关闭,客户端while循环无法退出求助
解决输入流无法退出while循环的问题
兄弟,我懂你这种卡在while循环里的痛苦!之前我也碰到过类似的问题,就是因为输入流不知道什么时候该停,一直堵在那儿没法往下执行播放逻辑。给你几个实用的解决办法,你可以根据自己的场景选:
方法一:先传文件大小,按需读取字节
这是最稳妥的方案,让服务器先把音乐文件的总字节数发过来,客户端拿到这个数值后,就知道要读多少字节才够,读完直接退出循环。
调整后的客户端代码大概是这样:
@Override protected Void call() { try { // 假设你用的是Socket的输入流,包装成DataInputStream方便读取长整型 DataInputStream dis = new DataInputStream(socket.getInputStream()); // 第一步:读取服务器发来的文件总大小 long totalFileSize = dis.readLong(); byte[] buffer = new byte[1024]; // 缓冲区大小可以根据需求调整 long bytesReadSoFar = 0; // 准备写入本地文件 FileOutputStream fos = new FileOutputStream("saved_song.mp3"); // 只要还没读完指定的字节数,就继续读 while (bytesReadSoFar < totalFileSize) { int currentRead = dis.read(buffer); if (currentRead == -1) { // 意外断开连接,提前终止循环 break; } fos.write(buffer, 0, currentRead); bytesReadSoFar += currentRead; } // 关闭流资源 fos.close(); dis.close(); // 现在可以放心播放歌曲了! playSavedSong(); } catch (IOException e) { e.printStackTrace(); } return null; }
方法二:服务器传完就关输出流
如果你的场景是一次性传输文件(不是长连接),让服务器在发送完所有音乐字节后,主动调用outputStream.close(),这样客户端的read()方法会返回-1,循环自然就终止了。
客户端代码可以这么写:
@Override protected Void call() { try { InputStream is = socket.getInputStream(); byte[] buffer = new byte[1024]; int currentRead; FileOutputStream fos = new FileOutputStream("saved_song.mp3"); // 当服务器关闭输出流后,read()会返回-1,循环结束 while ((currentRead = is.read(buffer)) != -1) { fos.write(buffer, 0, currentRead); } // 关闭资源 fos.close(); is.close(); // 执行播放逻辑 playSavedSong(); } catch (IOException e) { e.printStackTrace(); } return null; }
小提醒:UI线程注意事项
因为你这是UI应用的任务,千万别在call()方法里直接操作UI或者播放音频!比如Android里要用到runOnUiThread,Swing里用SwingUtilities.invokeLater,把播放逻辑切换到UI线程执行,不然容易出线程安全问题哦。
内容的提问来源于stack exchange,提问作者Lucky38i




