如何将字节数组读入FileStream中

19

我有一个byte数组,想将它读入FileStream中。以下是我的代码示例:

string fileName = "test.txt";
byte[] file = File.ReadAllBytes(Server.MapPath("~/Files/" + fileName));
FileStream fs = new FileStream();
fs.ReadByte(file);
object obj = LoadFile<object>(fs);

public static T LoadFile<T>(FileStream fs)
{
    using (GZipStream gzip = new GZipStream(fs, CompressionMode.Decompress))
    {
        BinaryFormatter bf = new BinaryFormatter();
        return (T)bf.Deserialize(gzip);
    }
}

在上述方法中,我使用了FileStream来读取字节数组,但不幸的是fs.ReadByte无法读取字节数组。请帮忙解决如何将字节数组读入FileStream中,以便作为“LoadFile”方法的参数使用。请不要直接将文件读入FileStream中,因为这里的文件是从其他地方加载的,比如从数据库或其他来源。

为什么不使用MemoryStream而不是FileStream? - Tomtom
MemoryStream可以在LoadFile方法中用作FileStream吗? - Tri Nguyen Dung
你的代码编译怎么样了?FileStream 的构造函数不接受0个参数。 - sa_ddam213
4个回答

20
string fileName = "test.txt";
byte[] file = File.ReadAllBytes(Server.MapPath("~/Files/" + fileName));
MemoryStream memStream = new MemoryStream();
BinaryFormatter binForm = new BinaryFormatter();
memStream.Write(file, 0, file.Length);
memStream.Seek(0, SeekOrigin.Begin);
Object obj = (Object)binForm.Deserialize(memStream);

你的方法使用了 memStream,但是在运行代码时我遇到了一个错误。它说:"输入流不是有效的二进制格式。起始内容(以字节为单位)如下:1F-8B-08-00-00-00-00-00-04-00-ED-BD-07-60-1C-49-96",这发生在 Object obj = (Object)binForm.Deserialize(memStream); 这一行。 - Tri Nguyen Dung
目前,我正在使用以下代码获取文件:byte[] file; using (var stream = new FileStream(Server.MapPath("~/Files/" + fileName), FileMode.Open, FileAccess.Read)) { using (var reader = new BinaryReader(stream)) { file = reader.ReadBytes((int)stream.Length); } } - Tri Nguyen Dung
如果您的文件已经被压缩,我假设是因为使用了GZipStream,那么这很可能就是为什么它无法正常工作的原因。 - juharr
我已经分析了我的代码,并得出了与您想法相同的结论。因此,我已经发布了我的新代码以寻求更多帮助。如果您也遇到了类似问题,请帮助我解决。 - Tri Nguyen Dung

9

我不确定误解出在哪里。FileStream代表磁盘上的文件。您不能“将字节读入其中”而不将它们写入磁盘,也不能从中读取而不从磁盘读取。

也许您需要的是MemoryStream,它可以包含任意内容。

两者都派生自Stream。


是的,我已经说过FileStream不能直接读取字节。如果MemoryStream可以包含字节数组,那么我该如何在我的方法“LoadFile”中使用它呢? - Tri Nguyen Dung
1
要么将 LoadFile 改为接受一个 Stream,要么将您的 byte 数组写入文件并从中创建一个 FileStream - juharr
利用它们都源自Stream的事实,因此您可以传递任何流。您即将体验到继承的有用性 :) - usr
如果我将字节数组写入文件,然后将文件读回到FileStream中,那么如果文件仅存在于数据库中而不在服务器上的任何驱动器上,该如何读取文件? - Tri Nguyen Dung
1
如果你不想将字节数组写入文件再去读取它,实际上这是我两个选项中比较糟糕的一个。那么你只需要改变 LoadFile 的参数类型,使其接收一个 Stream 而不是一个 FileStream,然后在一个 MemoryStream 中加载字节数组并传递它即可。 - juharr
这正是我现在在我的代码中正在做的。使用MemoryStream将字节数组写入其中,然后将其传递给对象。但目前我卡在了传递MemoryStream上。似乎字节数组没有正确的格式。 - Tri Nguyen Dung

2

是的!经过进一步研究,我得到了一个好的解决方案。就我发布的主题“如何将字节数组读入FileStream”而言。我们不能将字节数组读入FileStream,它只用于从驱动器上读取文件到字节数组中。因此,我对我的代码进行了一些改动,现在我有一个文件可以使用FileStream读取它。我如何制作一个文件?

在这个情境中,我有一个对象。该对象可以是任何您想要的东西!

我使用一个集合作为示例对象。

Collection<object> list = new Collection<object>();
//Now I will write this list to a file. fileName is what you want and be sure that folder Files is exist on server or at the root folder of your project
WriteFile(list, Server.MapPath("~/Files/" + fileName));
//The method to write object to file is here
public static void WriteFile<T>(T obj, string path)
{
    FileStream serializeStream = new FileStream(path, FileMode.Create);
    BinaryFormatter bf = new BinaryFormatter();
    bf.Serialize(serializeStream, obj);
    serializeStream.Flush();
    serializeStream.Close();
}

在我将对象写入文件后,需要一种方法将其读回对象。所以我编写了以下方法:

public static Collection<object> ReatFile(string fileName){
            //I have to read the file which I have wrote to an byte array            
            byte[] file;
            using (var stream = new FileStream(Server.MapPath("~/Files/" + fileName), FileMode.Open, FileAccess.Read))
            {
                using (var reader = new BinaryReader(stream))
                {
                    file = reader.ReadBytes((int)stream.Length);

                }

            }
            //And now is what I have to do with the byte array of file is to convert it back to object which I have wrote it into a file
            //I am using MemoryStream to convert byte array back to the original object.
            MemoryStream memStream = new MemoryStream();
            BinaryFormatter binForm = new BinaryFormatter();
            memStream.Write(file, 0, file.Length);
            memStream.Seek(0, SeekOrigin.Begin);
            Object obj = (Object)binForm.Deserialize(memStream);
            Collection<object> list = (Collection<object>)obj;
            return list;
}

在完成上述步骤后,我现在能够将任何类型的对象写入文件,然后将其读回原始对象。非常感谢我在那里得到的任何帮助。


0
为什么在使用 FileStream 之前要运行 File.ReadAllBytes
string fileName = "test.txt";
using(FileStream fs = new FileStream(Server.MapPath("~/Files/" + fileName), FileMode.Open, FileAccess.Read))
{
    object obj = LoadFile<object>(fs);
    fs.Close();
}

在我的问题中,我已经提到了字节数组并没有从服务器上的任何文件中读取。它只是一个我从数据库或其他来源得到的字节数组。因此,请不要直接将文件读入FileStream中。 - Tri Nguyen Dung
为什么要“请不要直接将文件读入FileStream”?您正在使用“Server.MapPath(〜/Files/+ fileName)”从磁盘上读取文件。如果您不打算在磁盘上读取任何文件,请勿对其使用FileStream。 - Freddie Fabregas
你说得对。我只有一个字节数组,它没有从任何文件中加载。所以你能帮我吗?因为方法“LoadFile”需要一个FileStream,而我只有来自数据库的字节数组。那么我该如何将它用于我的方法“LoadFile”呢? - Tri Nguyen Dung

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接