I'm currently writing a LibGDX game and I need to open an XML file for a spritesheet. Unfortunately, when I try to open the file, I get an IOException
. The files exist in the right places, the project's cleaned and up to date, etc.
Here's the kicker: LibGDX will open and display image files in the same directory, and in fact will obtain the XML file in its own FileHandle
object (I've had it logcat the size and it matches up). Yet when I send the file off to a SAX parser, I get an exception leading me back to the file saying that it can't open it.
Here's the problem line of code inside the ClipSprite
class:
private void parseConfigFile(FileHandle file) throws ParserConfigurationException, SAXException
{
//Use a SAX parser to get the data out of the XML file.
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
XMLConfigHandler handler = new XMLConfigHandler();
//Parse through the document
try
{
parser.parse(file.path(),handler); //IOException here
}
And here is the code where I select the file in the game in the create
method in the main LibGDX class
//This loads a png file
texture = new Texture(Gdx.files.internal("data/graphics/CDE1/CDE1.png"));
texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
TextureRegion region = new TextureRegion(texture, 0, 0, 512, 275);
//Here I load the xml file and it tells me how many bytes it is
Gdx.app.error("File","xml bytes:"+Gdx.files.internal("data/graphics/CDE1/CDE1.xml").length());
//Here I load the same file and it crashes
//Note that it looks in the subdirectory and finds /CDE1.xml properly
animation = new ClipSprite("data/graphics/CDE1");
Error from logcat:
java.io.IOException: Couldn't open data/graphics/CDE1/CDE1.xml
Why can it identify the file, yet I still get IOExceptions about being unable to open it? Thanks for the help, and I'll provide any more information if necessary.
Just to coalesce all the comments above into a single answer in case someone else runs into this or something similar:
Try Gdx.files.local()
to load your file, instead of Gdx.files.internal()
, as the "internal" files are read out of the (compressed) APK and may not be "visible" like a normal file. (This depends a lot on what the code you're passing a pathname to wants to do with it.)
For a libGDX FileHandle file
object use file.file()
to pass a File handle, instead of file.path()
to pass a String that might get misinterpreted.
For a libGDX FileHandle file
use file.read()
to pass an InputStream
directly to the consumer (instead of passing a string or file handle and expecting them to open it).
A libGDX "internal" file maps to an Android AssetManager file, so they can be a bit wonky in some cases. Specifically, they may be compressed and stored within a .jar
or .apk
and not visible to traditional file reading functions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With