very confused by this, when I read in a file using the code below when it gets to the end it prints out FFFFFF, could anyone explain this to me the text file only has numbers and letters in it? Any help would be most greatful!
String fileDirectory = "C:\\t.txt";
StreamReader reader = new StreamReader(fileDirectory);
int hexIn;
for (int i = 0; (hexIn = reader.Read()) != -1; i++)
{
String s;
s = hexIn.ToString("X2");
int x = 0;
while (x < 1)
{
hexIn = reader.Read();
s = hexIn.ToString("X2");
x++;
}
hexIn = reader.Read();
s = hexIn.ToString("X2");
MessageBox.Show(s);
}
You've got three Read calls per loop iteration, which means that any one of them could return -1 to indicate the end of the file. I suspect that's then being converted to FFFFFFFF, hence your output. Why do you have more than one Read call? And why aren't you reading a block at a time?
The FFFFFF may also indicate an empty value. If you Hex editted Nintendo DS Roms you would see a whole bunch of FFFFFFFF at the end which is put there because the game is too small for the cartridge so in actual fact that file may have empty values at the end.
Related
I am creating a program that reads a text file and gets the data then puts it into an array. My problem is that there are instances where a column is intended to be blank but the blank value must still be considered as a value but when my program reads the blank column, it reads the next value and puts it in the array where the value should be 0 or blank. I have tried to count the spaces between each column to make it a condition but the spaces are not reliable since the data varies in length. Any ideas about how I might do this?
Here is what my text data looks like.
Data1 Data2 Data3
1.325 1.57 51.2
2.2 21.85
12.5 25.13
15.85 13.78 1.85
I need my array to look like this
firstRow['1.325','1.57','51.2'];
secondRow['2.2','0','21.85'];
If your file is tab-splitted, use line.Split("\t") to get array of substrings of each line. Then, each substring you can convert into you data type. In your case it must be nullable, e,g, decimal?.
Here's a starting point if you have a list of headers in the order they appear in the data and if your values are always aligned to the headers.
import io, csv, sys
data = '''\
Data 1 Data 2 Data 3
1.325 1.57 51.2
2.2 21.85
12.5 25.13
15.85 13.78 1.85
'''
headers = ['Data 1', 'Data 2', 'Data 3'] # order should match headers
f = io.StringIO(data)
h = f.readline()
indexes = [h.find(s) for s in headers]
rows = []
for line in f:
line = line[:-1] # strip trailing linefeed
d = {}
for key, index in list(zip(headers, indexes))[::-1]: # slice from the right
val = line[index:]
line = line[:index]
d[key] = val.strip()
rows.append(d)
writer = csv.DictWriter(sys.stdout, headers)
writer.writeheader()
writer.writerows(rows)
Since I have ran out of time, what I did was to count the number of spaces and if the spaces exceed by a number (in my case, 10) I'll add a value empty value in my array
string[] lsData = pData.Split(' ');
string[] lsData1 = new string[18];
int newArrayData = 0;
int spaceCounter = 0;
for (int i = 0; i < lsData.Length; i++)
{
if (lsData[i] != "")
{
lsData1[newArrayData] = lsData[i];
newArrayData++;
spaceCounter = 0;
}
else
{
spaceCounter++;
}
if (spaceCounter >= 10)
{
lsData1[newArrayData] = "";
newArrayData++;
spaceCounter = 0;
}
}
I'm learning C and C#, this question is for C#. I have this while loop and it is resulting in a infinite loop. I have used this before and it always worked great. But now it just loops forever and never exits. I'm doing this while loop to count the number of lines in the file.
Here is the code:
using (TextReader obj2 = new StreamReader(combined))
{
int count = 1;
while (obj2.Peek() != -1)
{
count++;
}
obj2.Close();
TextWriter obj = File.AppendText(combined);
Console.Write("How many lines do you want to add to the file?:");
int numberOfLines = 0;
int lineNumer = count + 1;
numberOfLines = Convert.ToInt32(Console.ReadLine());
for (int i = 0; i < numberOfLines; i++)
{
Console.Write("Enter a line of text:");
string line = Console.ReadLine();
obj.WriteLine(lineNumer + ". " + line);
}
}
Peek() doesn't advanced the reader. You need to make a call to obj2.Read() inside your loop, or it will never terminate as you've seen.
From the linked MSDN reference:
Reads the next character without changing the state of the reader or
the character source. Returns the next available character without
actually reading it from the reader.
See also Read() on MSDN.
These two methods work hand-in-hand quite often so that you can check if the stream has ended without affecting it. You're on the right track!
I have several log files that I need to parse and combine based on a timestamp. They're of the format:
GaRbAgE fIrSt LiNe
[1124 0905 134242422 ] Logs initialized
[1124 0905 134242568 SYSTEM] Good log entry:
{ Collection:
["Attribute"|String]
...
[1124 0905 135212932 SYSTEM] Good log entry:
As you can see I don't need the first line.
I'm currently using some Regex to parse each file: one expression determines if I have a "Logs initialized" line, which I don't care about and discard; another determines if I have a "Good log entry", which I keep and parse; and some of the good log entries span multiple lines. I simply accept the logs that are on multiple lines. However, the code currently also captures the first garbage line because it is indistinguishable from a multi-line log comment from a Regex viewpoint. Furthermore, from what I read Regex is not the solution here (Parsing a log file with regular expressions).
There are many log files and they can grow to be rather large. For this reason, I'm only reading 50 lines at a time per log before buffering and then combining them into a separate file. I loop through every file as long as there are non-null files left. Below is a code example where I replaced some conditions and variables with explanations.
while (there are non-null files left to read)
{
foreach (object logFile in logFiles) //logFiles is an array that stores the log names
{
int numLinesRead = 0;
using (StreamReader fileReader = File.OpenText(logFile.ToString()))
{
string fileLine;
// read in a line from the file
while ((fileLine = fileReader.ReadLine()) != null && numLinesRead < 50)
{
// compare line to regex expressions
Match rMatch = rExp.Match(fileLine);
if (rMatch.Success) // found good log entry
{
...
How would you skip that first garbage line? Unfortunately it is not as easy as simply consuming a line with ReadLine() because the StreamReader is within a loop and I'll end up deleting a line every 50 others.
I thought of keeping a list or array of files for which I've skipped that first line already (in order to not skip it more than once) but that is sort of ugly. I also thought of getting rid of the using statement and opening the StreamReader up before the loop but I'd prefer not to do that.
EDIT after posting I just realized that my implementation might not be correct at all. When the StreamReader closes and disposes I believe my previous position in the file will be lost. In which case, should I still use StreamReader without the using construct or is there a different type of file reader I should consider?
You could just use something like this:
Instead of this:
using (StreamReader fileReader = File.OpenText(logFile.ToString()))
{
string fileLine;
// read in a line from the file
while ((fileLine = fileReader.ReadLine()) != null && numLinesRead < 50)
{
do this:
int numLinesRead = 0;
foreach (var fileLine in File.ReadLines(logFile.ToString()).Skip(1))
{
if (++numLinesRead >= 50)
break;
Add another parameter to the method for the position in the file. First time in it's zero, and you can consume the line before you go into the loop. After that you can use it to position the stream where that last one left off.
e.g
long position = 0;
while position >= 0
{
position = ReadFiftyLines(argLogFile,0);
}
public long ReadFiftyLines(string argLogFile, long argPosition)
{
using(FileStream fs = new FileStream(argLogFile,FileMode.Open,FileAccess.Read))
{
string line = null;
if (argPosition == 0)
{
line = reader.Readline();
if (line == null)
{
return -1; // empty file
}
}
else
{
fs.Seek(argPosition,SeekOrigin.Begin);
}
StreamReader reader = new StreamReader(fs);
int count = 0;
while ((line = reader.ReadLine() != null) && (count < 50))
{
count++;
// do stuff with line
}
if (line == null)
{
return -1; // end of file
}
return fs.Position;
}
}
or somesuch.
I am trying to read the same file twice.
I have been using a FileUpload to look up the file. I was successful in the first read where I find out how many lines the file have, using the next code in C# ans asp.net:
Stream data_file;
data_file=FileUpload1.PostedFile.InputStream;
string line;
int elements;
StreamReader sr = new StreamReader(data_file);
line = sr.ReadLine();
while (line != null)
{
elements = elements + 1;
line = sr.ReadLine();
}
sr.Close();
With this number I can now create an array of array by setting fist how many elements the array is going to hold. The array this time is going to hold the number from the file something like this:
datafile:
1,1
2,3
arrayL[0][0]=1
arrayL[0][1]=1
arrayL[1][0]=2
arrayL[1][0]=3
so the code to do this is the next:
double [][] dime= new double [elements][];
string[] div;
string line2;
int nn=0;
StreamReader ssr = new StreamReader(data_file);
line2 = ssr.ReadLine();
while (line2 != null)
{
dimen[nn] = new double[2];
for (int m2 = 0; m2 < 2; m2++)
{
div=line2.Split(new Char[] { ' ', ',', '\t' });
dimenc[nn][m2] = Convert.ToDouble(div[m2]);
}
nn=nn+1;
line2 = ssr.ReadLine();
}
ssr.Close();
However, the array says that it is empty but I know if I used the second part of the code in a complete diferrent method/ second button but if it is in the same method it does not work so my question is:
What's wrong? Why the second streamreader is not working?
Actually #NLemay comment is probably the better solution.
But in the case someone would need to read an uploaded file twice, you would need to cache the file in memory. Either read the stream into a byte[] or a MemoryStream then work your streamreader from that. You'll find that HttpPostedFile.InputStream.CanSeek is false, which is what you're trying to do.
For a byte[]:
HttpPostedFile uFile = uploadFile.PostedFile;
byte[] data = new byte[uFile.ContentLength];
uFile.InputStream.Read(data, 0, uFile.ContentLength);
For a MemoryStream look up a CopyStream method.
suppose this is my txt file:
line1
line2
line3
line4
line5
im reading content of this file with:
string line;
List<string> stdList = new List<string>();
StreamReader file = new StreamReader(myfile);
while ((line = file.ReadLine()) != null)
{
stdList.Add(line);
}
finally
{//need help here
}
Now i want to read data in stdList, but read only value every 2 line(in this case i've to read "line2" and "line4").
can anyone put me in the right way?
Even shorter than Yuck's approach and it doesn't need to read the whole file into memory in one go :)
var list = File.ReadLines(filename)
.Where((ignored, index) => index % 2 == 1)
.ToList();
Admittedly it does require .NET 4. The key part is the overload of Where which provides the index as well as the value for the predicate to act on. We don't really care about the value (which is why I've named the parameter ignored) - we just want odd indexes. Obviously we care about the value when we build the list, but that's fine - it's only ignored for the predicate.
You can simplify your file read logic into one line, and just loop through every other line this way:
var lines = File.ReadAllLines(myFile);
for (var i = 1; i < lines.Length; i += 2) {
// do something
}
EDIT: Starting at i = 1 which is line2 in your example.
Add a conditional block and a tracking mechanism inside of a loop. (The body of the loop is as follows:)
int linesProcessed = 0;
if( linesProcessed % 2 == 1 ){
// Read the line.
stdList.Add(line);
}
else{
// Don't read the line (Do nothing.)
}
linesProcessed++;
The line linesProcessed % 2 == 1 says: take the number of lines we have processed already, and find the mod 2 of this number. (The remainder when you divide that integer by 2.) That will check to see if the number of lines processed is even or odd.
If you have processed no lines, it will be skipped (such as line 1, your first line.) If you have processed one line or any odd number of lines already, go ahead and process this current line (such as line 2.)
If modular math gives you any trouble, see the question: https://stackoverflow.com/a/90247/758446
try this:
string line;
List<string> stdList = new List<string>();
StreamReader file = new StreamReader(myfile);
while ((line = file.ReadLine()) != null)
{
stdList.Add(line);
var trash = file.ReadLine(); //this advances to the next line, and doesn't do anything with the result
}
finally
{
}