我们有一个客户端服务器应用,1个服务器,大约10个客户端.它们使用自定义查询通过tcp套接字进行通信.
该系统运行平稳了好几个月,但在某些时候,在每日计划服务器FULL GC耗时约50秒后,我们发现客户端发送的查询与从服务器收到的响应之间的时间很长,> 10-20s.系统恢复3个小时后,一切都恢复正常.
在调查问题时,我们发现:
我们在服务器上进行了一次线程转储:
java.lang.Thread.State: RUNNABLE
at java.io.FilterInputStream.read(FilterInputStream.java:83)
at util.network.BytesBasedSocketConnection$ReadConnectionRunnable.run(BytesBasedSocketConnection.java:293)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Run Code Online (Sandbox Code Playgroud)
该FilterInputStream.read()如下:
public int read() throws IOException {
return in.read();
}
Run Code Online (Sandbox Code Playgroud)
在in我们的代码是一个BufferedInputStream.
问题是:为什么大多数连接在完全GC暂停后放慢了?为什么stacktrace结束FilterInputStream.read()?它不应该BufferedInputStream在套接字输入流中的某个地方结束吗?这读取会导致服务器上的高负载吗?
我们用于阅读的代码:
int constructLength = _socketDIS.readInt();
ByteArrayOutputStream constructBOAS = new ByteArrayOutputStream(constructLength);
for (int i = 0; i != constructLength; i++) …Run Code Online (Sandbox Code Playgroud) 我是Java的新手,也是学习Java ME开发的人.我陷入了这种转变.请帮我转换StringBuffer成InputStream.谢谢!
这可能是一个愚蠢的,但我想知道背景操作的差异.
InputStream is = new FileInputStream(filepath);FileInputStream is = new FileInputStream(filepath);上面两行代码之间的区别是什么,以及它们使用的场景.
不确定我应该怎么做.任何帮助,将不胜感激
有问题的文件不在我的控制之下.大多数字节序列都是有效的UTF-8,它不是ISO-8859-1(或其他编码).我想尽我所能提取尽可能多的信息.
该文件包含一些非法字节序列,应替换为替换字符.
这不是一件容易的事,它认为它需要一些关于UTF-8状态机的知识.
Oracle有一个包装器可以满足我的需求:
UTF8ValidationFilter javadoc
是否有类似的东西(商业或免费软件)?
谢谢 -
喜剧
解:
final BufferedInputStream in = new BufferedInputStream(istream);
final CharsetDecoder charsetDecoder = StandardCharsets.UTF_8.newDecoder();
charsetDecoder.onMalformedInput(CodingErrorAction.REPLACE);
charsetDecoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
final Reader inputReader = new InputStreamReader(in, charsetDecoder);
Run Code Online (Sandbox Code Playgroud) 我目前正在使用InpuStream从我的服务器获取JSON响应.
我需要做两件事:
在逐个使用这两种方法时,这完全没有问题.
使用GSON进行解析:
Gson gson = new Gson();
Reader reader = new InputStreamReader (myInputStream);
Result result = gson.FrmJson(reader, Result.class)
Run Code Online (Sandbox Code Playgroud)
并将复制到SDCard
FileOutputStream f (...) f.write (buffer)
Run Code Online (Sandbox Code Playgroud)
它们都经过了测试.
问题是一旦解析完成,我想写入SDCard并且它会中断.我知道我的InputStream已关闭,这就是问题所在.
这里有一些接近我的问题:如何缓存InputStream以供多次使用
有没有办法改进该解决方案并提供我们可以使用的东西?
HttpURLConnection.getInputStream()给出UnknownLengthHttpInputStream,由于此Document解析引发SAX解析器异常.
以下是代码
try{
URL url = new URL(uri);
HttpURLConnection connection =
(HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept", "application/xml");
InputStream xml = connection.getInputStream();
System.out.println(connection.getResponseCode());
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(connection.getInputStream());
doc.getDocumentElement().normalize();
}catch(Exception e){
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
任何人都知道UnknownLengthHttpInputStream的原因.我只在android中遇到此错误,此代码在Java Project中完美运行.
以下是LogCat的例外情况:
08-08 11:07:40.490: W/System.err(1493): org.xml.sax.SAXParseException: Unexpected end of document
08-08 11:07:40.504: W/System.err(1493): at org.apache.harmony.xml.parsers.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:129)
08-08 11:07:40.510: W/System.err(1493): at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:107)
08-08 11:07:40.510: W/System.err(1493): at com.example.testws.MainActivity.onCreate(MainActivity.java:59)
08-08 11:07:40.520: W/System.err(1493): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
08-08 11:07:40.520: W/System.err(1493): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
08-08 11:07:40.520: W/System.err(1493): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
08-08 …Run Code Online (Sandbox Code Playgroud) 我正在使用一个Android应用程序,它使用蓝牙连接在我的Android智能手机和非Android蓝牙模块之间传输数据,使用SPP配置文件.我使用Android Developer网站的蓝牙聊天示例作为参考.
我已经成功地将两个设备相互连接,并将简单的字符串从智能手机发送到蓝牙模块.但是我在读取从模块发回的数据时遇到了一些错误.我使用以下代码,与蓝牙聊天示例完全相同,从InputStream读取数据
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
String str = new String(buffer);
Log.i(TAG, "mmInStream - " + str);
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
break;
}
}
Run Code Online (Sandbox Code Playgroud)
当我的蓝牙模块向手机发送一个简单的字符串时,没有正确接收该字符串.它以随机的方式分成几个部分.例如,如果我将三次"1234567890abcdef1234567890abcdef0123456789"发送到手机,Eclipse上的Logcat将记录这些:
mmInstream - 12345678910abcdef????????(continuing null)
mmInstream - 1????????(continuing null)
mmInstream - 2345678910abcdef0123456789????????(continuing null)
Run Code Online (Sandbox Code Playgroud)
首次.在第二次和第三次传输数据时,它会收到差异:
mmInstream - 1234567891???????(continuing null)
mmInstream - 0abcdef012???????(continuing null)
mmInstream - 3456789?????????(continuing null)
mmInstream …Run Code Online (Sandbox Code Playgroud) 我使用下面的方法来写InputStream到File:
private void writeToFile(InputStream stream) throws IOException {
String filePath = "C:\\Test.jpg";
FileChannel outChannel = new FileOutputStream(filePath).getChannel();
ReadableByteChannel inChannel = Channels.newChannel(stream);
ByteBuffer buffer = ByteBuffer.allocate(1024);
while(true) {
if(inChannel.read(buffer) == -1) {
break;
}
buffer.flip();
outChannel.write(buffer);
buffer.clear();
}
inChannel.close();
outChannel.close();
}
Run Code Online (Sandbox Code Playgroud)
我想知道这是否是使用NIO的正确方法.我读过一个方法FileChannel.transferFrom,它有三个参数:
在我的情况下,我只有src,我没有position和count,有什么办法可以使用这种方法来创建文件?
另外对于Image有没有更好的方法来创建只有InputStreamNIO的图像?
任何信息对我都非常有用.这里有类似的问题,在SO中,但我找不到适合我的案例的特定解决方案.
我们希望让用户从任何应用中选择视频,然后将视频剪裁为最多5秒.
为了让Uri被选中,我们让它工作正常(这里有解决方案).
至于修剪本身,我们找不到任何具有许可许可的好图书馆,除了一个名为"k4l-video-trimmer"的图书馆.例如,库"FFmpeg"被认为是非许可,因为它使用GPLv3,这要求使用它的应用程序也是开源的.此外,正如我所读,它需要相当多(约9MB).
可悲的是,这个库(k4l-video-trimmer)很老了,多年没有更新了,所以我不得不把它(这里)分叉,以便很好地处理它.它使用一个名为"mp4parser"的开源库来进行修剪.
问题是,这个库似乎只能处理文件,而不是一个Uri或者InputStream,所以即使样本在选择像普通文件一样无法访问的项目时也会崩溃,甚至还有无法处理的路径.我知道在很多情况下可以获得文件的路径,但在许多其他情况下,它不是,我也知道可以只复制文件(这里),但这不是一个好的解决方案,因为文件可能很大并占用大量空间,即使它已经可以访问.
库有两个地方使用文件:
在"K4LVideoTrimmer"文件中,在"setVideoURI"函数中,它只是获取要显示的文件大小.根据Google的文档,这里的解决方案非常简单:
public void setVideoURI(final Uri videoURI) {
mSrc = videoURI;
if (mOriginSizeFile == 0) {
final Cursor cursor = getContext().getContentResolver().query(videoURI, null, null, null, null);
if (cursor != null) {
int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE);
cursor.moveToFirst();
mOriginSizeFile = cursor.getLong(sizeIndex);
cursor.close();
mTextSize.setText(Formatter.formatShortFileSize(getContext(), mOriginSizeFile));
}
}
...
Run Code Online (Sandbox Code Playgroud)在"TrimVideoUtils"文件中,在"startTrim"中调用"genVideoUsingMp4Parser"函数.在那里,它使用以下方法调用"mp4parser"库:
Movie movie = MovieCreator.build(new FileDataSourceViaHeapImpl(src.getAbsolutePath()));
Run Code Online (Sandbox Code Playgroud)
它说他们使用FileDataSourceViaHeapImpl(来自"mp4parser"库)来避免Android上的OOM,所以我决定继续使用它.
事实是,它有4个CTORS,都期望文件有一些变化:File,filePath,FileChannel,FileChannel + fileName. …
android filechannel inputstream android-contentresolver mp4parser
inputstream ×10
java ×8
android ×4
file ×2
image ×2
bluetooth ×1
encoding ×1
filechannel ×1
high-load ×1
java-io ×1
java-me ×1
midlet ×1
mp4parser ×1
networking ×1
nio ×1
saxparser ×1
sockets ×1
stringbuffer ×1
utf-8 ×1
web-services ×1