2015-05-23 14 views
5

Ho un QuoteBank classe che ha bisogno di leggere in un file txt con scanner, ma mi sta dando un file non trovato eccezioneLa lettura da un file di testo in Android Studio Java

di file java è a app/src/main/java/nate.marxBros/QuoteBank.java

di file txt

è a app/src/main/attività/quotes.txt

il codice è

File file = new File("assets/QuotesMonkeyBusiness.txt"); 
    Scanner input = null; 
    try { 
     input = new Scanner(file); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } 

Non dovrebbe funzionare come qualsiasi altro programma java? ma dà file non trovato eccezione

Ho provato molte cose su questo sito come Android Studio Reading from Raw Resource Text File ma questo metodo non funziona, perché non so come passare in Context

grazie per qualsiasi aiuto

codice aggiornato

public class QuoteBank { 
private ArrayList<ArrayList<QuoteBank>> bank; 
private Context mContext; 
private ArrayList<QuoteQuestion> monkeyBuisness; 


public QuoteBank(Context context){ 
    mContext = context; 
    InputStream is = null; 
    try { 
     is = mContext.getAssets().open("QuotesMonkeyBusiness.txt"); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    ArrayList<QuoteQuestion> monkeyBuisness = parseFileToBank(is); 
} 

MainActivity

public class MainActivity extends ActionBarActivity { 
QuoteBank b = new QuoteBank(MainActivity.this); 

risposta

4

Si dovrebbe avere un MainActivity.java o un altro Activity che instanzia QuoteBank. Si vorrebbe il costruttore di prendere in un parametro di contesto:

Imposta una variabile privata in QuoteBank.java:

private Context mContext; 

Setup il costruttore:

public QuoteBank(Context context) { 
    this.mContext = context; 
} 

Poi un'istanza nella vostra attività,

QuoteBank quoteBank = new QuoteBank(context); 

La variabile di contesto può essere chiamata all'interno di un'attività tramite il comando this o Activity.this in cui si sostituisce "Attività" con il nome dell'attività. In alternativa, se ci si trova all'interno di un frammento, è possibile ottenere il contesto dall'oggetto View all'interno del metodo onCreateView(...). Di solito chiamando view.getContext().

Ora nel tuo metodo in cui si sta afferrando il patrimonio, è possibile utilizzare il contesto:

InputStream is = mContext.getAssets().open("QuotesMonkeyBusiness.txt") 

Dal momento che si sta utilizzando Android Studio è possibile creare un metodo main(String[] args) { ... } ed eseguirlo o semplicemente avviare l'emulatore e farlo usare Log.d(...) per mostrare l'output dal file.

In alternativa è possibile utilizzare il seguente metodo così:

AssetManager am = mContext.getAssets(); 
InputStream is = am.open("QuotesMonkeyBusiness.txt"); 

Potrebbe anche senso avere QuoteBank come istanza Singleton, che potrebbero aumentare l'efficienza, anche se tutto dipende dalle vostre esigenze, Forse qualcosa di simile:

List<String> allTextLines = QuoteBank.readFromFile(context, path_to_file); 

E poi nella classe QuoteBank.java si può avere un metodo in questo modo:

/** 
* Created by AndyRoid on 5/23/15. 
*/ 
public class QuoteBank { 

private Context mContext; 

public QuoteBank(Context context) { 
    this.mContext = context; 
} 

public List<String> readLine(String path) { 
    List<String> mLines = new ArrayList<>(); 

    AssetManager am = mContext.getAssets(); 

    try { 
     InputStream is = am.open(path); 
     BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 
     String line; 

     while ((line = reader.readLine()) != null) 
      mLines.add(line); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    return mLines; 
} 

}

e poi nella mia classe MainActivity.java Ho il seguente:

/** 
* Created by AndyRoid on 5/23/15. 
*/ 
public class MainActivity extends AppCompatActivity { 

public static final String TAG = MainActivity.class.getSimpleName(); 

public static final String mPath = "adventur.txt"; 
private QuoteBank mQuoteBank; 
private List<String> mLines; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    mQuoteBank = new QuoteBank(this); 
    mLines = mQuoteBank.readLine(mPath); 
    for (String string : mLines) 
     Log.d(TAG, string); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.menu_main, menu); 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    // Handle action bar item clicks here. The action bar will 
    // automatically handle clicks on the Home/Up button, so long 
    // as you specify a parent activity in AndroidManifest.xml. 
    int id = item.getItemId(); 

    //noinspection SimplifiableIfStatement 
    if (id == R.id.action_settings) { 
     return true; 
    } 

    return super.onOptionsItemSelected(item); 
} 
} 

Questa è la mia struttura di progetto:

enter image description here

Questo è il file adventur.txt ho scaricato da un database casuale:

file

Questa è la mia uscita di registro:

enter image description here


UPDATE: Perché non si dovrebbe usare uno scanner in Android

Dalla documentazione ufficiale:

http://developer.android.com/reference/java/util/Scanner.html

Questa classe non è così utile come potrebbe sembrare. È molto inefficiente per comunicare tra macchine; dovresti usare JSON, protobufs o anche XML per questo. Usi molto semplici potrebbero farla franca con split (String). Per l'input dagli umani, l'uso di espressioni regolari specifiche della locale lo rende non solo costoso ma anche un po 'imprevedibile. La classe Scanner non è thread-safe.


NOTA FINALE:

consiglio vivamente di leggere sulla documentazione di tutti gli oggetti usati qui in modo da poter comprendere il processo.

+0

Grazie per la collaborazione. Ricevo ancora un'eccezione di puntatore nullo in "AssetManager am = mContext.getAssets();" Ho un contesto dichiarato come "Activity context = new Activity();" nell'attività principale e subito prima di tale riga ho "this.mContext = context ; ' –

+0

e non c'è modo di farlo semplicemente inserendo un percorso di file relativo nella classe del file? mi sento come se fosse più facile? Non sono sicuro che inputStream funzioni con i metodi scanner .nextLine() –

+0

Invece di ** Contesto attività = nuova attività(); ** per acquisire il contesto, utilizzare il comando ** this ** o ** YOURACTIVITYNAME.questo ** . Quindi dovrebbe assomigliare a ** QuoteBank qb = new QuoteBank (this); ** o ** QuoteBank qb = new QuoteBank (YOURACTIVITYNAME.this); ** Supponendo che tu non abbia scelto la rotta Singleton. – AndyRoid

1

Context.getResources().getAssets().open("QuotesMonkeyBusiness.txt"); restituisce un InputStream il resto si può prendere da lì

Modifica

perché non so come passare in Context

Context è ovunque in realtà se si avere un View è possibile ottenere un Context, se si uno Activity è possibile ottenere Context quindi trovalo

Spero che sia utile

Problemi correlati