Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从驱动器读取部分大文件_C#_File_Data Access - Fatal编程技术网

C# 从驱动器读取部分大文件

C# 从驱动器读取部分大文件,c#,file,data-access,C#,File,Data Access,我使用的是C#中的大文件(可能占可用内存的20%-40%),一次只需要将文件的一小部分加载到内存中(比如文件的1-2%)。我认为使用文件流是最好的选择,但是idk。我需要给出一个起始点(以字节为单位)和一个长度(以字节为单位),然后将该区域复制到一个字节[]。对文件的访问可能需要在线程之间共享,并且将在文件中的任意点进行(非线性访问)。我也需要它快一点 这个项目已经有了不安全的方法,所以请随意从C#更危险的方面提出建议。我对这些文件的结构一无所知,但是用FileStream或类似的方法读取一部分

我使用的是C#中的大文件(可能占可用内存的20%-40%),一次只需要将文件的一小部分加载到内存中(比如文件的1-2%)。我认为使用文件流是最好的选择,但是idk。我需要给出一个起始点(以字节为单位)和一个长度(以字节为单位),然后将该区域复制到一个字节[]。对文件的访问可能需要在线程之间共享,并且将在文件中的任意点进行(非线性访问)。我也需要它快一点


这个项目已经有了
不安全的
方法,所以请随意从C#

更危险的方面提出建议。我对这些文件的结构一无所知,但是用FileStream或类似的方法读取一部分文件听起来是最好、最快的方法

您不需要复制字节[],因为FileStream可以直接读取到字节数组中


听起来您可能更了解文件的结构,这也可能带来其他技术。但是,如果您只需要读取文件的一部分,那么这可能就是执行此操作的方法。

a
FileStream
将允许您查找所需的文件部分,没有问题。这是在C#中推荐的方法,而且速度很快

在线程之间共享:您需要创建一个锁,以防止其他线程在尝试读取文件流时更改文件流位置。最简单的方法是:

//  This really needs to be a member-level variable;
private static readonly object fsLock = new object();

//  Instantiate this in a static constructor or initialize() method
private static FileStream fs = new FileStream("myFile.txt", FileMode.Open);


public string ReadFile(int fileOffset) {

    byte[] buffer = new byte[bufferSize];

    int arrayOffset = 0;

    lock (fsLock) {
        fs.Seek(fileOffset, SeekOrigin.Begin);

        int numBytesRead = fs.Read(bytes, arrayOffset , bufferSize);

        //  Typically used if you're in a loop, reading blocks at a time
        arrayOffset += numBytesRead;
    }

    // Do what you want to the byte array and return it

}
根据需要添加
try..catch
语句和其他代码。无论您在何处访问此文件流,都要锁定成员级变量fsLock。。。这将防止其他方法在您尝试读取时读取/操作文件指针

就速度而言,我认为您会发现自己受到磁盘访问速度的限制,而不是代码的限制


您必须仔细考虑有关多线程文件访问的所有问题。。。谁初始化/打开文件,谁关闭文件,等等。有很多方面需要考虑。

如果您使用.Net 4,请在
System.IO.MemoryMappedFiles
命名空间中使用内存映射文件

它们非常适合从大文件中读取小块内容。有


您也可以在早期版本的.Net中执行此操作,但是您需要包装Win32 API(或使用),

@Hans:对。假设他知道去哪里,这就是实现的方法。[使用文件流]JOC,你要跳多少?即,在加载不同的1-2%之前,您将在内存中保留文件的1-2%多长时间?文件流速度很快,但您仍然会受到磁盘访问的影响。如果你能够预测需要加载的内容,你可能需要考虑一些缓存策略。我来看看:)@James我会在不同的时间段(我知道,最糟糕的情况)保留数据,因为一切都是基于用户输入的。虽然它与视频无关,但我认为非线性视频编辑软件的时间轴与我需要的时间轴相似。我很确定软件不会一次加载整个视频,但它能够相对快速地跳到视频剪辑的任何部分。我认为他应该有多个
FileStream
实例(每个线程一个),而不是使用锁定在线程之间共享。@Gabe,你能详细说明一下吗?如果你多次尝试对同一个文件进行流式处理,你不会得到IOExeption吗?@joe_coolish:只要你的文件是以共享(而不是独占)访问方式打开的,你就没有理由不能同时从多个流式处理访问它。Gabe是对的,只要你没有写入文件。请记住,打开并读取文件块的FileStream对象越多,将使用的内存就越多,您说过这是一个问题。还有多少取决于你的使用模式。。。当线程在文件指针处等待轮到它们时,使用锁平衡瓶颈将带来多少线程、您将如何重击此文件等。这是速度与内存的问题,你必须决定一个平衡你需求的策略。作为一名开发人员,60%的编码和40%的设计决策:)+1。非常有洞察力,这正是我想要的!这不意味着他的进程将为整个文件的大小分配虚拟内存吗?是的,我得出结论,每个人都在使用64位,分配内存空间不是问题。当然,在32位中这是一个问题,但您仍然可以使用mmf。只需分配文件中移动的较小部分。