how to read text files on android builds for Unity? - c#

I've been having a lot of trouble trying to read text files stored in the StreamingAsset folder on my Android phone when I build the game as an .apk file.
I know that for Android you have to use a different path to access the files by using
"jar:file://" + Application.dataPath + "!/assets" + fileName;
and store it into the WWW class. I have tried many ways but nothing seems to work for me as I am totally lost right now. My code looks like this:
void Awake(){
string filePath = "jar:file://" + Application.dataPath + "!/assets" + fileName;
// Reads our text file and stores it in the array
string[][] Level = readFile (filePath);
}
// Reads our level text file and stores the information in a jagged array, then returns that array
string[][] readFile(string file){
WWW loadFile = new WWW (file);
while (!loadFile.isDone) {}
string text = System.IO.File.ReadAllText(loadFile.text);
string[] lines = Regex.Split(text, "\r\n");
int rows = lines.Length;
string[][] levelBase = new string[rows][];
for (int i = 0; i < lines.Length; i++) {
string[] stringsOfLine = Regex.Split(lines[i], " ");
levelBase[i] = stringsOfLine;
}
return levelBase;
}

You can use streamreader for this:
List<string> lines = new List<string>();
using (StreamReader reader = new StreamReader("file.txt"))
{
string line;
while ((line = reader.ReadLine()) != null)
{
lines.Add(line);
}
}

The line string text = System.IO.File.ReadAllText(loadFile.text); is wrong:
loadFile.text already contains the contents of file you are trying to open with System.IO.File.ReadAllText
Also you can't use the System.IO.File.ReadAllText method to access file from StreamingAssets on Android.

Related

Read & write a single line from a file without overwrite [duplicate]

I have two text files, Source.txt and Target.txt. The source will never be modified and contain N lines of text. So, I want to delete a specific line of text in Target.txt, and replace by an specific line of text from Source.txt, I know what number of line I need, actually is the line number 2, both files.
I haven something like this:
string line = string.Empty;
int line_number = 1;
int line_to_edit = 2;
using StreamReader reader = new StreamReader(#"C:\target.xml");
using StreamWriter writer = new StreamWriter(#"C:\target.xml");
while ((line = reader.ReadLine()) != null)
{
if (line_number == line_to_edit)
writer.WriteLine(line);
line_number++;
}
But when I open the Writer, the target file get erased, it writes the lines, but, when opened, the target file only contains the copied lines, the rest get lost.
What can I do?
the easiest way is :
static void lineChanger(string newText, string fileName, int line_to_edit)
{
string[] arrLine = File.ReadAllLines(fileName);
arrLine[line_to_edit - 1] = newText;
File.WriteAllLines(fileName, arrLine);
}
usage :
lineChanger("new content for this line" , "sample.text" , 34);
You can't rewrite a line without rewriting the entire file (unless the lines happen to be the same length). If your files are small then reading the entire target file into memory and then writing it out again might make sense. You can do that like this:
using System;
using System.IO;
class Program
{
static void Main(string[] args)
{
int line_to_edit = 2; // Warning: 1-based indexing!
string sourceFile = "source.txt";
string destinationFile = "target.txt";
// Read the appropriate line from the file.
string lineToWrite = null;
using (StreamReader reader = new StreamReader(sourceFile))
{
for (int i = 1; i <= line_to_edit; ++i)
lineToWrite = reader.ReadLine();
}
if (lineToWrite == null)
throw new InvalidDataException("Line does not exist in " + sourceFile);
// Read the old file.
string[] lines = File.ReadAllLines(destinationFile);
// Write the new file over the old file.
using (StreamWriter writer = new StreamWriter(destinationFile))
{
for (int currentLine = 1; currentLine <= lines.Length; ++currentLine)
{
if (currentLine == line_to_edit)
{
writer.WriteLine(lineToWrite);
}
else
{
writer.WriteLine(lines[currentLine - 1]);
}
}
}
}
}
If your files are large it would be better to create a new file so that you can read streaming from one file while you write to the other. This means that you don't need to have the whole file in memory at once. You can do that like this:
using System;
using System.IO;
class Program
{
static void Main(string[] args)
{
int line_to_edit = 2;
string sourceFile = "source.txt";
string destinationFile = "target.txt";
string tempFile = "target2.txt";
// Read the appropriate line from the file.
string lineToWrite = null;
using (StreamReader reader = new StreamReader(sourceFile))
{
for (int i = 1; i <= line_to_edit; ++i)
lineToWrite = reader.ReadLine();
}
if (lineToWrite == null)
throw new InvalidDataException("Line does not exist in " + sourceFile);
// Read from the target file and write to a new file.
int line_number = 1;
string line = null;
using (StreamReader reader = new StreamReader(destinationFile))
using (StreamWriter writer = new StreamWriter(tempFile))
{
while ((line = reader.ReadLine()) != null)
{
if (line_number == line_to_edit)
{
writer.WriteLine(lineToWrite);
}
else
{
writer.WriteLine(line);
}
line_number++;
}
}
// TODO: Delete the old file and replace it with the new file here.
}
}
You can afterwards move the file once you are sure that the write operation has succeeded (no excecption was thrown and the writer is closed).
Note that in both cases it is a bit confusing that you are using 1-based indexing for your line numbers. It might make more sense in your code to use 0-based indexing. You can have 1-based index in your user interface to your program if you wish, but convert it to a 0-indexed before sending it further.
Also, a disadvantage of directly overwriting the old file with the new file is that if it fails halfway through then you might permanently lose whatever data wasn't written. By writing to a third file first you only delete the original data after you are sure that you have another (corrected) copy of it, so you can recover the data if the computer crashes halfway through.
A final remark: I noticed that your files had an xml extension. You might want to consider if it makes more sense for you to use an XML parser to modify the contents of the files instead of replacing specific lines.
When you create a StreamWriter it always create a file from scratch, you will have to create a third file and copy from target and replace what you need, and then replace the old one.
But as I can see what you need is XML manipulation, you might want to use XmlDocument and modify your file using Xpath.
You need to Open the output file for write access rather than using a new StreamReader, which always overwrites the output file.
StreamWriter stm = null;
fi = new FileInfo(#"C:\target.xml");
if (fi.Exists)
stm = fi.OpenWrite();
Of course, you will still have to seek to the correct line in the output file, which will be hard since you can't read from it, so unless you already KNOW the byte offset to seek to, you probably really want read/write access.
FileStream stm = fi.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
with this stream, you can read until you get to the point where you want to make changes, then write. Keep in mind that you are writing bytes, not lines, so to overwrite a line you will need to write the same number of characters as the line you want to change.
I guess the below should work (instead of the writer part from your example). I'm unfortunately with no build environment so It's from memory but I hope it helps
using (var fs = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite)))
{
var destinationReader = StreamReader(fs);
var writer = StreamWriter(fs);
while ((line = reader.ReadLine()) != null)
{
if (line_number == line_to_edit)
{
writer.WriteLine(lineToWrite);
}
else
{
destinationReader .ReadLine();
}
line_number++;
}
}
The solution works fine. But I need to change single-line text when the same text is in multiple places. For this, need to define a trackText to start finding after that text and finally change oldText with newText.
private int FindLineNumber(string fileName, string trackText, string oldText, string newText)
{
int lineNumber = 0;
string[] textLine = System.IO.File.ReadAllLines(fileName);
for (int i = 0; i< textLine.Length;i++)
{
if (textLine[i].Contains(trackText)) //start finding matching text after.
traced = true;
if (traced)
if (textLine[i].Contains(oldText)) // Match text
{
textLine[i] = newText; // replace text with new one.
traced = false;
System.IO.File.WriteAllLines(fileName, textLine);
lineNumber = i;
break; //go out from loop
}
}
return lineNumber
}

I am unable to read content from .txt file using StreamReader class of c#

Here is my code..I am trying to read data from .txt file which was stored in music folder. But i am getting some error like,
System.NotSupportedException.
The given path's format is not supported.
Please help...........
string path = #"Music:\streamfile.txt";
using (StreamReader sr = File.OpenText(path))
{
String s = "";
while ((s = sr.ReadLine()) != null)
{
Console.WriteLine(s);
}
}
Console.ReadLine();
There is a list with 'special' folders somewhere but you can construct it yourself:
string path = Path.Combine(Environment.GetEnvironmentVariable("USERPROFILE"),
"Music", "streamfile.txt");
you can try Environment.GetFolderPath
//if you want windows common music folder ex:C:\Users\Public\Music\streamfile.txt
var CommonMusicPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonMusic) + #"\streamfile.txt";
//if you want windows user music folder ex:C:\Users\username\Music\streamfile.txt
var MyUserMusicPath = Environment.GetFolderPath(Environment.SpecialFolder.MyMusic) + #"\streamfile.txt";
using (StreamReader sr = File.OpenText(MyUserMusicPath))
{
String s = "";
while ((s = sr.ReadLine()) != null)
{
Console.WriteLine(s);
}
}
Console.ReadLine();

Replace a line in text file without creating another file [duplicate]

I have two text files, Source.txt and Target.txt. The source will never be modified and contain N lines of text. So, I want to delete a specific line of text in Target.txt, and replace by an specific line of text from Source.txt, I know what number of line I need, actually is the line number 2, both files.
I haven something like this:
string line = string.Empty;
int line_number = 1;
int line_to_edit = 2;
using StreamReader reader = new StreamReader(#"C:\target.xml");
using StreamWriter writer = new StreamWriter(#"C:\target.xml");
while ((line = reader.ReadLine()) != null)
{
if (line_number == line_to_edit)
writer.WriteLine(line);
line_number++;
}
But when I open the Writer, the target file get erased, it writes the lines, but, when opened, the target file only contains the copied lines, the rest get lost.
What can I do?
the easiest way is :
static void lineChanger(string newText, string fileName, int line_to_edit)
{
string[] arrLine = File.ReadAllLines(fileName);
arrLine[line_to_edit - 1] = newText;
File.WriteAllLines(fileName, arrLine);
}
usage :
lineChanger("new content for this line" , "sample.text" , 34);
You can't rewrite a line without rewriting the entire file (unless the lines happen to be the same length). If your files are small then reading the entire target file into memory and then writing it out again might make sense. You can do that like this:
using System;
using System.IO;
class Program
{
static void Main(string[] args)
{
int line_to_edit = 2; // Warning: 1-based indexing!
string sourceFile = "source.txt";
string destinationFile = "target.txt";
// Read the appropriate line from the file.
string lineToWrite = null;
using (StreamReader reader = new StreamReader(sourceFile))
{
for (int i = 1; i <= line_to_edit; ++i)
lineToWrite = reader.ReadLine();
}
if (lineToWrite == null)
throw new InvalidDataException("Line does not exist in " + sourceFile);
// Read the old file.
string[] lines = File.ReadAllLines(destinationFile);
// Write the new file over the old file.
using (StreamWriter writer = new StreamWriter(destinationFile))
{
for (int currentLine = 1; currentLine <= lines.Length; ++currentLine)
{
if (currentLine == line_to_edit)
{
writer.WriteLine(lineToWrite);
}
else
{
writer.WriteLine(lines[currentLine - 1]);
}
}
}
}
}
If your files are large it would be better to create a new file so that you can read streaming from one file while you write to the other. This means that you don't need to have the whole file in memory at once. You can do that like this:
using System;
using System.IO;
class Program
{
static void Main(string[] args)
{
int line_to_edit = 2;
string sourceFile = "source.txt";
string destinationFile = "target.txt";
string tempFile = "target2.txt";
// Read the appropriate line from the file.
string lineToWrite = null;
using (StreamReader reader = new StreamReader(sourceFile))
{
for (int i = 1; i <= line_to_edit; ++i)
lineToWrite = reader.ReadLine();
}
if (lineToWrite == null)
throw new InvalidDataException("Line does not exist in " + sourceFile);
// Read from the target file and write to a new file.
int line_number = 1;
string line = null;
using (StreamReader reader = new StreamReader(destinationFile))
using (StreamWriter writer = new StreamWriter(tempFile))
{
while ((line = reader.ReadLine()) != null)
{
if (line_number == line_to_edit)
{
writer.WriteLine(lineToWrite);
}
else
{
writer.WriteLine(line);
}
line_number++;
}
}
// TODO: Delete the old file and replace it with the new file here.
}
}
You can afterwards move the file once you are sure that the write operation has succeeded (no excecption was thrown and the writer is closed).
Note that in both cases it is a bit confusing that you are using 1-based indexing for your line numbers. It might make more sense in your code to use 0-based indexing. You can have 1-based index in your user interface to your program if you wish, but convert it to a 0-indexed before sending it further.
Also, a disadvantage of directly overwriting the old file with the new file is that if it fails halfway through then you might permanently lose whatever data wasn't written. By writing to a third file first you only delete the original data after you are sure that you have another (corrected) copy of it, so you can recover the data if the computer crashes halfway through.
A final remark: I noticed that your files had an xml extension. You might want to consider if it makes more sense for you to use an XML parser to modify the contents of the files instead of replacing specific lines.
When you create a StreamWriter it always create a file from scratch, you will have to create a third file and copy from target and replace what you need, and then replace the old one.
But as I can see what you need is XML manipulation, you might want to use XmlDocument and modify your file using Xpath.
You need to Open the output file for write access rather than using a new StreamReader, which always overwrites the output file.
StreamWriter stm = null;
fi = new FileInfo(#"C:\target.xml");
if (fi.Exists)
stm = fi.OpenWrite();
Of course, you will still have to seek to the correct line in the output file, which will be hard since you can't read from it, so unless you already KNOW the byte offset to seek to, you probably really want read/write access.
FileStream stm = fi.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
with this stream, you can read until you get to the point where you want to make changes, then write. Keep in mind that you are writing bytes, not lines, so to overwrite a line you will need to write the same number of characters as the line you want to change.
I guess the below should work (instead of the writer part from your example). I'm unfortunately with no build environment so It's from memory but I hope it helps
using (var fs = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite)))
{
var destinationReader = StreamReader(fs);
var writer = StreamWriter(fs);
while ((line = reader.ReadLine()) != null)
{
if (line_number == line_to_edit)
{
writer.WriteLine(lineToWrite);
}
else
{
destinationReader .ReadLine();
}
line_number++;
}
}
The solution works fine. But I need to change single-line text when the same text is in multiple places. For this, need to define a trackText to start finding after that text and finally change oldText with newText.
private int FindLineNumber(string fileName, string trackText, string oldText, string newText)
{
int lineNumber = 0;
string[] textLine = System.IO.File.ReadAllLines(fileName);
for (int i = 0; i< textLine.Length;i++)
{
if (textLine[i].Contains(trackText)) //start finding matching text after.
traced = true;
if (traced)
if (textLine[i].Contains(oldText)) // Match text
{
textLine[i] = newText; // replace text with new one.
traced = false;
System.IO.File.WriteAllLines(fileName, textLine);
lineNumber = i;
break; //go out from loop
}
}
return lineNumber
}

How to make seperate lines with c# (Textfile)

I'm making this application for fun but i have a problem
I want this string/file to be read in seperate lines.
this the file(not the whole file):
1ChampSelectPack.Ahri.mp31ChampSelectPack.Akali.mp31ChampSelectPack.Alistar.mp31ChampSelectPack.Amumu.mp31ChampSelectPack.Anivia.mp31ChampSelectPack.Annie.mp31ChampSelectPack.Ashe.mp31ChampSelectPack.Blitzcrank.mp31ChampSelectPack.Brand.mp31ChampSelectPack.Caitlyn.mp3
and this is what i got so far:
List<SoundPath> paths = new List<SoundPath>();
StreamReader reader = File.OpenText("C:/Users/Esat/Documents/Visual Studio 2010/Projects/WikiLoL/WikiLoL/lolSoundBoard/1ChampSelectPack/files.txt");
while (!reader.EndOfStream)
{
SoundPath path = new SoundPath();
path.Path = reader.ReadLine();
paths.Add(path);
}
reader.Close();
return paths;
Not sure if that is what you want:
"YourString".Split(new string[] {"mp3"}, StringSplitOptions.None)
You would have to append the "mp3" on each line afterwards.
You can do it using splitting on .mp3 and adding .mp3 in each element of resultant array.
string text = File.ReadAllText("C:/Users/Esat/Documents/Visual Studio 2010/Projects/WikiLoL/WikiLoL/lolSoundBoard/1ChampSelectPack/files.txt");
string[] lines = text.Split(new string[] { ".mp3" }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < lines.Length; i++)
lines[i] = lines[i] + ".mp3";

Rewriting a text file after reading it

i got a file that is store in my appliction directory, and he got some site list.
i dont have any problem reading it, but when i want to write to it, i get
System.ArgumentException: Stream is not writeable
this is how i accsess the file:
FileStream theTextFileStream = new FileStream(Environment.CurrentDirectory + "/fourmlinks.txt",FileMode.OpenOrCreate);
and this is the function that throw me the expection:
public static void WriteNewTextToFile(string text, FileStream theFile)
{
string fileText = GetAllTextFromFile(theFile);
ArrayList fileLIst = populateListFromText(fileText);
using (StreamWriter fileWriter = new StreamWriter(theFile))
{
fileWriter.Write(String.Empty);
for (int i = 0; i < fileLIst.Count; i++)
{
fileWriter.WriteLine(fileLIst[i].ToString());
}
}
}
the function read the old and new text and add it to an arry. then i clean the file from every thing, and rewriting it with the old and new data from the arry i made.
i dont know if that will help but here is the file proprites:
Build Action: None
Copy To Out Put Directory: Copy always
why i cant rewrite the file?
this is the function i use to read the file content:
public static string GetAllTextFromFile(FileStream theFile)
{
string fileText = "";
using (theFile)
{
using (StreamReader stream = new StreamReader(theFile))
{
string currentLine = "";
while ((currentLine = stream.ReadLine()) != null)
{
fileText += currentLine + "\n";
}
}
}
return fileText;
}
You have to use Read/Write file access as third parameter -
FileStream theTextFileStream = new FileStream(Environment.CurrentDirectory + "/fourmlinks.txt",FileMode.OpenOrCreate, FileAccess.ReadWrite
);
Important - Remove using(theFile) statement:
public static string GetAllTextFromFile(FileStream theFile)
{
string fileText = "";
using (StreamReader stream = new StreamReader(theFile))
{
string currentLine = "";
while ((currentLine = stream.ReadLine()) != null)
{
fileText += currentLine + "\n";
}
}
return fileText;
}
Do not use using construct in your case as it will close the underlying stream as in your case you have to manually open and close stream objects.
This will allow you to write in the file as well.
For more information refer following links -
FileStream Constructor
FileAccess Enumeration

Categories