来自内部存储器中文件的 InputStream 打开不完整(由于文件中的字符无效?)
InputStream from file in internal memory opens incomplete (due to invalid char in file?)
为什么当我解析 StringReader 而不是来自位于内部存储器中的文件的 InputStream 时,下面的代码有效,即使该文件具有与之前使用的 String 完全相同的数据(在代码中注释)?解析器在第二行之后立即到达 EOF。当我使用 String 时,它会一直走到最后。变量 linha 只是为了在调试期间查看正在解析的行以及当我使用 InputStream 方法时,解析器在文件的第 2 行到达 EOF。
public boolean read(){
boolean ret = false;
try{
InputStream is = mContext.openFileInput(fileName);
if(is!=null) {
XmlPullParserFactory xmlFactoryObject = XmlPullParserFactory.newInstance();
XmlPullParser myparser = xmlFactoryObject.newPullParser();
xmlFactoryObject.setNamespaceAware(true);
myparser.setInput(is,null); //or myparser.setInput(is,"utf-8");
int event;
String name = null;
boolean sai = false;
event=myparser.getEventType();
do{
linha = myparser.getLineNumber();
if ((event == XmlPullParser.START_TAG)
&&((name=myparser.getName()).equals("list-of-commands")))
sai = true;
else
event = myparser.next();
}while(!sai && event!= XmlPullParser.END_DOCUMENT);
if((name!=null) && myparser.getAttributeValue(null,"machine").equals(modelName)){
MachineCommand novoParam = null;
int itemCount = 0;
while (event != XmlPullParser.END_DOCUMENT) {
linha = myparser.getLineNumber();
name = myparser.getName();
switch (event) {
case XmlPullParser.START_TAG:
if (name.equals("param")) {
itemCount = 0;
int numComando =
Integer.parseInt(myparser.getAttributeValue(null,"num_command"));
int numParam =
Integer.parseInt(myparser.getAttributeValue(null,"num_param"));
novoParam =
((MachineCommand) progMenu.getExpandableListAdapter()
.getChild(numComando, numParam))
.deepClone(mContext);
novoParam.setNumCommand(numComando);
novoParam.setNumParam(numParam);
} else if (name.equals("spinner")) {
int selected =
Integer.parseInt(myparser.getAttributeValue(null,"selected_pos"));
Spinner sp = (Spinner)novoParam.getValueAt(itemCount++);
sp.setSelection(selected);
} else if (name.equals("EditTextNoKB")) {
String text = myparser.nextText();
EditTextNoKB et = (EditTextNoKB)novoParam.getValueAt(itemCount++);
et.setText(text);
}
break;
case XmlPullParser.END_TAG:
if (name.equals("param")) {
((ArrayAdapter<MachineCommand>)(dslvProgList.getAdapter())).add(novoParam);
}
}
event = myparser.next();
}
if(dslvProgList.getCount()>0) ret = true;
}
}
}catch(Exception e) {
e.printStackTrace();
ret = false;
}
return ret;
}
待解析的xml文件如下:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<list-of-commands machine="1005" version="1.0.0">
<param num_command="0" num_param="0">Velocidade<EditTextNoKB>6</EditTextNoKB></param>
<param num_command="0" num_param="2">Sentido<Spinner selected_pos="1">Anti-horário</Spinner></param>
<param num_command="0" num_param="5">Zerar Contador</param>
<param num_command="0" num_param="1">Desacelerar<EditTextNoKB>69</EditTextNoKB>voltas</param>
<param num_command="2" num_param="4">Aguardar Liberar</param>
</list-of-commands>
编辑:正如下面的评论所指出的,我可以说问题出在文件的写入过程中。也许一些无效的字符?
这是用于在内部存储器中创建文件的代码:
public boolean write(){
try {
FileOutputStream fos = mContext.openFileOutput(fileName, Context.MODE_PRIVATE);
XmlSerializer serializer = Xml.newSerializer();
serializer.setOutput(fos, "utf-8");
serializer.startDocument("utf-8", true);
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
serializer.startTag(null, "list-of-commands");
serializer.attribute(null, "machine", modelName); //TO DO: Estes dois atributos devem ser
serializer.attribute(null,"version","1.0.0"); //definidos em arquivo de configuração
for(int i=0; i<dslvProgList.getCount()-1; i++){
MachineCommand com = (MachineCommand)dslvProgList.getItemAtPosition(i);
serializer.startTag(null,"param");
serializer.attribute(null, "num_command", com.getStringNumCommand());
serializer.attribute(null,"num_param",com.getStringNumParam());
serializer.text(com.getName());
for (int j=0; j<com.getNumOfValues(); j++){
View v = com.getValueViewAt(j);
if(v instanceof EditTextNoKB){
serializer.startTag(null, "EditTextNoKB");
serializer.text(((EditTextNoKB)v).getText().toString());
serializer.endTag(null, "EditTextNoKB");
}
else if(v instanceof Spinner){
serializer.startTag(null, "Spinner");
int selectedPos = ((Spinner) v).getSelectedItemPosition();
serializer.attribute(null, "selected_pos", String.valueOf(selectedPos));
serializer.text(((Spinner) v).getItemAtPosition(selectedPos).toString());
serializer.endTag(null, "Spinner");
}
}
serializer.text(com.getUnity());
serializer.endTag(null, "param");
}
serializer.endTag(null, "list-of-commands");
serializer.endDocument();
serializer.flush();
fos.close();
}catch (Exception e){
return false;
}
return true;
}
事实证明这只是一些非常愚蠢的事情。整个问题是我的编码字符串:"UTF-8"。正确的是 "utf-8"(无大写字母)。写作和阅读都是错误的。我将编辑代码以反映正确的代码。
@OneWorld:谢谢你,你是对的,问题在于写作,然后反思阅读。你认为我应该删除这个问题,还是应该把它留在这里作为回答,以便其他人可以从中受益?由于这是一个愚蠢的错误,我不确定我是否应该保留它。
我是新来的,所以我想请教一下。
为什么当我解析 StringReader 而不是来自位于内部存储器中的文件的 InputStream 时,下面的代码有效,即使该文件具有与之前使用的 String 完全相同的数据(在代码中注释)?解析器在第二行之后立即到达 EOF。当我使用 String 时,它会一直走到最后。变量 linha 只是为了在调试期间查看正在解析的行以及当我使用 InputStream 方法时,解析器在文件的第 2 行到达 EOF。
public boolean read(){
boolean ret = false;
try{
InputStream is = mContext.openFileInput(fileName);
if(is!=null) {
XmlPullParserFactory xmlFactoryObject = XmlPullParserFactory.newInstance();
XmlPullParser myparser = xmlFactoryObject.newPullParser();
xmlFactoryObject.setNamespaceAware(true);
myparser.setInput(is,null); //or myparser.setInput(is,"utf-8");
int event;
String name = null;
boolean sai = false;
event=myparser.getEventType();
do{
linha = myparser.getLineNumber();
if ((event == XmlPullParser.START_TAG)
&&((name=myparser.getName()).equals("list-of-commands")))
sai = true;
else
event = myparser.next();
}while(!sai && event!= XmlPullParser.END_DOCUMENT);
if((name!=null) && myparser.getAttributeValue(null,"machine").equals(modelName)){
MachineCommand novoParam = null;
int itemCount = 0;
while (event != XmlPullParser.END_DOCUMENT) {
linha = myparser.getLineNumber();
name = myparser.getName();
switch (event) {
case XmlPullParser.START_TAG:
if (name.equals("param")) {
itemCount = 0;
int numComando =
Integer.parseInt(myparser.getAttributeValue(null,"num_command"));
int numParam =
Integer.parseInt(myparser.getAttributeValue(null,"num_param"));
novoParam =
((MachineCommand) progMenu.getExpandableListAdapter()
.getChild(numComando, numParam))
.deepClone(mContext);
novoParam.setNumCommand(numComando);
novoParam.setNumParam(numParam);
} else if (name.equals("spinner")) {
int selected =
Integer.parseInt(myparser.getAttributeValue(null,"selected_pos"));
Spinner sp = (Spinner)novoParam.getValueAt(itemCount++);
sp.setSelection(selected);
} else if (name.equals("EditTextNoKB")) {
String text = myparser.nextText();
EditTextNoKB et = (EditTextNoKB)novoParam.getValueAt(itemCount++);
et.setText(text);
}
break;
case XmlPullParser.END_TAG:
if (name.equals("param")) {
((ArrayAdapter<MachineCommand>)(dslvProgList.getAdapter())).add(novoParam);
}
}
event = myparser.next();
}
if(dslvProgList.getCount()>0) ret = true;
}
}
}catch(Exception e) {
e.printStackTrace();
ret = false;
}
return ret;
}
待解析的xml文件如下:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<list-of-commands machine="1005" version="1.0.0">
<param num_command="0" num_param="0">Velocidade<EditTextNoKB>6</EditTextNoKB></param>
<param num_command="0" num_param="2">Sentido<Spinner selected_pos="1">Anti-horário</Spinner></param>
<param num_command="0" num_param="5">Zerar Contador</param>
<param num_command="0" num_param="1">Desacelerar<EditTextNoKB>69</EditTextNoKB>voltas</param>
<param num_command="2" num_param="4">Aguardar Liberar</param>
</list-of-commands>
编辑:正如下面的评论所指出的,我可以说问题出在文件的写入过程中。也许一些无效的字符? 这是用于在内部存储器中创建文件的代码:
public boolean write(){
try {
FileOutputStream fos = mContext.openFileOutput(fileName, Context.MODE_PRIVATE);
XmlSerializer serializer = Xml.newSerializer();
serializer.setOutput(fos, "utf-8");
serializer.startDocument("utf-8", true);
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
serializer.startTag(null, "list-of-commands");
serializer.attribute(null, "machine", modelName); //TO DO: Estes dois atributos devem ser
serializer.attribute(null,"version","1.0.0"); //definidos em arquivo de configuração
for(int i=0; i<dslvProgList.getCount()-1; i++){
MachineCommand com = (MachineCommand)dslvProgList.getItemAtPosition(i);
serializer.startTag(null,"param");
serializer.attribute(null, "num_command", com.getStringNumCommand());
serializer.attribute(null,"num_param",com.getStringNumParam());
serializer.text(com.getName());
for (int j=0; j<com.getNumOfValues(); j++){
View v = com.getValueViewAt(j);
if(v instanceof EditTextNoKB){
serializer.startTag(null, "EditTextNoKB");
serializer.text(((EditTextNoKB)v).getText().toString());
serializer.endTag(null, "EditTextNoKB");
}
else if(v instanceof Spinner){
serializer.startTag(null, "Spinner");
int selectedPos = ((Spinner) v).getSelectedItemPosition();
serializer.attribute(null, "selected_pos", String.valueOf(selectedPos));
serializer.text(((Spinner) v).getItemAtPosition(selectedPos).toString());
serializer.endTag(null, "Spinner");
}
}
serializer.text(com.getUnity());
serializer.endTag(null, "param");
}
serializer.endTag(null, "list-of-commands");
serializer.endDocument();
serializer.flush();
fos.close();
}catch (Exception e){
return false;
}
return true;
}
事实证明这只是一些非常愚蠢的事情。整个问题是我的编码字符串:"UTF-8"。正确的是 "utf-8"(无大写字母)。写作和阅读都是错误的。我将编辑代码以反映正确的代码。 @OneWorld:谢谢你,你是对的,问题在于写作,然后反思阅读。你认为我应该删除这个问题,还是应该把它留在这里作为回答,以便其他人可以从中受益?由于这是一个愚蠢的错误,我不确定我是否应该保留它。 我是新来的,所以我想请教一下。