从sharepoint数据库中提取文件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从sharepoint数据库中提取文件相关的知识,希望对你有一定的参考价值。

我试图在C#中创建一个小程序来从Sharepoint数据库中提取文件。我从在线搜索中获取了代码,我正在尝试编辑它,以便在保持Sharepoint数据库中的文件夹的同时将文件解压缩到特定文件夹。

具体来说,我希望用户从表单中输入服务器的名称,他们尝试从中提取文件的数据库的名称,最后是他们希望用来提取文件的路径。

我调试时收到错误。

错误说明:Could not find a part of the path: 关于这行代码:

FileStream fs = new FileStream(txtdir.Text + "/" + DirName + "/" + LeafName,
FileMode.Create, FileAccess.Write);

这是我的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.IO;

namespace SPEXTRACTOR
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
    }

    private void ENTER_Click(object sender, EventArgs e)
    {
      string DBConnString = "Server=" + txtserver.Text + ";Database=" 
                            + txtDB.Text + ";Trusted_Connection=True;";
      SqlConnection con = new SqlConnection(DBConnString);
      con.Open();

      SqlCommand com = con.CreateCommand();
      com.CommandText = "SELECT ad.SiteId, ad.Id, ad.DirName," +
          " ad.LeafName, ads.Content" +
          " FROM AllDocs ad, AllDocStreams ads" +
          " WHERE ad.SiteId = ads.SiteId" +
          " AND ad.Id = ads.Id" +
          " AND ads.Content IS NOT NULL" +
          " Order by DirName";


      //SqlCommand com = con.CreateCommand();
      //com.CommandText = "select DirName, LeafName, Content 
        from AllDocStreams, AllDocs 
        where (LeafName like '%.doc' or LeafName like '%.xls' 
               or LeafName like '%.pdf' or LeafName like '%.ppt') 
               and Content is not NULL";


      //com.CommandText = "select DirName, LeafName, Content 
        from AllDocStreams, AllDocs 
        where (LeafName like '%.doc' or LeafName like '%.xls' 
               or LeafName like '%.pdf' or LeafName like '%.ppt') 
               and Content is not NULL";


      SqlDataReader reader = com.ExecuteReader();

      while (reader.Read())
      {
        // grab the file's directory and name
        string DirName = (string)reader["DirName"];
        string LeafName = (string)reader["LeafName"];

        if (!Directory.Exists(DirName))
        {
          Directory.CreateDirectory(DirName);
          Console.WriteLine("Creating directory: " + DirName);
        }

        //FileStream fs = new FileStream(DirName + "/" + LeafName
                              , FileMode.Create, FileAccess.Write);
        FileStream fs = new FileStream(txtdir.Text + "/" + DirName + "/" 
                          + LeafName, FileMode.Create, FileAccess.Write);

        BinaryWriter writer = new BinaryWriter(fs);

        // depending on the speed of your network, 
        //you may want to change the buffer size (it's in bytes)
        int bufferSize = 1000000;
        long startIndex = 0;
        long retval = 0;
        byte[] outByte = new byte[bufferSize];

        // grab the file out of the db one chunk (of size bufferSize) at a time
        do
        {
          retval = reader.GetBytes(4, startIndex, outByte, 0, bufferSize);
          //retval = reader.GetBytes(2, startIndex, outByte, 0, bufferSize);
          startIndex += bufferSize;

          writer.Write(outByte, 0, (int)retval);
          writer.Flush();
        } while (retval == bufferSize);

        // finish writing the file
        writer.Close();
        fs.Close();

        Console.WriteLine("Finished writing file: " + LeafName);
      }

      // close the DB connection and whatnots
      reader.Close();
      con.Close();   
    }                   
  }
}
答案

这是用于从WSS3数据库(即MDF文件)中提取文件的整个DoxoEater2程序,但必须在MS SQL中安装。

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.IO;

namespace DoxoEater2
{
    class Program
    {
        static void Main(string[] args)
        {

            // WSS 3.0 default DB via SQL 2005 embedded edition.
            //string DBConnString = "Data Source=\\.\pipe\MSSQL$MICROSOFT##SSEE\sql\query;Database=WSS_Content;Trusted_Connection=yes;Timeout=2000;MultipleActiveResultSets=True";

            // Or localhost, WSS_Content, typical SQL connection style, TCP/IP listener.
            string DBConnString = "Data Source=localhost;Database=WSS_Content;Trusted_Connection=yes;Timeout=2000;MultipleActiveResultSets=True";
            string DocsQuery = "select [AllDocs].[Id], [AllDocs].[DirName], [AllDocs].[LeafName] from [AllDocs] where dirname <> '' order by dirname;";

            Console.WriteLine("START: " + DateTime.Now.ToUniversalTime() + " UTC");

            SqlConnection con;

            try // create a DB connection
            {   
                con = new SqlConnection(DBConnString);
                con.Open();
            }
            catch (Exception e) {
                Console.WriteLine(e.Message);
                return;
            }

            SqlCommand com = con.CreateCommand();
            com.CommandText = DocsQuery;

            // readers for SQL queries: 1) which docs? 2) featch binary data per DocID
            SqlDataReader reader, reader2;

            try {   // execute query
                reader = com.ExecuteReader();
            }
            catch (Exception e) {
                if (con != null) { con.Close(); }
                Console.WriteLine(e.Message); 
                return;
            }

            while (reader.Read()) { // rows of document ID, name and directory nodes

                // grab the file's directory and name
                Guid FileId = (Guid)reader["Id"];
                string DirName = (string)reader["DirName"];
                string LeafName = (string)reader["LeafName"];

                // create directory for the file if it doesn't yet exist
                if (!Directory.Exists(DirName))
                {
                    Directory.CreateDirectory(DirName);
                    Console.WriteLine("DIR: " + DirName);
                }

                // check if file already exists or not
                if (File.Exists(DirName + "/" + LeafName)) {
                    Console.WriteLine("ERROR: File Already Exists: " + DirName + "/" + LeafName);
                    continue;
                }

                SqlCommand com2 = con.CreateCommand();
                com2.CommandText = "select content from [AllDocStreams]  where  [AllDocStreams].[Id] = '" + FileId.ToString() + "';";
                Console.WriteLine("SQL: " + com2.CommandText.ToString());

                try
                {   // execute file fetch query
                    reader2 = com2.ExecuteReader(CommandBehavior.SequentialAccess);
                }
                catch (Exception e)
                {
                    if (con != null) { con.Close(); }
                    Console.WriteLine(e.Message);
                    return;
                }

                while(reader2.Read()) {

                    // create a filestream to spit out the file
                    FileStream fs = new FileStream(DirName + "/" + LeafName, FileMode.Create, FileAccess.Write);
                    BinaryWriter writer = new BinaryWriter(fs);


                    // depending on the speed of your network, you may want to change the buffer size (it's in bytes)
                    int bufferSize = 1048576;
                    long startIndex = 0;
                    long retval = 0;
                    byte[] outByte = new byte[bufferSize];

                    // grab the file out of the db one chunk (of size bufferSize) at a time
                    do
                    {
                        retval = reader2.GetBytes(0, startIndex, outByte, 0, bufferSize);
                        startIndex += bufferSize;

                        writer.Write(outByte, 0, (int)retval);
                        writer.Flush();
                    } while (retval == bufferSize);

                    // finish writing the file
                    Console.WriteLine("FILE: " + LeafName);
                    writer.Close();
                    fs.Close();

                }
                reader2.Close();

            }

            // close the DB connection and whatnots
            reader.Close();
            con.Close();

            Console.WriteLine("DONE: " + DateTime.Now.ToUniversalTime() + " UTC");
        }
    }
}
另一答案

相同的PowerShell:

$Server="localhost"
$db="WSSContent"
$LocalDir="C:xyz"

$sql = "SELECT ad.SiteId, ad.Id, ad.DirName,
 ad.LeafName, ads.Content
 FROM AllDocs ad, AllDocStreams ads
 WHERE ad.SiteId = ads.SiteId
 AND ad.Id = ads.Id
 AND ads.Content IS NOT NULL
 AND ad.LeafName like '%aspx'
 Order by DirName";


$connectionString = "Data Source=$Server;Integrated Security=true;Initial Catalog=$db;Connect Timeout=3;"
$con = new-object ("Data.SqlClient.SqlConnection") $connectionString

$con.Open();
$cmd = $con.CreateCommand();
$cmd.CommandText = $sql;
$reader = $cmd.ExecuteReader();

while ($reader.Read())
{
    # grab the file's directory and name
    $DirName = [string]$reader["DirName"];
    $LeafName = [string]$reader["LeafName"];

    if (-not [System.IO.Directory]::Exists("$LocalDir$DirName"))
    {
        [System.IO.Directory]::CreateDirectory("$LocalDir$DirName");
        Write-Host "Creating directory: $LocalDir$DirName"
    }

    $fs = New-Object IO.FileStream "$LocalDir$DirName$LeafName" ,'Create','Write','Read';

    $writer = new-object "System.IO.BinaryWriter" $fs;

    # depending on the speed of your network, 
    #you may want to change the buffer size (it's in bytes)
    $bufferSize = 1000000;
    $startIndex = 0;
    $retval = 0;
    $out = [array]::CreateInstance('Byte', $bufferSize) 
    #
    ## grab the file out of the db one chunk (of size bufferSize) at a time
    Write-Host "Writing to $LocalDir$DirName$LeafName"
    Do{
      $retval = $reader.GetBytes(4, $startIndex, $out, 0, $bufferSize);
      $startIndex += $bufferSize;

      $writer.Write($out, 0, $retval);
      $writer.Flush();
    }while ($retval -eq $bufferSize)
    #
    ## finish writing the file
    $writer.Close();
    $fs.Close();

}
另一答案

试试这个:

string fullPath = System.IO.Path.Combine(txtdir.Text,DirName,LeafName);
Console.WriteLine("accessing " + fullPath);
FileStream fs = new FileStream(fullPath, FileMode.Create, FileAccess.Write);

以上是关于从sharepoint数据库中提取文件的主要内容,如果未能解决你的问题,请参考以下文章

从单个按钮从多个片段中提取数据

带有从加入列表中提取的元数据的 Sharepoint 文档库 - 是不是可以不编码?

powershell Powershell脚本,用于从CSV中提取数据并将其放入SharePoint列表中。

如何使用 Power Query 从 SharePoint 库中的(许多)文档中获取数据

使用从循环内的代码片段中提取的函数避免代码冗余/计算开销

错误代码:从 SharePoint 文档库中删除文件时出现 3604