geniuses!
I'm practicing Java 8.
So if I do something like this:
Files.walk(Paths.get(corpusPathStr))
.filter(path -> path.toFile().isFile())
.forEach(path -> {
try {
Files.lines(path)
.forEach(...);
} catch (IOException e) {
e.printStackTrace();
}
});
I got FileSystemException error.
If I open a file under forEach, may too many files be opened?
Or are there other reasons causing FileSystemException (Too many open files)?
Thanks for your help in advance!
Use
try(Stream<Path> stream = Files.walk(Paths.get(corpusPathStr))) {
stream.filter(path -> Files.isRegularFile(path) && Files.isReadable(path))
.flatMap(path -> {
try { return Files.lines(path); }
catch (IOException e) { throw new UncheckedIOException(e); }
})
.forEach(...);
}
catch(UncheckedIOException ex) {
throw ex.getCause();
}
The streams returned by Files.walk and Files.lines must be properly closed to release the resources, which you do by either, a try(…) construct or returning them in the mapping function of a flatMap operation.
Don’t use nested forEachs.
The UncheckedIOException might not only be thrown by our mapping function, but also the stream implementations. Translating it back to an IOException allows to treat them all equally.
Files::line opens and reads the file in a lazy manner, i.e. Stream<String>. Since you're not closing any of your opened Streams you're getting such an error.
So when you're done reading a file you should close its handle. Since the returned Stream is AutoCloseable you can and should use a try-with-resource block.
try (Stream<Path> walk = Files.walk(Paths.get(""))) {
walk.filter(Files::isRegularFile).forEach(path -> {
try (Stream<String> lines = Files.lines(path)) {
lines.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
});
} catch (IOException e) {
e.printStackTrace();
}
Related
I am trying to understand exception handling in TPL Dataflow so I can effectively handle errors. In my comment numbered 1. below I am expecting to catch an AggregateException but everything just halts and doesn't recover. If I remove the throw (2.) then the ActionBlock continues to process but again, the AggregateException handler doesn't trigger.
Would anyone be able to help with an explanation to improve my intuition.
Would also welcome any documentation references on the topic.
async Task Main()
{
var ab = new System.Threading.Tasks.Dataflow.ActionBlock<int>(async a => {
try
{
await Task.Delay(100);
if (a == 7)
{
throw new Exception("Failed");
}
else
{
Console.WriteLine(a);
}
}
catch (Exception ie)
{
Console.WriteLine(ie.Message);
throw; //2. This causes the actionblock to halt, removing allows block to continue
}
});
for (int i = 0; i < 10; i++)
{
await ab.SendAsync(i);
}
ab.Complete();
try
{
await ab.Completion;
}
catch (AggregateException ae)
{
Console.WriteLine(ae.Flatten().Message);
// 1. Expecting to catch here.
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
What you're seeing is the await unwrapping your Aggregate Exception. When you await the completion task the exception is unwrapped and thrown to the general exception catch. But if you don't unwrap the exception then you'd see the exception caught as an aggregate exception like this:
try
{
ab.Completion.Wait();
}
catch (AggregateException ae)
{
Console.WriteLine("Aggregate Exception");
// 1. Expecting to catch here.
}
catch (Exception e)
{
Console.WriteLine("Exception Caught");
}
It's obviously better to properly await the completion but this samples shows you that indeed an AggregateExcpetion is caught when it's not unwrapped.
Exception handling provides the smooth flow of application but when we come to the technical part it's difficult to understand why we should use multiple catch blocks.When we can handle the exception by general parent exception using one catch block so why we need multiple catch
A multiple catch block is useful when you want to handle different exceptions in different ways.
try
{
int num1 = int.Parse(Console.ReadLine());
int num2 = int.Parse(Console.ReadLine());
int result = num1 / num2;
}
catch (DivideByZeroException ex)
{
Console.Write("Cannot divide by zero");
}
catch (InvalidOperationException ex)
{
Console.Write("Not a valid number");
}
catch (FormatException ex)
{
Console.Write("Not a valid number");
}
When use multiple catch blocks
To print message specific to an exception
To execute some logic specific to an exception
I’m trying to catch NoSuchElementException. This is my code:
public void checkActiveApps() {
try {
$(BUTTON).click();
} catch (org.openqa.selenium.NoSuchElementException e) {
System.out.println(e);
}
}
But the exception is still thrown. How to catch it?
This is the log:
Element not found {button[role='checkbox']}
Expected: visible
Screenshot: file:/Users/user/source/project/build/reports/tests/1537866631954.0.png
Page source: file:/Users/user/source/project/build/reports/tests/1537866631954.0.html
Timeout: 4 s.
Caused by: NoSuchElementException: Unable to locate element: button[role='checkbox']
at com.codeborne.selenide.impl.WebElementSource.createElementNotFoundError(WebElementSource.java:31)
at com.codeborne.selenide.impl.ElementFinder.createElementNotFoundError(ElementFinder.java:82)
at com.codeborne.selenide.impl.WebElementSource.checkCondition(WebElementSource.java:59)
at com.codeborne.selenide.impl.WebElementSource.findAndAssertElementIsVisible(WebElementSource.java:72)
at com.codeborne.selenide.commands.Click.execute(Click.java:16)
at com.codeborne.selenide.commands.Click.execute(Click.java:12)
at com.codeborne.selenide.commands.Commands.execute(Commands.java:144)
at com.codeborne.selenide.impl.SelenideElementProxy.dispatchAndRetry(SelenideElementProxy.java:90)
at com.codeborne.selenide.impl.SelenideElementProxy.invoke(SelenideElementProxy.java:65)
I use selenide version 4.12.3
Selenide does not throw Selenium exceptions as it uses it's own.
You can try using:
public void checkActiveApps() {
try {
$(BUTTON).click();
} catch (com.codeborne.selenide.ex.ElementNotFound e) {
System.out.println(e);
}
}
Why do you want to catch it anyway?
I want to create a method that can tell me if an exception is retry-able or not. Exceptions are from 3rd party library. So i have something like this :
bool isRetryable ( std::exception_ptr ex) {
try {
if(ex) {
std::rethrow_exception (ex);
}
return true;
} catch (const ExceptionA& ex) {
return true;
} catch (const ExceptionB& ex) {
return true;
} catch (const ExceptionC& ex) {
return true;
} catch (const ExceptionD& ex) {
return false;
} catch (const ExceptionE& ex) {
return false;
} catch (const ExceptionF& ex) {
return false;
}
}
The list of Exceptions can go as long as 100, So my question is - what is the impact of a long list of exception and is there any other way to accomplish the same goal ?
It depends on the C++ runtime library, but in general having a long list of catch blocks will result in O(n) performance as the implementation performs a linear scan, matching the thrown exception type against each of the types in the list of catch blocks in turn; this is e.g. how libstdc++ (the default C++ runtime on Linux) works.
I don't know whether any other runtime libraries optimize this, but I'd suspect they wouldn't, as a long list of exception blocks would usually be considered a "code smell" and also since the implementation is required to ensure that the first matching catch block receives the exception, which makes a linear scan the natural implementation.
However, if all your exceptions derive from a polymorphic base (e.g. std::exception) there is a much more elegant solution: you can take the typeid of the exception, construct a std::type_index and look it up in a container:
struct ExceptionA : std::exception {};
// etc.
static std::unordered_set<std::type_index> const retryables{
typeid(ExceptionA),
typeid(ExceptionB),
typeid(ExceptionC)
};
bool isRetryable ( std::exception_ptr ex) {
try {
if(ex) {
std::rethrow_exception (ex);
}
return true;
} catch (const std::exception& ex) {
return retryables.count(typeid(ex));
}
}
Example.
once again I need some help:
yesterday I asked this question that was about the way to use a large jpg image as a Bitmap (http://stackoverflow.com/questions/13511657/problems-with-big-drawable-jpg-image) and I resolved myself (Is my own response on that question) but whenever I resume my activity, as it uses that bitmap as the GLRenderer texture it crashes. I've tried many things, the last try was to make that bitmap static in order to keep it as a member variable into the activity but it crashes because, I supose, it looses it's mBuffer.
More details on the Activity code:
I declared it as SingletonInstance into the manifest:
android:launchMode="singleInstance"
in order to keep the tiles for the renderer.
and here some code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGLSurfaceView = new GLSurfaceView(this);
mGLSurfaceView.setEGLConfigChooser(true);
mSimpleRenderer = new GLRenderer(this);
getTextures();
if (!mIsTileMapInitialized){
tileMap = new LandSquareGrid(1, 1, mHeightmap, mLightmap, false, true, true, 128, true);
tileMap.setupSkybox(mSkyboxBitmap, true);
mIsTileMapInitialized = true;
}
initializeRenderer();
mGLSurfaceView.setRenderer(mSimpleRenderer);
setContentView( R.layout.game_layout );
setOnTouchListener();
initializeGestureDetector();
myCompassView = (MyCompassView)findViewById(R.id.mycompassview);
// Once set the content view we can set the TextViews:
coordinatesText = (TextView) findViewById(R.id.coordDynamicText);
altitudeText = (TextView) findViewById(R.id.altDynamicText);
directionText = (TextView) findViewById(R.id.dirDynamicText);
//if (!mIsGLInitialized){
mOpenGLLayout = (LinearLayout)findViewById(R.id.openGLLayout);
mOpenGLLayout.addView(mGLSurfaceView);
mVirtual3DMap = new Virtual3DMap(mSimpleRenderer, tileMap);
if (mGameThread == null){
mGameThread = new Thread(mVirtual3DMap);
mGameThread.start();
}
}
On getTextures method I get few small textures and the largest one as in my last question self response:
if (mTerrainBitmap==null){
InputStream is = getResources().openRawResource(R.drawable.terrain);
try {
// Set terrain bitmap options to 16-bit, 565 format.
terrainBitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap auxBitmap = BitmapFactory.decodeStream(is, null, terrainBitmapOptions);
mTerrainBitmap = Bitmap.createBitmap(auxBitmap);
}
catch (Exception e){
}
finally {
try {
is.close();
}
catch (IOException e) {
// Ignore.
}
}
}
So, again, first time it works great but when I go back I do:
protected void onPause() {
super.onPause();
mGLSurfaceView.onPause();
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
if (mVirtual3DMap != null) {
try {
mVirtual3DMap.cancel();
mGameThread=null;
mVirtual3DMap = null;
mGLSurfaceView.destroyDrawingCache();
mSimpleRenderer=null;
System.gc();
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
And whan I resume the activity:
#Override
protected void onResume() {
super.onResume();
mGLSurfaceView.onResume();
if (mVirtual3DMap != null) {
try {
mVirtual3DMap.resume();
} catch (Throwable e) {
e.printStackTrace();
}
}
}
And it crashes.
Why?? Ok, here is the exception cause on the GLThread:
java.lang.IllegalArgumentException: bitmap is recycled...
I tried this messy stuff because launching more than two times the original activity the application crashes bacuse of this or because of the amount of memory used and now I don't know if revert all these changes or what todo with this.
Is there a good way to keep in memory and usable, by this or another application activity, this bitmap?
Please, I need your advices.
Thanks in advance.
Do not handle resources manually or your app's surface will broke up. You can't handle your resources manually.
If you worry about reloading resources and you use API level 11+, you can use setPreserveEGLContextOnPause(). It will perserve your textures and FBOs.
If you can't use API 11+, you can port GLSurfaceView() to your app. You can check my own GLSurfaceView that is ported from ICS.
PS: Sorry about my poor english.
No. Let Android handle all the resources. You must handle the appropriate events and reload the bitmap when the activity is resumed. You cannot expect, that any OpenGL handles are still valid after the activity has been resumed.
Think of it as in the example of a laptop coming out from hibernation. Although all memory has been restored, you cannot expect that any open socket has still a real active connection going.
I am an Android noobie, so please correct me if I am wrong.