Where is my .txt file stored ?

瀏覽次數:116 次
跳到第一則未讀訊息

Harry Mangurian

未讀,
2017年2月25日 晚上9:27:352017/2/25
收件者:MIT App Inventor Forum
I stored a text file using the blocks shown below.
Later in my app I read the file using (again) just the file name.
I put the file contents into a textbox and the text is correct, so everything works.

  1. Just so I can learn, where on my phone or emulator is the file stored. I searched for it by file name and could not locate it.
  2. Where would it be stored if I had used "/testtextfile.txt" instead ?
  3. Is there a tutorial or lesson where I can read up on file addresses in general when using AI2 ?
Thanks,



Taifun

未讀,
2017年2月26日 上午10:40:162017/2/26
收件者:MIT App Inventor Forum
see the documentation http://ai2.appinventor.mit.edu/reference/components/storage.html#File

SaveFile(text text, text fileName)
Saves text to a file. If the filename begins with a slash (/) the file is written to the sdcard (for example, writing to /myFile.txt will write the file to /sdcard/myFile.txt). If the filename does not start with a slash, it will be written in the program's private data directory where it will not be accessible to other programs on the phone. There is a special exception for the AI Companion where these files are written to /sdcard/AppInventor/data to facilitate debugging. Note that this block will overwrite a file if it already exists. If you want to add content to a file use the append block.

Taifun

Trying to push the limits of App Inventor! Snippets, Tutorials and Extensions from Pura Vida Apps by Taifun. 

Harry Mangurian

未讀,
2017年2月26日 上午11:14:192017/2/26
收件者:MIT App Inventor Forum
excellent.   Thanks

Min Sullivan

未讀,
2017年3月1日 下午3:08:442017/3/1
收件者:MIT App Inventor Forum
Hello again!

Your response is very helpful for me, too.  I have some questions about files, please:
  1. The app I am working on makes lists out of the text in the file.  Should I convert to and from csv format when writing to and reading from the file?
  2. Is there a limit to the amount of text data that can be stored in a file?
  3. The app I am working on uses a file it creates on the device it's being used on.  I want the user of the app to be able to get that file and send (email, etc.) it to another device.  In that device, I want the user to be able to tell the [same] app on that device to replace the text in the file it created and uses with the text in the file that was sent from the other device.  Is there a file picker that the user could use to give the app the filepath to the file sent from the other device?

Abraham Getzler

未讀,
2017年3月1日 下午3:31:332017/3/1
收件者:MIT App Inventor Forum
  1. The app I am working on makes lists out of the text in the file.  Should I convert to and from csv format when writing to and reading from the file?

You definitely need a text representation of your list(s).
CSV format is good for simple lists and tables, one per file.
More complex data structures should be wrapped in JSON 
for clarity and flexibility.
Web search for JSON Introduction for examples.

Abg
 

Min Sullivan

未讀,
2017年3月1日 下午3:36:422017/3/1
收件者:MIT App Inventor Forum
Will do!

Can you have a list of lists in CSV?  From what I'm seeing in my searches, it looks like no.

Abraham Getzler

未讀,
2017年3月1日 下午3:42:202017/3/1
收件者:MIT App Inventor Forum
Can you have a list of lists in CSV?  From what I'm seeing in my searches, it looks like no

A csv table is a list of lists.

Look for the project "states" in the Gallery for an example loading a table from a file.

ABG
 

Min Sullivan

未讀,
2017年3月1日 下午3:43:382017/3/1
收件者:MIT App Inventor Forum
Thanks so much!

Taifun

未讀,
2017年3月1日 下午3:45:042017/3/1
收件者:MIT App Inventor Forum
use the list to csv table block to convert a 2 dimensional list of lists into a csv table, for more dimensions use JSON as ABG suggested

Taifun

Min Sullivan

未讀,
2017年3月1日 下午3:46:562017/3/1
收件者:MIT App Inventor Forum
Can I do a list of JSON values?

Abraham Getzler

未讀,
2017年3月1日 下午4:14:292017/3/1
收件者:MIT App Inventor Forum
See this doc for my latest JSON project ...

After you understand it,
if you want more advanced work,

Warning - JSON schemas are in JSON, leading you to swirl around in a whirlpool of metadata if you stray too far from the shore.
Best to start out simple.

ABG

Min Sullivan

未讀,
2017年3月1日 下午5:46:202017/3/1
收件者:MIT App Inventor Forum
I slapped together an app to test my knowledge of how to get the values from a JSON file.  Turns out JSON code is the same as JavaScript when it comes to arrays and objects, so I understand JSON files.

In your example you're only reading from a JSON file.  Is there a simple way to update a JSON file, after it's JsonTextDecoded?  My JSON file is a list of objects, the objects of keys.  Is there a simple way to add another object of keys to the list?  A simple way to change the value of a key in one of the objects in the list?  I hope I'm not swirling down a whirlpool of metadata too far from sure shore...

Thanks for all your help!

Abraham Getzler

未讀,
2017年3月1日 下午6:56:022017/3/1
收件者:MIT App Inventor Forum
Updating a list inside another list in AI2 is tricky.
it's all pointers at that level.

There's a new flag in SCreen1 that turns on JSON conversion of lists when they are assigned into text.

I would use a JOIN with an empty string to force that conversion,
and keep simple lists of JSON strings to do just simple list replace operations at the top level,
before forcing a new JSON conversion.

If you stay with lists of lists, use the copy list block or build
entirely new structures with updated results to avoid pointing to dead data.

I do some of that in my JSON editor project.

ABG

Min Sullivan

未讀,
2017年3月1日 晚上7:45:302017/3/1
收件者:MIT App Inventor Forum
I could make a list of keys and a list of values.  Then I could use the find item in list block to find the index at which the key I want is.  I could get or replace the value at that index in the values list.  Whenever I made a change, I could copy the list that includes the other lists and lists of lists to the file.

One problem, though.  How will App Inventor know how to recreate those lists of lists of lists from the file's text?  I can't tell App Inventor to separate at commas.  Does the JSON conversion of lists that you mentioned take care of that?  I couldn't quite wrap my mind around your explanation.

Min Sullivan

未讀,
2017年3月1日 晚上7:47:002017/3/1
收件者:MIT App Inventor Forum
For that matter, how could I store a list of a lists in a file and then re-create those lists from the file?

Taifun

未讀,
2017年3月1日 晚上8:24:122017/3/1
收件者:MIT App Inventor Forum
convert the list of lists into csv format and store the csv table in the file
btw. probably easier would be to store the list of lists in TinyDB without need to convert it...

Abraham Getzler

未讀,
2017年3月1日 晚上8:48:092017/3/1
收件者:MIT App Inventor Forum
TinyDB is very update friendly if you can figure out how to build up tags that will identify table, row, and column all in one string.  See my Tinydb_export_import app in the Gallery.
ABG

Abraham Getzler

未讀,
2017年3月1日 晚上9:02:312017/3/1
收件者:MIT App Inventor Forum

Abraham Getzler

未讀,
2017年3月1日 晚上9:21:282017/3/1
收件者:MIT App Inventor Forum
Regarding creating JSOn codes of your own, attached are blocks for how to do it recursively.
I coded them for the ability to limit the parse depth, to defend against lists that point to themselves.
(See my Ouroboros example in the Gallery )

Unfortunately, it only works for 3 of 4 sample JSON examples .
AI2 does not guarantee recursion will always work.

ABG

blocks.png
JSON_encoder.aia

Min Sullivan

未讀,
2017年3月2日 下午3:00:282017/3/2
收件者:MIT App Inventor Forum
Thanks!  If I have lists inside of lists inside of lists, could I still convert to CSV format and store the table in the file?

I know it sounds crazy, but:
My app is a talking app.
There are levels in the app, that can be switched between using a list view.
In each level the sprites say texts when clicked.  The texts for each sprite are different in each level.
In each level each sprite also has a different x and y coordinate, etc.

I want to store a list, one list item for each sprite.
Each list items will be a list of the levels.
Each item in the list of levels will be a list of text, x, y, etc.

The user is allowed to add and delete levels and edit the details of each sprite in each level.

TinyDB has a character limit for each tag.  I would make a tag for each sprite in each level, but the user can add and delete levels, so having a list makes more sense.  That would be a list 3 lists deep (list inside a list inside a list):
sprites list
     levels list
          text, x, y, etc. list

That's why I need to know if I can convert a list 3 lists deep (list inside a list inside a list) to CSV format and store the table in the file.  Any advice?  Maybe I'm making this too complicated...
I would make a file for each sprite, but when the user switches levels I would have to get as many files as I have sprites, and that's a lot.

Min Sullivan

未讀,
2017年3月2日 下午3:01:502017/3/2
收件者:MIT App Inventor Forum
Thanks!  I'll look at your projects.  Ad I'll be using that webpage you pointed me to for a future project!

Min Sullivan

未讀,
2017年3月2日 下午4:33:552017/3/2
收件者:MIT App Inventor Forum
I tried to make a program that would allow the user to create, edit, and get results from a file.  When the file is created, I use the list to csv table block.  In the socket are lists inside of lists inside of lists, just like I'd be using for my Talker app.  Unfortunately, when I try to make the csv tables back into lists of lists of lists, it gives me a runtime error.  I have included screenshots of my test app.  How do you make lists of lists of lists into text for the file, and then re-create the lists of lists of lists from the file's text?
Screen shot 2017-03-02 at 4.28.48 PM.png
Screen shot 2017-03-02 at 4.29.16 PM.png
Screen shot 2017-03-02 at 4.29.26 PM.png
Screen shot 2017-03-02 at 4.30.18 PM.png

Min Sullivan

未讀,
2017年3月2日 下午4:34:542017/3/2
收件者:MIT App Inventor Forum
 Look at the last two screenshots first...

Min Sullivan

未讀,
2017年3月2日 下午4:40:032017/3/2
收件者:MIT App Inventor Forum
Attached is a screenshot of keys.  I'm trying to emulate keys and values, like in JSON.  The make a list [true, "text"]s is in the order of the keys list:
KEY  ---  value
Visible --- true
Text --- "text"
Screen shot 2017-03-02 at 4.36.33 PM.png

Min Sullivan

未讀,
2017年3月2日 下午5:01:132017/3/2
收件者:MIT App Inventor Forum
Hang on.  I had the select list item [list, index] backwards...  See attached screen capture.  Don't know what to do about list from csv table [text], though, when I'm trying to re-make the lists from the text.

I just made a successful version of the testing program with lists only 2 levels deep...
Screen shot 2017-03-02 at 4.58.38 PM.png
Screen shot 2017-03-02 at 4.58.49 PM.png

Abraham Getzler

未讀,
2017年3月2日 下午5:25:032017/3/2
收件者:MIT App Inventor Forum
I think you have a data modelling problem.

You have to flatten your data so it does not have more than 2 dimensions.

Lists inside lists of lists is 3 dimensions; that's beyond the csv limit of just 2 dimensions.

You need to switch to a table with more key columns and a compound key.
Have you seen the relational data model yet?

Your character table might look like:
character ID (PK)
character picture
character level (PK)
character's text
character's sprite component (at run time only)
character's X (for load/save)
character's Y (")

That's 7 columns (at least).

This can be done with Fusion Tables
(pk = Primary Key,  if each character can simultaneously be on multiple levels, otherwise just character ID is the key.)

See this doc for how to filter a list of lists (table) by column  to simulate SELECT with multiple WHERE clauses ...

ABG

Min Sullivan

未讀,
2017年3月2日 下午6:37:042017/3/2
收件者:MIT App Inventor Forum
I considered fusion tables earlier, but I want my app to work without Internet connection.  Wouldn't be good if someone relying on the app found themselves in a place without Internet and therefore couldn't communicate.  I'd use fusion tables otherwise...

Great article.  Do you have a website of your programming articles?

As for the Talking app data modeling problem, maybe I could squash that 3rd dimension by:
  1. Making a list for each level.
  2. Making a list inside the levels list with the particulars (visible, text, x, y, etc.) all in that list.  It would be like:
    Levels list item 1:
         Sprite 1 visible
         Sprite 1 text
         all the others for Sprite 1
         Sprite 2 visible
         Sprite 2 text
         all the others for Sprite 2
         and on and on for the other sprites
    Levels list item 2:
         follows the pattern of Levels list item 1
  3. Then I could make a function.  The function would multiply the number of the sprite who's details (visible, text, x, y, etc.) I need by the number of details each sprite has (a global variable), and add to that the item index of the detail I need (1 for visible, 2 for text, 3 for x, 4 for y, etc.).  The number the function ends with would be the id in the list (inside the levels list) of the detail I need.

I think that will work.  Thank you so much!!!  One more question: In App Inventor is there a limit to the number of items a list can contain?  If so, I'm sunk, since the lists inside the levels list will be quite lengthy I estimate.

Abraham Getzler

未讀,
2017年3月2日 下午6:55:272017/3/2
收件者:MIT App Inventor Forum
Try to think in terms of the logical data model first before you try to optimize it in a physical data model.

What are your objects and their attributes?

What depends on what?

How many sentences can you write of the form:

A ___ has one/many ___ ?


ABG


Taifun

未讀,
2017年3月2日 下午6:58:482017/3/2
收件者:mitappinv...@googlegroups.com
I considered fusion tables earlier, but I want my app to work without Internet connection
you could use the local SQlite database, see my SQlite extension here https://puravidaapps.com/sqlite.php

Taifun

Min Sullivan

未讀,
2017年3月2日 晚上7:32:352017/3/2
收件者:MIT App Inventor Forum
That looks awesome! I can't really afford it right now, though.

Min Sullivan

未讀,
2017年3月2日 晚上7:58:552017/3/2
收件者:MIT App Inventor Forum
There are many sprites.

A sprite has many levels.

A level has many values.

There are only level values for existing levels.

I'll do the objects and attributes in another post...

Min Sullivan

未讀,
2017年3月2日 晚上8:01:472017/3/2
收件者:MIT App Inventor Forum
My objects are:
Visible (in use)
Text to say
Web link or file path for image
The web link or image path
Width of image (for displaying as sprite)
Height of image (for the same)
X coordinate of sprite
Y coordinate of sprite
Z value if sprite

Abraham Getzler

未讀,
2017年3月3日 上午11:32:232017/3/3
收件者:MIT App Inventor Forum
Thanks! If I have lists inside of lists inside of lists, could I still 

convert to CSV format and store the table in the file?
 

 After sleeping on this question, I remembered a trick I used in my TinyDB_export_import sample
to turn the entire contents of TinyDB, including tags and values that might
be simple values, lists, and tables (lists of lists) into a single piece of text
that could be written to a file, and imported and reconstructed later.

The core of the technique is to take the outer 2 branch levels of a 
three level tree and temporarily replace them with their csv table text,
reducing the depth needed for further csv text conversion.

There's a limit to how far this technique can be pushed, involving
AI2's (and yours) ability to unravel quotes of quotes of quotes.

ABG


Abraham Getzler

未讀,
2017年3月3日 上午11:37:462017/3/3
收件者:MIT App Inventor Forum
About JSON - JSON is the data equivalent of the multiple layers of cardboard, bubble wrap, 
plastic peanuts, inner boxes, plastic bags, twist ties, and IKEA assembly instruction sheets
that accompany a product you buy over the Internet.

 It's fine for storage and transport across programs, but it's awkward to live out of.

ABG

Min Sullivan

未讀,
2017年3月3日 下午2:29:572017/3/3
收件者:MIT App Inventor Forum
So if I use that technique I would create a sprite list.

Each item in the sprite list would be a levels list. Each item in the levels list would be a details (visible, text, x,y, etc.) list translated into a csv row.

Min Sullivan

未讀,
2017年3月3日 下午2:33:032017/3/3
收件者:MIT App Inventor Forum
To edit a details list I would translate a levels list item from csv to a list, edit the newly created list, and translate the lust back to csv.

Am I correct or do I misunderstand?

Abraham Getzler

未讀,
2017年3月3日 下午4:33:152017/3/3
收件者:MIT App Inventor Forum
So if I use that technique I would create a sprite list.

Each item in the sprite list would be a levels list.  Each item in the levels list would be a details (visible, text, x,y, etc.) list translated into a csv row


To edit a details list I would translate a levels list item from csv to a list, edit the newly created list, and translate the list back to csv.

Am I correct or do I misunderstand?


So your key hierarchy is: sprite, level, detailname ?
And you have a simple value to save or load for each combination (sprite,level,detail)?

The simplest and easiest way to do this is to build up a TinyDB tag from a 5-way text JOIN (spriteName, '/', levelNameorNumber, '/', detailName)
and store that detail value under that tag.

That would eliminate a boat load of complexity.

ABG

Min Sullivan

未讀,
2017年3月3日 下午4:53:372017/3/3
收件者:MIT App Inventor Forum
That would work awesome, but:
Levels can be created and deleted. Levels are navigated with a listview. I need the levels to be a list to work with the creating and deleting the user is allowed to do. At least, I think so.

Abraham Getzler

未讀,
2017年3月3日 下午4:57:042017/3/3
收件者:MIT App Inventor Forum
Levels can be created and deleted.  Levels are navigated with a listview.  I need the levels to be a list to work with the creating and deleting the user is allowed to do

So devote a TinyDB tag 'LEVELS' to the list of names of the levels, emptyList if not found.

ABG
 

Min Sullivan

未讀,
2017年3月3日 下午5:00:532017/3/3
收件者:MIT App Inventor Forum
Ob my gosh! You're right! All I have to do then would be give each level a different name. Thank you!!!

Min Sullivan

未讀,
2017年3月3日 晚上9:17:522017/3/3
收件者:MIT App Inventor Forum
When a level is deleted, should I cleae the tags with the values for that level? I could loop through the sprites tags for that level:
In loop:
Clear tag join level name, sprite number, visible
Clear tag join lev name, sprite number, text
And so on.

Abraham Getzler

未讀,
2017年3月4日 下午6:49:192017/3/4
收件者:MIT App Inventor Forum
Yes.

That's called relational integrity in a data base,
but here you should do it manually.

there's a TinyDB block to return a list of all the tags, which
you can examine one by one either by pattern matching for /levelname/
or by splitting at / and examining by length of list and selected values.

ABG

 

Min Sullivan

未讀,
2017年3月4日 晚上8:35:352017/3/4
收件者:MIT App Inventor Forum
Awesome! Thanks so much! One more question, please:
I'm actually doing it level, sprite, detail. Wheb a sprite is 'deleted' from a level, I'm going to clear its tags for the level. Should I make a list of the names of the details tags? So when a sprite's deleted, its tags can be cleared by looping through the list of the details names.

Is that a bad way to do it?

Abraham Getzler

未讀,
2017年3月4日 晚上8:56:092017/3/4
收件者:MIT App Inventor Forum
Sounds good.
Try it.

ABG

Min Sullivan

未讀,
2017年3月6日 下午5:04:582017/3/6
收件者:MIT App Inventor Forum
I was looking at other communication apps — something I should have done before I started this whole endeavor — and saw that one has a listview of texts.  So that set me to thinking maybe I should allow the user to switch between a listview and the sprites.  The user could have an unlimited number of texts [tems] in the listview.  But that's not possible to do with the sprites.

So I was thinking, when a sprite is deleted in the level the user is in, if there are more items in the listview for that level than there are sprites available, the "deleted" sprite should be set to one of the unseen listview items.

Going back and forth between listview and spritesview, and doing the "when sprite deleted" thing described above, I'd need to use a list for the items inside the levels.

Why?  For example:

I have a total of 5 sprites (I won't really, but for this example, I will).
  1. I switch to listview.
  2. I create more than 5 items (texts to say).
  3. I switch back to spriteview.
  4. Since there are only 5 spites, I use them for the first 5 items (texts to say) created.
then
  1. Sprite 1 is deleted.
  2. The 6th item in the list for that level replaces the 1st item in the list for that level.
  3. Sprite 1 is set to the new 1st item in the list for that level.

Do I make sense?

I'm not sure what to do now with the data modeling.  The only solution I can see is having a file for each level that stores the level's items list.  But that would be awkward, like living out of a suitcase.  I can't see how tinyDB will work, though.  'Course, sometimes I can't find my shoe when it's right next to me (which actually happened once).  Do you have any suggestions?  Thanks!

Abraham Getzler

未讀,
2017年3月6日 下午5:39:492017/3/6
收件者:MIT App Inventor Forum
You are overloading the word "sprite".

The AI2 Sprite component is like a moving picture frame for a picture of a person or thing.

You no doubt have pictures in your house that are not sitting in frames at the moment,
because there's a limit to your wall and desk space.

Pick a new word for the thing you might eventually show in a sprite:
  character?
  object (too vague)
  NPC ?

ABg

Min Sullivan

未讀,
2017年3月6日 下午5:55:402017/3/6
收件者:MIT App Inventor Forum
Maybe picture?

Abraham Getzler

未讀,
2017年3月6日 下午6:13:432017/3/6
收件者:MIT App Inventor Forum
I've played games where one player character could have any of multiple pictures, depending on how sick or bloody they got.

I've also played small Indy games that let me build multiple characters, each of which had just one picture chosen from a small pool of pictures.

Your choice of words changes the model.

ABG



Min Sullivan

未讀,
2017年3月7日 中午12:57:402017/3/7
收件者:MIT App Inventor Forum
Each sprite can have 1 image in each level. In each level, the sprites that have an image in that level also have 1 word/phrase or filepath to a audio file in that level.

P.S. Sorry I accidentally emailed you.

Abraham Getzler

未讀,
2017年3月7日 下午1:54:262017/3/7
收件者:MIT App Inventor Forum
Now think up how you can store that information when the app is shut down between runs.
ABG

Min Sullivan

未讀,
2017年3月7日 下午2:10:332017/3/7
收件者:MIT App Inventor Forum
I could keep a file for each level (since tinyDB has a limit of 80 characters). Each file will store a csv list.

To get the detail "name" (the user will name the items in the levels) of the first item in a level called myLevel, I'd get the tinyDB tag:
Join "myLevel/" + first item in list from file myLevel + "/name"

How's that? In the file I could do all the list work that needs to be done when a sprite in a level is deleted and there are more items in that level than there are sprites.

Abraham Getzler

未讀,
2017年3月7日 下午3:01:482017/3/7
收件者:MIT App Inventor Forum
 (since tinyDB has a limit of 80 characters

Where did you hear this?

It's news to me.
Maybe the limit is only on the length of the tags?

ABG
 

Min Sullivan

未讀,
2017年3月7日 下午3:12:172017/3/7
收件者:MIT App Inventor Forum
Yeah. I meant the length of the tags. Sorry.

Abraham Getzler

未讀,
2017年3月7日 下午3:38:132017/3/7
收件者:MIT App Inventor Forum

To get the detail "name" (the user will name the items in the levels) of the first item in a level called myLevel, I'd get the tinyDB tag:
Join "myLevel/" + first item in list from file myLevel + "/name"

How's that?  In the file I could do all the list work that needs to be done when a sprite in a level is deleted and there are more items in that level than there are sprites.


Here are some tags ;  values to consider:

SETTINGS/Orientation ; Portrait
Levels ; (myLevel, hisLevel)
Levels/myLevel/characters ; (ABG, Min)
Levels/myLevel/characters/ABG/class ; Troll
Levels/myLevel/characters/ABG/XP ; 34567
Levels/myLevel/characters/Min/class ; Bosmer
Levels/myLevel/characters/Min/XP ; 345
 

Notice how it's possible to go way down to the attribute level  in your tags.
Also notice how I left room for settings in my tag design.

Any assignments of characters to Sprite component sowuld be tracked separately at run time.

ABG

Min Sullivan

未讀,
2017年3月7日 下午4:09:192017/3/7
收件者:MIT App Inventor Forum
I like your tags and values.

I don't understand what you mean by:


Any assignments of characters to Sprite component sowuld be tracked separately at run time.

How do you track something? Does that mean that during runtime I should set the image blocks and other blocks of the sprites? I'll be doing that.

Abraham Getzler

未讀,
2017年3月7日 下午4:39:502017/3/7
收件者:MIT App Inventor Forum
How do you track something?  Does that mean that during runtime I should set the image blocks and other blocks of the sprites?  I'll be doing that.

Pretty much.

We'll cross that bridge when you get to it.

ABG
 
回覆所有人
回覆作者
轉寄
0 則新訊息