Well I'm trying to write some values and strings to a text file.
but this text file must contain 2 bytes
These are the 2 bytes I want to insert to my text file after finishing writing the other values to it:
I tried this method but I have no idea how to write bytes through it
using (StreamWriter sw = new StreamWriter(outputFilePath, false, Encoding.UTF8))
I have no idea about how to write them to the text file after putting the strings I want on it.
I just figured this out. It works quite well for me. The idea is you open the file with a FileStream that can write byte arrays, and put a StreamWriter on top of it to write strings. And then you can use both to mix strings with your bytes:
// StreamWriter writer = new StreamWriter(new FileStream("file.txt", FileMode.OpenOrCreate));
byte[] bytes = new byte[] { 0xff, 0xfe };
writer.BaseStream.Write(bytes, 0, bytes.Length);
If I recall correctly from your question. You want to write strings to a file and then write bytes to it?
This example will do that for you:
using (FileStream fsStream = new FileStream("Bytes.data", FileMode.Create))
using (BinaryWriter writer = new BinaryWriter(fsStream, Encoding.UTF8))
{
// Writing the strings.
writer.Write("The");
writer.Write(" strings");
writer.Write(" I");
writer.Write(" want");
writer.Write(".");
// Writing your bytes afterwards.
writer.Write(new byte[]
{
0xff,
0xfe
});
}
When opening the "Bytes.data" file with a hex editor you should see these bytes:
Here is one more way to look for a solution...
StringBuilder sb = new StringBuilder();
sb.Append("Hello!! ").Append(",");
sb.Append("My").Append(",");
sb.Append("name").Append(",");
sb.Append("is").Append(",");
sb.Append("Rajesh");
sb.AppendLine();
//use UTF8Encoding(true) if you want to use Byte Order Mark (BOM)
UTF8Encoding utf8withNoBOM = new UTF8Encoding(false);
byte[] bytearray;
bytearray = utf8withNoBOM.GetBytes(sb.ToString());
using (FileStream fileStream = new FileStream(System.Web.HttpContext.Current.Request.MapPath("~/" + "MyFileName.csv"), FileMode.Append, FileAccess.Write))
{
StreamWriter sw = new StreamWriter(fileStream, utf8withNoBOM);
//StreamWriter for writing bytestream array to file document
sw.BaseStream.Write(bytearray, 0, bytearray.Length);
sw.Flush();
sw.Close();
fileStream.Close();
}
If I understand correctly, you're trying to write some strings to a text file, but you want to add 2 bytes to this file.
Why won't you try using: File.WriteAllBytes ?
Convert your string to a Byte array using
byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(str); // If your using UTF8
Create a new byte array from the original byteArray with the additional 2 bytes.
And write them to a file using:
File.WriteAllBytes("MyFile.dat", newByteArray)
There is a StreamWriter.Write(char) that will write a 16-bit value. You should be able to set your variable with the hex value like char val = '\xFFFE' and pass it to Write. You could also use FileStream where all the Write methods work off bytes, and it specifically has a WriteByte(byte) method. The MSDN documentation for it gives an example of outputting UTF8 text.
After saving the string simply write those bytes using for example using File.WriteAllBytes or a BinaryWriter:
Can a Byte[] Array be written to a file in C#?
Related
From what I understand, the Formatter converts a serializable object into a stream of bytes and the Stream (e.g. FileStream) does the actual writing of those bytes into a file. Example code:
public static void SaveData(MySerializableData data)
{
BinaryFormatter formatter = new BinaryFormatter();
FileStream stream = new FileStream(SavePath, FileMode.Create);
formatter.Serialize(stream, data);
stream.Close();
}
However at other times, I'm also seeing this type of code:
void Save()
{
string data = "Value 1";
StreamWriter writer = new StreamWriter("MySaveFile.txt", true);
writer.Write(data);
}
Why is it that in the second case, we abandon the 2-step process of saving? Why do we sometimes use only StreamWriter, but at other times use both the formatter and a stream object?
Thank you!
BinaryFormatter serializes a class into a byte array and writes it to a stream. It's useful when you want to save/load classes with it's data. Serializtion stores metadata about the class graph that is storing.
StreamWriter is a stream that has specific functions to write a string into a file.
Consider this example:
MemoryStream mstr = new MemoryStream();
string datastr = "hello!";
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(mstr, datastr);
mstr.Seek(0, SeekOrigin.Begin);
string resultString = Encoding.ASCII.GetString(mstr.ToArray());
If you inspect resultString you will find that it contains something like this:
"\0\u0001\0\0\0????\u0001\0\0\0\0\0\0\0\u0006\u0001\0\0\0\u0006hello!\v"
Well, that's not what you would want to have in a text file, right? As you see serialization is not intended to store raw data but class instances.
Now check this:
MemoryStream mstr = new MemoryStream();
StreamWriter sw = new StreamWriter(mstr);
string datastr = "hello!";
sw.Write(datastr);
mstr.Seek(0, SeekOrigin.Begin);
sw.Close();
string resultString = Encoding.ASCII.GetString(mstr.ToArray());
If you now inspect resultString it will contain:
"hello!"
As you see it's very different, that's what you would expect in a text file.
You can also store raw binary data with a stream:
byte[] data = new byte[]{ 1,2,3,4 };
var fs = File.Create("out.dat"); //this creates a new file and creates a filestream
fs.Write(data, 0, data.Length);
fs.Close();
If you now inspect the file with a binary editor you will see it contains:
0x01, 0x02, 0x03, 0x04
There are many types of streams with different purposes (per example, the MemoryStream that I used in the examples, a binary stream that stores it's data into an array in memory) and a ton of classes that use streams for many things, in this case you have mixed the concepts of serialization and data storage using streams, those are two different things.
If i read byte array from a file and write it using below code
byte[] bytes = File.ReadAllBytes(filePath);
File.WriteAllBytes(filePath, byteArr);
works perfectly fine.I can open and view the written file properly.
But if i read file contents into a string and then convert it to byte array using below function
string s = File.ReadAllText(filePath);
var byteArr = System.Text.Encoding.UTF8.GetBytes(s);
the size of byte array is more than the previous array read directly from file and the values are also different, hence if i write the file using this array the cannot be read when opened
Note:- File is utf-8 encoded
i found out that using below code
using (StreamReader reader = new StreamReader(filePath, Encoding.UTF8, true))
{
reader.Peek(); // you need this!
var encoding = reader.CurrentEncoding;
}
Unable to understand why both the array differs??
I was using the below attached image for converting and then writing
With
using (StreamReader reader = new StreamReader(filePath, Encoding.UTF8, true))
{
reader.Peek(); // you need this!
var encoding = reader.CurrentEncoding;
}
your var encoding will just echo the Encoding.UTF8 parameter. You are deceiving yourself there.
A binary file just has no text encoding.
Need to save a file may be anything an image or a text
Then just use ReadAllBytes/WriteAllBytes. A text file is always also a byte[], but not all file types are text. You would need Base64 encoding first and that just adds to the size.
The safest way to convert byte arrays to strings is indeed encoding it in something like base64.
Like:
string s= Convert.ToBase64String(bytes);
byte[] bytes = Convert.FromBase64String(s);
I have a file with size 10124, I am adding a byte array, which has length 4 in the beginning of the file.
After that the file size should become 10128, but as I write it to file, the size decreased to 22 bytes. I don't know where is the problem
public void AppendAllBytes(string path, byte[] bytes)
{
var encryptedFile = new FileStream(path, FileMode.Open, FileAccess.Read);
////argument-checking here.
Stream header = new MemoryStream(bytes);
var result = new MemoryStream();
header.CopyTo(result);
encryptedFile.CopyTo(result);
using (var writer = new StreamWriter(#"C:\\Users\\life.monkey\\Desktop\\B\\New folder (2)\\aaaaaaaaaaaaaaaaaaaaaaaaaaa.docx.aef"))
{
writer.Write(result);
}
}
How can I write bytes to the file?
The issue seems to be caused by:
using a StreamWriter to write binary formatted data. The name does not inthuitively suggest this, but the StreamWriter class is suited for writing textual data.
passing an entire stream instead of the actual binary data. To obtain the bytes stored in a MemoryStream, use its convenient ToArray() method.
I suggest you the following code:
public void AppendAllBytes(string path, byte[] bytes)
{
var fileName = #"C:\\Users\\life.monkey\\Desktop\\B\\New folder (2)\\aaaaaaaaaaaaaaaaaaaaaaaaaaa.docx.aef";
using (var encryptedFile = new FileStream(path, FileMode.Open, FileAccess.Read))
using (var writer = new BinaryWriter(File.Open(fileName, FileMode.Append)))
using (var result = new MemoryStream())
{
encryptedFile.CopyTo(result);
result.Flush(); // ensure header is entirely written.
// write header directly, no need to put it in a memory stream
writer.Write(bytes);
writer.Flush(); // ensure the header is written to the result stream.
writer.Write(result.ToArray());
writer.Flush(); // ensure the encryptdFile is written to the result stream.
}
}
The code above uses the BinaryWriter class which is better suited for binary data. It has a Write(byte[] bytes) method overload that is used above to write an entire array to the file. The code uses regular calls to the Flush() method that some may consider not needed, but these guarantee in general, that all the data written prior the call of the Flush() method is persisted within the stream.
Just started with writing unit tests and I am now, blocked with this situation:
I have a method which has a FileStream object and I am trying to pass a "string" to it.
So, I would like to convert my string to FileStream and I am doing this:
File.WriteAllText(string.Concat(Environment.ExpandEnvironmentVariables("%temp%"),
#"/test.txt"), testFileContent); //writes my string to a temp file!
new FileStream(string.Concat(Environment.ExpandEnvironmentVariables("%temp%"),
#"/test.txt"), FileMode.Open) //open that temp file and uses it as a fileStream!
close the file then!
But, I guess there must be some very simple alternative to convert a string to a fileStream.
Suggestions are welcome! [Note there are other answers to this question in stackoverflow but none seems to be a straight forward solution to that]
Thanks in advance!
First of all change your method to allow Stream instead of FileStream. FileStream is an implementation which, as I remember, does not add any methods or properties, just implement abstract class Stream. And then using below code you can convert string to Stream:
public Stream GenerateStreamFromString(string s)
{
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.Write(s);
writer.Flush();
stream.Position = 0;
return stream;
}
As FileStream class provides a stream for a file and hence it's constructor requires the path of the file,mode, permission parameter etc. to read the file into stream and hence it is used to read the text from file into stream. If we need to convert string to stream first we need to convert string to bytes array as stream is a sequence of bytes. Below is the code.
//Stream is a base class it holds the reference of MemoryStream
Stream stream = new MemoryStream();
String strText = "This is a String that needs to beconvert in stream";
byte[] byteArray = Encoding.UTF8.GetBytes(strText);
stream.Write(byteArray, 0, byteArray.Length);
//set the position at the beginning.
stream.Position = 0;
using (StreamReader sr = new StreamReader(stream))
{
string strData;
while ((strData= sr.ReadLine()) != null)
{
Console.WriteLine(strData);
}
}
I want to read an exe file in my C# code then decode as base64.
I am doing it like this
FileStream fr = new FileStream(#"c:\1.exe", FileMode.Open, FileAccess.Read, FileShare.Read);
StreamReader sr = new StreamReader(fr);
fr.Read(data, 0, count);
But the problem is that when I write this file the written file gets corrupted.
When analyzing in hex workshop code value 20 in hex is being replaced by 0.
A StreamReader should be used only with text files. With binary files you need to use directly a FileStream or:
byte[] buffer = File.ReadAllBytes(#"c:\1.exe");
string base64Encoded = Convert.ToBase64String(buffer);
// TODO: do something with the bas64 encoded string
buffer = Convert.FromBase64String(base64Encoded);
File.WriteAllBytes(#"c:\2.exe", buffer);
StreamReader official docs:
"Implements a TextReader that reads characters from a byte stream in a particular encoding."
It's for text, not binary files. Try just Stream or BinaryReader.. (Why did you try a StreamReader?)