Kotlin access file in project [duplicate] - android

I have a simple .txt file with just a couple lines in right now, each line has a word then a comma then another word, representing a very simplistic username , password bank. For some reason though I cant get the File to open to read from it.
Here is my code that I'm using....
try {
final String PATH = "src\\main\\assets\\passwords.txt";
Log.w("myApp", "passed");
List<String> user_password = FileUtils.readLines(new File(PATH));
Log.w("myApp", "passed2");
#SuppressWarnings("unchecked") List<Credentials> credentials = (List<Credentials>) CollectionUtils.collect(user_password, new Transformer() {
#Override
public Object transform(Object input) {
String cred = (String) input;
String parsed[] = cred.split(",");
Log.w("myApp", parsed[0]);
return new Credentials(parsed[0], parsed[1]);
//return credential;
}
});
user = (Credentials) CollectionUtils.find(credentials, new Predicate() {
#Override
public boolean evaluate(Object object) {
Credentials c = (Credentials) object;
return c.getUserName().equals(userName);
}
});
} catch (IOException e) {
System.out.print(e);
Log.w("MyApp", "failed");
}
I've tried putting the passwords.txt file in different places but that doesn't seem to work either.

You're referencing wrong to file in assets folder. It has to be smth like:
file:///android_asset/myfoldername/myfilename
in your particular case it's file:///android_asset/passwords.txt, though you have to keep in mind that it's always read only file

final String PATH = "src\\main\\assets\\passwords.txt";
That's not going to work. Android is not Windows, and an Android device is not your Windows development PC.
First, \ is the Windows path separator. On OS X, Linux, and Android, the path separator is /.
Second, src\main\assets\passwords.txt is a file in your project. It is not a file on the filesystem of the Android device.
To access assets, use AssetManager to open an InputStream(). You can get an AssetManager by calling getAssets() on any handy Context, such as your activity. Then, for your asset, call open("passwords.txt") on the AssetManager to get the InputStream, that you can then use to read in the data.

Thanks to #CommonsWare I was able to achieve what I was trying to do by using InputStream and then also IOUtils to read everything into the List.
try {
InputStream iS = this.getAssets().open("passwords.txt");
List<String> user_password = IOUtils.readLines(iS);
#SuppressWarnings("unchecked") List<Credentials> credentials = (List<Credentials>) CollectionUtils.collect(user_password, new Transformer() {
#Override
public Object transform(Object input) {
String cred = (String) input;
String parsed[] = cred.split(",");
return new Credentials(parsed[0], parsed[1]);
}
});
user = (Credentials) CollectionUtils.find(credentials, new Predicate() {
#Override
public boolean evaluate(Object object) {
Credentials c = (Credentials) object;
return c.getUserName().equals(userName);
}
});
}catch (IOException e){
System.out.print(e);
}

Related

Fail to locate text file

I am basically trying to read a long list of numbers(doubles)from a text file and save them into an array. I have these lines of code but it doesn't work when I load into my android smartphone. The readfile() does work completely when I use debug mode to check if my code reads the ExamScore, it does read and store the values as expected in my laptop. When it loads into smartphone, it just doesn't work. I save my ExamScore.txt in the root directory of android studio, for example, Users->AndroidStudioProjects->Project A. The main concern I have is that:
How do I know if this ExamScore.txt is saved into my smartphone as well when I build the app? Do I have to save the text file into my smartphone separately or something?The error I get is
java.io.FileNotFoundException: ExamScore.txt: open failed: ENOENT (No such file or directory)
static double[] readfile() throws FileNotFoundException{
Scanner scorefile = new Scanner(new File("ExamScore.txt"));
int count = -1;
double[] score = new double[8641];
while (scorefile.hasNext()) {
count = count + 1;
score[count] = Double.parseDouble(scorefile.nextLine());
}
scorefile.close();
return score;
}
In my main code,
double []score=readfile();
I save my ExamScore.txt in the root directory of android studio, for example, Users->AndroidStudioProjects->Project A... How do I know if this ExamScore.txt is saved into my smartphone as well when I build the app?
It isn't.
You need to create an assets folder.
Refer: Where do I place the 'assets' folder in Android Studio?
And you would use getAssets() to read from that folder.
public class MainActivity extends Activity {
private double[] readfile() throws FileNotFoundException{
InputStream fileStream = getAssets().open("ExamScore.txt");
// TODO: read an InputStream
}
}
Note: that is a read-only location of your app.
Or you can use the internal SD card.
How do I read the file content from the Internal storage - Android App
EDIT With refactored code in other answer
public static List<Double> readScore(Context context, String filename) {
List<Double> scores = new ArrayList<>();
AssetManager mgr = context.getAssets();
try (
BufferedReader reader = new BufferedReader(
new InputStreamReader(mgr.open(fileName)));
) {
String mLine;
while ((mLine = reader.readLine()) != null) {
scores.add(Double.parseDouble(mLine));
}
} catch (NumberFormatException e) {
Log.e("ERROR: readScore", e.getMessage());
}
return scores;
}
And then
List<Double> scores = readScore(MainActivity.this, "score.txt");
For those who are wondering, this is my solution! Thank you all for your help!!!! The issue I had was I didn't write it in the main activity but wrote the code in other java file. After writing this in the main activity file and putting my text file inside the assets folder. The issue is resolved :
public static LinkedList<Double> score=new LinkedList<Double>();
public void readScore() throws java.io.IOException {
BufferedReader reader = new BufferedReader(
new InputStreamReader(getAssets().open("score.txt")));
String mLine;
while ((mLine = reader.readLine()) != null) {
score.add(Double.parseDouble(mLine));
}
reader.close();
}

Failing to open file, am I linking it wrong? Or is Android Studio not seeing it for some reason?

I have a simple .txt file with just a couple lines in right now, each line has a word then a comma then another word, representing a very simplistic username , password bank. For some reason though I cant get the File to open to read from it.
Here is my code that I'm using....
try {
final String PATH = "src\\main\\assets\\passwords.txt";
Log.w("myApp", "passed");
List<String> user_password = FileUtils.readLines(new File(PATH));
Log.w("myApp", "passed2");
#SuppressWarnings("unchecked") List<Credentials> credentials = (List<Credentials>) CollectionUtils.collect(user_password, new Transformer() {
#Override
public Object transform(Object input) {
String cred = (String) input;
String parsed[] = cred.split(",");
Log.w("myApp", parsed[0]);
return new Credentials(parsed[0], parsed[1]);
//return credential;
}
});
user = (Credentials) CollectionUtils.find(credentials, new Predicate() {
#Override
public boolean evaluate(Object object) {
Credentials c = (Credentials) object;
return c.getUserName().equals(userName);
}
});
} catch (IOException e) {
System.out.print(e);
Log.w("MyApp", "failed");
}
I've tried putting the passwords.txt file in different places but that doesn't seem to work either.
You're referencing wrong to file in assets folder. It has to be smth like:
file:///android_asset/myfoldername/myfilename
in your particular case it's file:///android_asset/passwords.txt, though you have to keep in mind that it's always read only file
final String PATH = "src\\main\\assets\\passwords.txt";
That's not going to work. Android is not Windows, and an Android device is not your Windows development PC.
First, \ is the Windows path separator. On OS X, Linux, and Android, the path separator is /.
Second, src\main\assets\passwords.txt is a file in your project. It is not a file on the filesystem of the Android device.
To access assets, use AssetManager to open an InputStream(). You can get an AssetManager by calling getAssets() on any handy Context, such as your activity. Then, for your asset, call open("passwords.txt") on the AssetManager to get the InputStream, that you can then use to read in the data.
Thanks to #CommonsWare I was able to achieve what I was trying to do by using InputStream and then also IOUtils to read everything into the List.
try {
InputStream iS = this.getAssets().open("passwords.txt");
List<String> user_password = IOUtils.readLines(iS);
#SuppressWarnings("unchecked") List<Credentials> credentials = (List<Credentials>) CollectionUtils.collect(user_password, new Transformer() {
#Override
public Object transform(Object input) {
String cred = (String) input;
String parsed[] = cred.split(",");
return new Credentials(parsed[0], parsed[1]);
}
});
user = (Credentials) CollectionUtils.find(credentials, new Predicate() {
#Override
public boolean evaluate(Object object) {
Credentials c = (Credentials) object;
return c.getUserName().equals(userName);
}
});
}catch (IOException e){
System.out.print(e);
}

android file system persistance

Hi Iam having serious issues try to persist some serializable objects to a file on the local android file system. Iam getting a Bad file descriptor error and I think it is to do with my methods for creating the file. the file and checking if the file exists. i create a private file object in the class. Then, on write or read. I check file existance with the following code.
#Override
public boolean fileExists() {
File file = context.getFileStreamPath(filename);
return file.exists();
}
this doesnt instantiate my file object called "objectfile"!! but does check the "filename" exists.
to create the file I call this method if "filename" doesnt exist.
public void createFile()
{
objectfile = new File(context.getFilesDir(), filename);
objectfile.setReadable(true);
objectfile.setWritable(true);
}
Iam not sure if this will give me back my previously created file which would be ideally what I want to do. Is there a way i can just get the old file or create a new one and pass it to "objectfile" variable in the constructor??
Iam also wondering what the best way to do this is??
Or should i just use the mysqlite db? using object file persistance doesn't seem to be working out for me right now and iam working to a deadline. Also this method is mention in the gooogle docs so I thought it would be legit was to do it.
http://developer.android.com/training/basics/data-storage/files.html
here is my method for reading the serializable objects
public synchronized ArrayList<RoomItem> readObjects() {
final ArrayList<RoomItem> readlist = new ArrayList<>();
if(!fileExists())
return readlist;
if(objectfile == null)
createFile();
try {
finputstream = new FileInputStream(objectfile);
instream = new ObjectInputStream(finputstream);
readwritethread = new Thread(new Runnable() {
#Override
public void run() {
try {
final ArrayList<RoomItem> readitems = (ArrayList<RoomItem>) instream.readObject();
instream.close();
finputstream.close();
handler.post(new Runnable() {
#Override
public void run() {
listener.updateList(readitems);
}
});
} catch(IOException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
Log.d("read failed", "file read failed");
}
}
});
}
catch(Exception e)
{
e.printStackTrace();
}
timeOutReadWrite(readwritethread);
readwritethread.start();
try {
readwritethread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d("read from file", "file read");
return readlist;
if anyone could suggest any improvements id really appreciate it. I use a handler to pass back to my activity and implement a listener interface on my activity thats call the activity when all the obj are read. Thanks again!
1#: Yes, it will return the original file you created.
2#: Depends on the thing you want to store, seems File is more flex from description
hope helpful.
We have used
FileOutputStream fos = context.openFileOutput("file.ser", Context.MODE_PRIVATE);
to write our serialized files.This will carete files in /data/data/app.package.name/files/. In fact, this path is returned by getFilesDir().
And while deserializing, use
//make sure you pass the same file that was passed to openFileOutput()..
FileInputStream fis = context.openFileInput("file.ser");
Also, to avoid confusing between file names you can use name of class that is being serialized.
Ex:
public static <T> void serialize(final Context context, final T objectToSerialize) {
....
....
Strin fileName = objectToSerialize.getClass().getSimpleName();
...
}
Do this and keep the method in util so it can be used for any type of objects (T type) to serialize.

android testing accessing json file

I implemented a JSON interface for getting model data over http in one of my android projects.
this works so far and I would like to write some tests. I created a test project as suggested in the android documentation. for testing the JSON interface I need some test data which I would like to put in a file.
my research showed up that it's best to put these files in the assets folder of the android test project. to access files in the assets folder one should extend the test class by InstrumentationTestCase. then it should be possible to access the files by calling getAssets().open() on a resources object. so I came up with the following code:
public class ModelTest extends InstrumentationTestCase {
public void testModel() throws Exception {
String fileName = "models.json";
Resources res = getInstrumentation().getContext().getResources();
InputStream in = res.getAssets().open(fileName);
...
}
}
unfortunately I'm getting an "no such file or directory (2)" error when trying to access "models.json" file. (/assets/models.json)
when getting a list of the available files by
String[] list = res.getAssets().list("");
"models.json" is listed in there.
I'm running these tests on Android 4.2.2 api level 17.
public static String readFileFromAssets(String fileName, Context c) {
try {
InputStream is = c.getAssets().open(fileName);
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
String text = new String(buffer);
return text;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Then use the following code:
JSONObject json = new JSONObject(Util.readFileFromAssets("abc.txt", getApplicationContext()));
please use below code:
AssetManager assetManager = getResources().getAssets();
InputStream inputStream = null;
try {
inputStream = assetManager.open("foo.txt");
if ( inputStream != null)
Log.d(TAG, "It worked!");
} catch (IOException e) {
e.printStackTrace();
}

Bluetooth folder, different path on different phones

I found out that different versions of android puts the received bluetooth files in different folder. For instance, one of my test phones running android 2.2 saves the files to this path:
/mnt/sdcard/Downloads/Bluetooth
and my second test phone, running android 4.0 saves the files here
/mnt/sdcard/Bluetooth
Is this operating system "issue" or is it set from the manufacture of the phone?
If the first statement is the correct can I check which version of android running, and the point to the bluetooth folder? Or is there a much simpler way to do this?
Thanks!
After some hours I made two methods for doing this. You should put the methods in a AsyncTask or a Thread. So here is my two methods:
public List<File> folderSearchBT(File src, String folder)
throws FileNotFoundException {
List<File> result = new ArrayList<File>();
File[] filesAndDirs = src.listFiles();
List<File> filesDirs = Arrays.asList(filesAndDirs);
for (File file : filesDirs) {
result.add(file); // always add, even if directory
if (!file.isFile()) {
List<File> deeperList = folderSearchBT(file, folder);
result.addAll(deeperList);
}
}
return result;
}
This is a recursive method which will add all folders in the src parameter into a List.
I use this method in this method here:
public String searchForBluetoothFolder() {
String splitchar = "/";
File root = Environment.getExternalStorageDirectory();
List<File> btFolder = null;
String bt = "bluetooth";
try {
btFolder = folderSearchBT(root, bt);
} catch (FileNotFoundException e) {
Log.e("FILE: ", e.getMessage());
}
for (int i = 0; i < btFolder.size(); i++) {
String g = btFolder.get(i).toString();
String[] subf = g.split(splitchar);
String s = subf[subf.length - 1].toUpperCase();
boolean equals = s.equalsIgnoreCase(bt);
if (equals)
return g;
}
return null; // not found
}
Hope this helps, guys!

Categories

Resources