I have got a text file which name is "file.txt".
There is binary text like "11100100100" in that file and I am trying to read the file and convert the binary into a bytearray.
When I run the code it converts to ascii characters. Btw i am just checking the code from break points. I saw ASCII characters from there.
Here is the code
String^ fileName = "file.txt";
FileStream^ fs = gcnew FileStream(fileName, FileMode::Open);
BinaryReader^ br = gcnew BinaryReader(fs);
INT32 tmpInd = 0;
array<Byte^>^ byteArr = gcnew array<Byte^>(br->BaseStream->Length);
while(br->BaseStream->Position < br->BaseStream->Length){
byteArr[tmpInd] = br->ReadByte();
tmpInd++;
}
fs->Close();
Related
So I need to read a file that has a 'word' inside in hex (ACSII). Of course words can be of any length, but always starts at offset 0x1290. What I am trying to do is read the hex of a file starting at offset 0x1290, and continue UNTIL it encounters a null byte (00). So far all the coding I have tried seems to need a fixed length to read.
filePath = "C:\myfile"
BinaryReader reader = new BinaryReader(new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None));
reader.BaseStream.Position = 0x1290; // The starting offset
byte[] word = reader.ReadBytes(); // Must specify length within ReadBytes(e.g. 0x99)
reader.Close();`
After the required 'word' there can often be other hex data which is not required, however there is always a null byte after the 'word'. This is why I cannot specify a length.
use while loop:
filePath = "C:\myfile"
BinaryReader reader = new BinaryReader(new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None));
reader.BaseStream.Position = 0x1290;
byte char;
byte[] result=new byte[length_of_the_word];
int i=0;
while(((byte)char=reader.Read())!=-1)
{
result[i++]=char;
}
reader.close();
then replace -1 (end of file) with the end word hex, like 0x00
If you don't know how many chars is the length of your string you should use some kind of collection that doesn't require beforehand the exact length of data to store. This seems the perfect work for a List<byte>
List<byte> bits = new List<byte>();
using(FileStream s = new FileStream(#"C:\myfile", FileMode.Open))
using (BinaryReader reader = new BinaryReader(s))
{
reader.BaseStream.Position = 0x1290;
while (reader.PeekChar() != -1)
{
byte b = reader.ReadByte();
if(b != 0x00)
bits.Add(reader.ReadByte());
}
string result = Encoding.UTF8.GetString(bits.ToArray());
}
Thanks guys, I tried the above mentioned, but they seem to keep coming up with errors. Anyway I figured out a loop myself and am here to share:
int c = 0;
int runs = 0;
byte[] data = new byte[400]; // byte array setup
// read hex values (loop) and convert to acsii string
BinaryReader reader = new BinaryReader(new FileStream("C:\File", FileMode.Open, FileAccess.Read, FileShare.None));
reader.BaseStream.Position = 0x1290;
while (c == 0)
{
data[runs] = reader.ReadByte();
if (data[runs] == 0x00)
{
c = 1; // stop loop at .ReadByte = 0x00
}
runs++;
}
reader.Close();
// hex to acsii string, removing null bytes
result = Encoding.Default.GetString(data.Where(x => x != 0).ToArray());
Seems to work well
I am trying to write a program that transfers a file through sound (kind of like a fax). I broke up my program into several steps:
convert file to binary
convert 1 to a certain tone and 0 to another
play the tones to another computer
other computer listens to tones
other computer converts tones into binary
other computer converts binary into file.
However, I can't seem to find a way to convert a file to binary. I found a way to convert a string to binary using
public static string StringToBinary(string data)
{
StringBuilder sb = new StringBuilder();
foreach (char c in data.ToCharArray())
{
sb.Append(Convert.ToString(c, 2).PadLeft(8,'0'));
}
return sb.ToString();
}
From http://www.fluxbytes.com/csharp/convert-string-to-binary-and-binary-to-string-in-c/ .
But I can't find out how to convert a file to binary (the file could be of any extension).
So, how can I convert a file to binary? Is there a better way for me to write my program?
Why don't you just open the file in binary mode?
this function opens the file in binary mode and returns the byte array:
private byte[] GetBinaryFile(filename)
{
byte[] bytes;
using (FileStream file = new FileStream(filename, FileMode.Open, FileAccess.Read))
{
bytes = new byte[file.Length];
file.Read(bytes, 0, (int)file.Length);
}
return bytes;
}
then to convert it to bits:
byte[] bytes = GetBinaryFile("filename.bin");
BitArray bits = new BitArray(bytes);
now bits variable holds 0,1 you wanted.
or you can just do this:
private BitArray GetFileBits(filename)
{
byte[] bytes;
using (FileStream file = new FileStream(filename, FileMode.Open, FileAccess.Read))
{
bytes = new byte[file.Length];
file.Read(bytes, 0, (int)file.Length);
}
return new BitArray(bytes);
}
Or even shorter code could be:
private BitArray GetFileBits(filename)
{
byte[] bytes = File.ReadAllBytes(filename);
return new BitArray(bytes);
}
I'm trying to differentiate between "text files" and "binary" files, as I would effectively like to ignore files with "unreadable" contents.
I have a file that I believe is a GZIP archive. I'm tring to ignore this kind of file by detecting the magic numbers / file signature. If I open the file with the Hex editor plugin in Notepad++ I can see the first three hex codes are 1f 8b 08.
However if I read the file using a StreamReader, I'm not sure how to get to the original bytes..
using (var streamReader = new StreamReader(#"C:\file"))
{
char[] buffer = new char[10];
streamReader.Read(buffer, 0, 10);
var s = new String(buffer);
byte[] bytes = new byte[6];
System.Buffer.BlockCopy(s.ToCharArray(), 0, bytes, 0, 6);
var hex = BitConverter.ToString(bytes);
var otherhex = BitConverter.ToString(System.Text.Encoding.UTF8.GetBytes(s.ToCharArray()));
}
At the end of the using statement I have the following variable values:
hex: "1F-00-FD-FF-08-00"
otherhex: "1F-EF-BF-BD-08-00-EF-BF-BD-EF-BF-BD-0A-51-02-03"
Neither of which start with the hex values shown in Notepad++.
Is it possible to get the original bytes from the result of reading a file via StreamReader?
Your code tries to change a binary buffer into a string. Strings are Unicode in NET so two bytes are required. The resulting is a bit unpredictable as you can see.
Just use a BinaryReader and its ReadBytes method
using(FileStream fs = new FileStream(#"C:\file", FileMode.Open, FileAccess.Read))
{
using (var reader = new BinaryReader(fs, new ASCIIEncoding()))
{
byte[] buffer = new byte[10];
buffer = reader.ReadBytes(10);
if(buffer[0] == 31 && buffer[1] == 139 && buffer[2] == 8)
// you have a signature match....
}
}
Usage (for a pdf file):
Assert.AreEqual("25504446", GetMagicNumbers(filePath, 4));
Method GetMagicNumbers:
private static string GetMagicNumbers(string filepath, int bytesCount)
{
// https://en.wikipedia.org/wiki/List_of_file_signatures
byte[] buffer;
using (var fs = new FileStream(filepath, FileMode.Open, FileAccess.Read))
using (var reader = new BinaryReader(fs))
buffer = reader.ReadBytes(bytesCount);
var hex = BitConverter.ToString(buffer);
return hex.Replace("-", String.Empty).ToLower();
}
You can't. StreamReader is made to read text, not binary. Use the Stream directly to read bytes. In your case FileStream.
To guess whether a file is text or binary you could read the first 4K into a byte[] and interpret that.
Btw, you tried to force chars into bytes. This is invalid by principle. I suggest you familiarize yourself with what an Encoding is: it is the only way to convert between chars and bytes in a semantically correct way.
Basically I need to convert text in a textbox from UTF-8 to base16 (I think that is what hex is in) and write it to a file.
This but back words:
//Setup byte reader.
FileStream fs = new FileStream(EditOpen.FileName, FileMode.Open);
BinaryReader br = new BinaryReader(fs);
long length = fs.Length;
//Read bytes to textBox1.
br.BaseStream.Position = 0x00001844; //Min loading address.
byte[] PT = br.ReadBytes(0x00000428); //Amount of bytes to load (1064 to be exact).
//Print string PT to textBox1 after converting to UTF-8 and replace 0's with DOT's.
textBox1.Text = System.Text.Encoding.UTF8.GetString(PT).Replace("\0", ".");
fs.Close();
The easiest way is to use a StreamWriter created with the correct encoding
using(StreamWriter sw =
new System.IO.StreamWriter(fs,
System.Text.UTF8Encoding))
{
sw.Write(textBox1.Text);
}
I have a huge text file, size > 4GB and I want to replace some text in it programmatically. I know the line number at which I have to replace the text but the problem is that I do not want to copy all the text (along with my replaced line) to a second file. I have to do this within the source file. Is there a way to do this in C#?
The text which has to be replaced is exactly the same size as the source text (if this helps).
Since the file is so large you may want to take a look at the .NET 4.0 support for memory mapped files. Basically you'll need to move the file/stream pointer to the location in the file, overwrite that location, then flush the file to disk. You won't need to load the entire file into memory.
For example, without using memory mapped files, the following will overwrite a part of an ascii file. Args are the input file, the zero based start index and the new text.
static void Main(string[] args)
{
string inputFilename = args[0];
int startIndex = int.Parse(args[1]);
string newText = args[2];
using (FileStream fs = new FileStream(inputFilename, FileMode.Open, FileAccess.Write))
{
fs.Position = startIndex;
byte[] newTextBytes = Encoding.ASCII.GetBytes(newText);
fs.Write(newTextBytes, 0, newTextBytes.Length);
}
}
Unless the new text is exactly the same size as the old text, you will have to re-write the file. There is no way around it. You can at least do this without keeping the entire file in memory.
Hello I tested the following -works well.This caters to variable length lines separated by Environment.NewLine. if you have fixed length lines you can straightaway seek to it.For converting bytes to string and vice versa you can use Encoding.
static byte[] ReadNextLine(FileStream fs)
{
byte[] nl = new byte[] {(byte) Environment.NewLine[0],(byte) Environment.NewLine[1] };
List<byte> ll = new List<byte>();
bool lineFound = false;
while (!lineFound)
{
byte b = (byte)fs.ReadByte();
if ((int)b == -1) break;
ll.Add(b);
if (b == nl[0]){
b = (byte)fs.ReadByte();
ll.Add(b);
if (b == nl[1]) lineFound = true;
}
}
return ll.Count ==0?null: ll.ToArray();
}
static void Main(string[] args)
{
using (FileStream fs = new FileStream(#"c:\70-528\junk.txt", FileMode.Open, FileAccess.ReadWrite))
{
int replaceLine=1231;
byte[] b = null;
int lineCount=1;
while (lineCount<replaceLine && (b=ReadNextLine(fs))!=null ) lineCount++;//Skip Lines
long seekPos = fs.Position;
b = ReadNextLine(fs);
fs.Seek(seekPos, 0);
string line=new string(b.Select(x=>(char)x).ToArray());
line = line.Replace("Text1", "Text2");
b=line.ToCharArray().Select(x=>(byte)x).ToArray();
fs.Write(b, 0, b.Length);
}
}
I'm guessing you'll want to use the FileStream class and seek to your positon, and place your updated data.